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)
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 ;; ??? Currently does not have define_function_unit support for the R8000.
27 ;; Must include new entries for fmadd in addition to existing entries.
30 [(UNSPEC_LOAD_DF_LOW
0)
31 (UNSPEC_LOAD_DF_HIGH
1)
32 (UNSPEC_STORE_DF_HIGH
2)
36 (UNSPEC_EH_RECEIVER
6)
38 (UNSPEC_CONSTTABLE_QI
8)
39 (UNSPEC_CONSTTABLE_HI
9)
40 (UNSPEC_CONSTTABLE_SI
10)
41 (UNSPEC_CONSTTABLE_DI
11)
42 (UNSPEC_CONSTTABLE_SF
12)
43 (UNSPEC_CONSTTABLE_DF
13)
60 (UNSPEC_ADDRESS_FIRST
100)
62 (FAKE_CALL_REGNO
79)])
64 ;; ....................
68 ;; ....................
70 (define_attr "got" "unset,xgot_high,load"
71 (const_string "unset"))
73 ;; For jal instructions, this attribute is DIRECT when the target address
74 ;; is symbolic and INDIRECT when it is a register.
75 (define_attr "jal" "unset,direct,indirect"
76 (const_string "unset"))
78 ;; This attribute is YES if the instruction is a jal macro (not a
79 ;; real jal instruction).
81 ;; jal is always a macro in SVR4 PIC since it includes an instruction to
82 ;; restore $gp. Direct jals are also macros in NewABI PIC since they
83 ;; load the target address into $
25.
84 (define_attr "jal_macro" "no,yes"
85 (cond [(eq_attr "jal" "direct")
86 (symbol_ref "TARGET_ABICALLS !=
0")
87 (eq_attr "jal" "indirect")
88 (symbol_ref "(TARGET_ABICALLS && !TARGET_NEWABI) !=
0")]
91 ;; Classification of each insn.
92 ;; branch conditional branch
93 ;; jump unconditional jump
94 ;; call unconditional call
95 ;; load load instruction(s)
96 ;; fpload floating point load
97 ;; fpidxload floating point indexed load
98 ;; store store instruction(s)
99 ;; fpstore floating point store
100 ;; fpidxstore floating point indexed store
101 ;; prefetch memory prefetch (register + offset)
102 ;; prefetchx memory indexed prefetch (register + register)
103 ;; move data movement within same register set
104 ;; condmove conditional moves
105 ;; xfer transfer to/from coprocessor
106 ;; hilo transfer of hi/lo registers
107 ;; arith integer arithmetic instruction
108 ;; darith double precision integer arithmetic instructions
109 ;; const load constant
110 ;; imul integer multiply
111 ;; imadd integer multiply-add
112 ;; idiv integer divide
113 ;; icmp integer compare
114 ;; fadd floating point add/subtract
115 ;; fmul floating point multiply
116 ;; fmadd floating point multiply-add
117 ;; fdiv floating point divide
118 ;; fabs floating point absolute value
119 ;; fneg floating point negation
120 ;; fcmp floating point compare
121 ;; fcvt floating point convert
122 ;; fsqrt floating point square root
123 ;; frsqrt floating point reciprocal square root
124 ;; multi multiword sequence (or user asm statements)
127 "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,prefetch,prefetchx,move,condmove,xfer,hilo,const,arith,darith,imul,imadd,idiv,icmp,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,multi,nop"
128 (cond [(eq_attr "jal" "!unset") (const_string "call")
129 (eq_attr "got" "load") (const_string "load")]
130 (const_string "unknown")))
132 ;; Main data type used by the insn
133 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW"
134 (const_string "unknown"))
136 ;; Is this an extended instruction in mips16 mode?
137 (define_attr "extended_mips16" "no,yes"
140 ;; Length of instruction in bytes.
141 (define_attr "length" ""
142 (cond [;; Direct branch instructions have a range of [-
0x40000,
0x3fffc].
143 ;; If a branch is outside this range, we have a choice of two
144 ;; sequences. For PIC, an out-of-range branch like:
149 ;; becomes the equivalent of:
158 ;; where the load address can be up to three instructions long
161 ;; The non-PIC case is similar except that we use a direct
162 ;; jump instead of an la/jr pair. Since the target of this
163 ;; jump is an absolute
28-bit bit address (the other bits
164 ;; coming from the address of the delay slot) this form cannot
165 ;; cross a
256MB boundary. We could provide the option of
166 ;; using la/jr in this case too, but we do not do so at
169 ;; Note that this value does not account for the delay slot
170 ;; instruction, whose length is added separately. If the RTL
171 ;; pattern has no explicit delay slot, mips_adjust_insn_length
172 ;; will add the length of the implicit nop.
173 (eq_attr "type" "branch")
174 (cond [(lt (abs (minus (match_dup
1) (plus (pc) (const_int
4))))
177 (ne (symbol_ref "flag_pic && ! TARGET_EMBEDDED_PIC")
182 (eq_attr "got" "load")
184 (eq_attr "got" "xgot_high")
187 (eq_attr "type" "const")
188 (symbol_ref "mips_const_insns (operands[
1]) *
4")
189 (eq_attr "type" "load,fpload,fpidxload")
190 (symbol_ref "mips_fetch_insns (operands[
1]) *
4")
191 (eq_attr "type" "store,fpstore,fpidxstore")
192 (symbol_ref "mips_fetch_insns (operands[
0]) *
4")
194 ;; In the worst case, a call macro will take
8 instructions:
196 ;; lui $
25,%call_hi(FOO)
198 ;; lw $
25,%call_lo(FOO)($
25)
204 (eq_attr "jal_macro" "yes")
207 (and (eq_attr "extended_mips16" "yes")
208 (ne (symbol_ref "TARGET_MIPS16") (const_int
0)))
211 (eq_attr "type" "idiv")
212 (symbol_ref "mips_idiv_insns () *
4")
215 ;; Attribute describing the processor. This attribute must match exactly
216 ;; with the processor_type enumeration in mips.h.
218 "default,
4kc,
5kc,
20kc,m4k,r3000,r3900,r6000,r4000,r4100,r4111,r4120,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sr71000"
219 (const (symbol_ref "mips_tune")))
221 ;; The type of hardware hazard associated with this instruction.
222 ;; DELAY means that the next instruction cannot read the result
223 ;; of this one. HILO means that the next two instructions cannot
224 ;; write to HI or LO.
225 (define_attr "hazard" "none,delay,hilo"
226 (cond [(and (eq_attr "type" "load,fpload,fpidxload")
227 (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int
0)))
228 (const_string "delay")
230 (and (eq_attr "type" "xfer")
231 (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int
0)))
232 (const_string "delay")
234 (and (eq_attr "type" "fcmp")
235 (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int
0)))
236 (const_string "delay")
238 ;; The r4000 multiplication patterns include an mflo instruction.
239 (and (eq_attr "type" "imul")
240 (ne (symbol_ref "TARGET_FIX_R4000") (const_int
0)))
241 (const_string "hilo")
243 (and (eq_attr "type" "hilo")
244 (and (eq (symbol_ref "ISA_HAS_HILO_INTERLOCKS") (const_int
0))
245 (match_operand
1 "hilo_operand" "")))
246 (const_string "hilo")]
247 (const_string "none")))
249 ;; Is it a single instruction?
250 (define_attr "single_insn" "no,yes"
251 (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ?
2 :
4)"))
253 ;; Can the instruction be put into a delay slot?
254 (define_attr "can_delay" "no,yes"
255 (if_then_else (and (eq_attr "type" "!branch,call,jump")
256 (and (eq_attr "hazard" "none")
257 (eq_attr "single_insn" "yes")))
259 (const_string "no")))
261 ;; Attribute defining whether or not we can use the branch-likely instructions
262 (define_attr "branch_likely" "no,yes"
264 (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int
0))
266 (const_string "no"))))
268 ;; Describe a user's asm statement.
269 (define_asm_attributes
270 [(set_attr "type" "multi")])
272 ;; .........................
274 ;; Branch, call and jump delay slots
276 ;; .........................
278 (define_delay (and (eq_attr "type" "branch")
279 (eq (symbol_ref "TARGET_MIPS16") (const_int
0)))
280 [(eq_attr "can_delay" "yes")
282 (and (eq_attr "branch_likely" "yes")
283 (eq_attr "can_delay" "yes"))])
285 (define_delay (eq_attr "type" "jump")
286 [(eq_attr "can_delay" "yes")
290 (define_delay (and (eq_attr "type" "call")
291 (eq_attr "jal_macro" "no"))
292 [(eq_attr "can_delay" "yes")
296 ;; .........................
300 ;; .........................
302 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
303 ; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
305 ;; Make the default case (PROCESSOR_DEFAULT) handle the worst case
307 (define_function_unit "memory"
1 0
308 (and (eq_attr "type" "load,fpload,fpidxload")
309 (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4100,r4120,r4300,r5000"))
312 (define_function_unit "memory"
1 0
313 (and (eq_attr "type" "load,fpload,fpidxload")
314 (eq_attr "cpu" "r3000,r3900,r4600,r4650,r4100,r4120,r4300,r5000"))
317 (define_function_unit "memory"
1 0
318 (eq_attr "type" "store,fpstore,fpidxstore")
321 (define_function_unit "memory"
1 0 (eq_attr "type" "xfer")
2 0)
323 (define_function_unit "imuldiv"
1 0
324 (eq_attr "type" "hilo")
327 (define_function_unit "imuldiv"
1 0
328 (and (eq_attr "type" "imul,imadd")
329 (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4120,r4300,r5000"))
332 ;; On them mips16, we want to stronly discourage a mult from appearing
333 ;; after an mflo, since that requires explicit nop instructions. We
334 ;; do this by pretending that mflo ties up the function unit for long
335 ;; enough that the scheduler will ignore load stalls and the like when
336 ;; selecting instructions to between the two instructions.
338 (define_function_unit "imuldiv"
1 0
339 (and (eq_attr "type" "hilo") (ne (symbol_ref "TARGET_MIPS16") (const_int
0)))
342 (define_function_unit "imuldiv"
1 0
343 (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r3000,r3900"))
346 (define_function_unit "imuldiv"
1 0
347 (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r4000,r4600"))
350 (define_function_unit "imuldiv"
1 0
351 (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r4650"))
354 (define_function_unit "imuldiv"
1 0
355 (and (eq_attr "type" "imul,imadd")
356 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100,r4120")))
359 (define_function_unit "imuldiv"
1 0
360 (and (eq_attr "type" "imul,imadd")
361 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100,r4120")))
364 (define_function_unit "imuldiv"
1 0
365 (and (eq_attr "type" "imul,imadd")
366 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300,r5000")))
369 (define_function_unit "imuldiv"
1 0
370 (and (eq_attr "type" "imul,imadd")
371 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
374 (define_function_unit "imuldiv"
1 0
375 (and (eq_attr "type" "imul,imadd")
376 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
379 (define_function_unit "imuldiv"
1 0
380 (and (eq_attr "type" "idiv")
381 (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4120,r4300,r5000"))
384 (define_function_unit "imuldiv"
1 0
385 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r3000,r3900"))
388 (define_function_unit "imuldiv"
1 0
389 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4600"))
392 (define_function_unit "imuldiv"
1 0
393 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4650"))
396 (define_function_unit "imuldiv"
1 0
397 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000"))
400 (define_function_unit "imuldiv"
1 0
401 (and (eq_attr "type" "idiv")
402 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100,r4120")))
405 (define_function_unit "imuldiv"
1 0
406 (and (eq_attr "type" "idiv")
407 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100,r4120")))
410 (define_function_unit "imuldiv"
1 0
411 (and (eq_attr "type" "idiv")
412 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300")))
415 (define_function_unit "imuldiv"
1 0
416 (and (eq_attr "type" "idiv")
417 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
420 (define_function_unit "imuldiv"
1 0
421 (and (eq_attr "type" "idiv")
422 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r5000")))
425 (define_function_unit "imuldiv"
1 0
426 (and (eq_attr "type" "idiv")
427 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
430 ;; The R4300 does *NOT* have a separate Floating Point Unit, instead
431 ;; the FP hardware is part of the normal ALU circuitry. This means FP
432 ;; instructions affect the pipe-line, and no functional unit
433 ;; parallelism can occur on R4300 processors. To force GCC into coding
434 ;; for only a single functional unit, we force the R4300 FP
435 ;; instructions to be processed in the "imuldiv" unit.
437 (define_function_unit "adder"
1 1
438 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000"))
441 (define_function_unit "adder"
1 1
442 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r3000,r3900,r6000"))
445 (define_function_unit "adder"
1 1
446 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r5000"))
449 (define_function_unit "adder"
1 1
450 (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r3900,r6000,r4300"))
453 (define_function_unit "adder"
1 1
454 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3000,r3900"))
457 (define_function_unit "adder"
1 1
458 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r6000"))
461 (define_function_unit "adder"
1 1
462 (and (eq_attr "type" "fabs,fneg")
463 (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4300,r5000"))
466 (define_function_unit "adder"
1 1
467 (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "r3000,r3900,r4600,r4650,r5000"))
470 (define_function_unit "mult"
1 1
471 (and (eq_attr "type" "fmul")
472 (and (eq_attr "mode" "SF")
473 (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
476 (define_function_unit "mult"
1 1
477 (and (eq_attr "type" "fmul")
478 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900,r5000")))
481 (define_function_unit "mult"
1 1
482 (and (eq_attr "type" "fmul")
483 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
486 (define_function_unit "mult"
1 1
487 (and (eq_attr "type" "fmul")
488 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
491 (define_function_unit "mult"
1 1
492 (and (eq_attr "type" "fmul")
493 (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000")))
496 (define_function_unit "mult"
1 1
497 (and (eq_attr "type" "fmul")
498 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900,r5000")))
501 (define_function_unit "mult"
1 1
502 (and (eq_attr "type" "fmul")
503 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
506 (define_function_unit "divide"
1 1
507 (and (eq_attr "type" "fdiv")
508 (and (eq_attr "mode" "SF")
509 (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
512 (define_function_unit "divide"
1 1
513 (and (eq_attr "type" "fdiv")
514 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900")))
517 (define_function_unit "divide"
1 1
518 (and (eq_attr "type" "fdiv")
519 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
522 (define_function_unit "divide"
1 1
523 (and (eq_attr "type" "fdiv")
524 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
527 (define_function_unit "divide"
1 1
528 (and (eq_attr "type" "fdiv")
529 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
532 (define_function_unit "divide"
1 1
533 (and (eq_attr "type" "fdiv")
534 (and (eq_attr "mode" "DF")
535 (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300")))
538 (define_function_unit "divide"
1 1
539 (and (eq_attr "type" "fdiv")
540 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900")))
543 (define_function_unit "divide"
1 1
544 (and (eq_attr "type" "fdiv")
545 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
548 (define_function_unit "divide"
1 1
549 (and (eq_attr "type" "fdiv")
550 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
553 ;;; ??? Is this number right?
554 (define_function_unit "divide"
1 1
555 (and (eq_attr "type" "fsqrt,frsqrt")
556 (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
559 (define_function_unit "divide"
1 1
560 (and (eq_attr "type" "fsqrt,frsqrt")
561 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
564 (define_function_unit "divide"
1 1
565 (and (eq_attr "type" "fsqrt,frsqrt")
566 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
569 ;;; ??? Is this number right?
570 (define_function_unit "divide"
1 1
571 (and (eq_attr "type" "fsqrt,frsqrt")
572 (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
575 (define_function_unit "divide"
1 1
576 (and (eq_attr "type" "fsqrt,frsqrt")
577 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
580 (define_function_unit "divide"
1 1
581 (and (eq_attr "type" "fsqrt,frsqrt")
582 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r5000")))
585 ;; R4300 FP instruction classes treated as part of the "imuldiv"
588 (define_function_unit "imuldiv"
1 0
589 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r4300"))
592 (define_function_unit "imuldiv"
1 0
593 (and (eq_attr "type" "fcmp,fabs,fneg") (eq_attr "cpu" "r4300"))
596 (define_function_unit "imuldiv"
1 0
597 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
599 (define_function_unit "imuldiv"
1 0
600 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
603 (define_function_unit "imuldiv"
1 0
604 (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt,frsqrt"))
605 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
607 (define_function_unit "imuldiv"
1 0
608 (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt,frsqrt"))
609 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
612 ;; Include scheduling descriptions.
621 ;; ....................
625 ;; ....................
629 [(trap_if (const_int
1) (const_int
0))]
632 if (ISA_HAS_COND_TRAP)
634 /* The IRIX
6 O32 assembler requires the first break operand. */
635 else if (TARGET_MIPS16 || !TARGET_GAS)
641 (define_expand "conditional_trap"
642 [(trap_if (match_operator
0 "cmp_op"
643 [(match_dup
2) (match_dup
3)])
644 (match_operand
1 "const_int_operand" ""))]
647 if (operands[
1] == const0_rtx)
649 mips_gen_conditional_trap (operands);
657 [(trap_if (match_operator
0 "trap_cmp_op"
658 [(match_operand:SI
1 "reg_or_0_operand" "dJ")
659 (match_operand:SI
2 "arith_operand" "dI")])
665 [(trap_if (match_operator
0 "trap_cmp_op"
666 [(match_operand:DI
1 "reg_or_0_operand" "dJ")
667 (match_operand:DI
2 "arith_operand" "dI")])
669 "TARGET_64BIT && ISA_HAS_COND_TRAP"
673 ;; ....................
677 ;; ....................
680 (define_insn "adddf3"
681 [(set (match_operand:DF
0 "register_operand" "=f")
682 (plus:DF (match_operand:DF
1 "register_operand" "f")
683 (match_operand:DF
2 "register_operand" "f")))]
684 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
686 [(set_attr "type" "fadd")
687 (set_attr "mode" "DF")])
689 (define_insn "addsf3"
690 [(set (match_operand:SF
0 "register_operand" "=f")
691 (plus:SF (match_operand:SF
1 "register_operand" "f")
692 (match_operand:SF
2 "register_operand" "f")))]
695 [(set_attr "type" "fadd")
696 (set_attr "mode" "SF")])
698 (define_expand "addsi3"
699 [(set (match_operand:SI
0 "register_operand" "")
700 (plus:SI (match_operand:SI
1 "reg_or_0_operand" "")
701 (match_operand:SI
2 "arith_operand" "")))]
704 /* If a large stack adjustment was forced into a register, we may be
705 asked to generate rtx such as:
707 (set (reg:SI sp) (plus:SI (reg:SI sp) (reg:SI pseudo)))
709 but no such instruction is available in mips16. Handle it by
710 using a temporary. */
712 && REGNO (operands[
0]) == STACK_POINTER_REGNUM
713 && ((GET_CODE (operands[
1]) == REG
714 && REGNO (operands[
1]) != STACK_POINTER_REGNUM)
715 || GET_CODE (operands[
2]) != CONST_INT))
717 rtx tmp = gen_reg_rtx (SImode);
719 emit_move_insn (tmp, operands[
1]);
720 emit_insn (gen_addsi3 (tmp, tmp, operands[
2]));
721 emit_move_insn (operands[
0], tmp);
726 (define_insn "addsi3_internal"
727 [(set (match_operand:SI
0 "register_operand" "=d,d")
728 (plus:SI (match_operand:SI
1 "reg_or_0_operand" "dJ,dJ")
729 (match_operand:SI
2 "arith_operand" "d,Q")))]
734 [(set_attr "type" "arith")
735 (set_attr "mode" "SI")])
737 ;; For the mips16, we need to recognize stack pointer additions
738 ;; explicitly, since we don't have a constraint for $sp. These insns
739 ;; will be generated by the save_restore_insns functions.
744 (match_operand:SI
0 "small_int" "I")))]
747 [(set_attr "type" "arith")
748 (set_attr "mode" "SI")
749 (set (attr "length") (if_then_else (match_operand:VOID
0 "m16_simm8_8" "")
754 [(set (match_operand:SI
0 "register_operand" "=d")
756 (match_operand:SI
1 "small_int" "I")))]
759 [(set_attr "type" "arith")
760 (set_attr "mode" "SI")
761 (set (attr "length") (if_then_else (match_operand:VOID
1 "m16_uimm8_4" "")
766 [(set (match_operand:SI
0 "register_operand" "=d,d,d")
767 (plus:SI (match_operand:SI
1 "register_operand" "
0,d,d")
768 (match_operand:SI
2 "arith_operand" "Q,O,d")))]
770 && (GET_CODE (operands[
1]) != REG
771 || REGNO (operands[
1]) >= FIRST_PSEUDO_REGISTER
772 || M16_REG_P (REGNO (operands[
1]))
773 || REGNO (operands[
1]) == ARG_POINTER_REGNUM
774 || REGNO (operands[
1]) == FRAME_POINTER_REGNUM
775 || REGNO (operands[
1]) == STACK_POINTER_REGNUM)
776 && (GET_CODE (operands[
2]) != REG
777 || REGNO (operands[
2]) >= FIRST_PSEUDO_REGISTER
778 || M16_REG_P (REGNO (operands[
2]))
779 || REGNO (operands[
2]) == ARG_POINTER_REGNUM
780 || REGNO (operands[
2]) == FRAME_POINTER_REGNUM
781 || REGNO (operands[
2]) == STACK_POINTER_REGNUM)"
783 if (REGNO (operands[
0]) == REGNO (operands[
1]))
784 return "addu
\t%
0,%
2";
786 return "addu
\t%
0,%
1,%
2";
788 [(set_attr "type" "arith")
789 (set_attr "mode" "SI")
790 (set_attr_alternative "length"
791 [(if_then_else (match_operand:VOID
2 "m16_simm8_1" "")
794 (if_then_else (match_operand:VOID
2 "m16_simm4_1" "")
800 ;; On the mips16, we can sometimes split an add of a constant which is
801 ;; a
4 byte instruction into two adds which are both
2 byte
802 ;; instructions. There are two cases: one where we are adding a
803 ;; constant plus a register to another register, and one where we are
804 ;; simply adding a constant to a register.
807 [(set (match_operand:SI
0 "register_operand" "")
808 (plus:SI (match_dup
0)
809 (match_operand:SI
1 "const_int_operand" "")))]
810 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
811 && GET_CODE (operands[
0]) == REG
812 && M16_REG_P (REGNO (operands[
0]))
813 && GET_CODE (operands[
1]) == CONST_INT
814 && ((INTVAL (operands[
1]) >
0x7f
815 && INTVAL (operands[
1]) <=
0x7f +
0x7f)
816 || (INTVAL (operands[
1]) < -
0x80
817 && INTVAL (operands[
1]) >= -
0x80 -
0x80))"
818 [(set (match_dup
0) (plus:SI (match_dup
0) (match_dup
1)))
819 (set (match_dup
0) (plus:SI (match_dup
0) (match_dup
2)))]
821 HOST_WIDE_INT val = INTVAL (operands[
1]);
825 operands[
1] = GEN_INT (
0x7f);
826 operands[
2] = GEN_INT (val -
0x7f);
830 operands[
1] = GEN_INT (-
0x80);
831 operands[
2] = GEN_INT (val +
0x80);
836 [(set (match_operand:SI
0 "register_operand" "")
837 (plus:SI (match_operand:SI
1 "register_operand" "")
838 (match_operand:SI
2 "const_int_operand" "")))]
839 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
840 && GET_CODE (operands[
0]) == REG
841 && M16_REG_P (REGNO (operands[
0]))
842 && GET_CODE (operands[
1]) == REG
843 && M16_REG_P (REGNO (operands[
1]))
844 && REGNO (operands[
0]) != REGNO (operands[
1])
845 && GET_CODE (operands[
2]) == CONST_INT
846 && ((INTVAL (operands[
2]) >
0x7
847 && INTVAL (operands[
2]) <=
0x7 +
0x7f)
848 || (INTVAL (operands[
2]) < -
0x8
849 && INTVAL (operands[
2]) >= -
0x8 -
0x80))"
850 [(set (match_dup
0) (plus:SI (match_dup
1) (match_dup
2)))
851 (set (match_dup
0) (plus:SI (match_dup
0) (match_dup
3)))]
853 HOST_WIDE_INT val = INTVAL (operands[
2]);
857 operands[
2] = GEN_INT (
0x7);
858 operands[
3] = GEN_INT (val -
0x7);
862 operands[
2] = GEN_INT (-
0x8);
863 operands[
3] = GEN_INT (val +
0x8);
867 (define_expand "adddi3"
868 [(parallel [(set (match_operand:DI
0 "register_operand" "")
869 (plus:DI (match_operand:DI
1 "register_operand" "")
870 (match_operand:DI
2 "arith_operand" "")))
871 (clobber (match_dup
3))])]
872 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
874 /* If a large stack adjustment was forced into a register, we may be
875 asked to generate rtx such as:
877 (set (reg:DI sp) (plus:DI (reg:DI sp) (reg:DI pseudo)))
879 but no such instruction is available in mips16. Handle it by
880 using a temporary. */
882 && REGNO (operands[
0]) == STACK_POINTER_REGNUM
883 && ((GET_CODE (operands[
1]) == REG
884 && REGNO (operands[
1]) != STACK_POINTER_REGNUM)
885 || GET_CODE (operands[
2]) != CONST_INT))
887 rtx tmp = gen_reg_rtx (DImode);
889 emit_move_insn (tmp, operands[
1]);
890 emit_insn (gen_adddi3 (tmp, tmp, operands[
2]));
891 emit_move_insn (operands[
0], tmp);
897 emit_insn (gen_adddi3_internal_3 (operands[
0], operands[
1],
902 operands[
3] = gen_reg_rtx (SImode);
905 (define_insn "adddi3_internal_1"
906 [(set (match_operand:DI
0 "register_operand" "=d,&d")
907 (plus:DI (match_operand:DI
1 "register_operand" "
0,d")
908 (match_operand:DI
2 "register_operand" "d,d")))
909 (clobber (match_operand:SI
3 "register_operand" "=d,d"))]
910 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
912 return (REGNO (operands[
0]) == REGNO (operands[
1])
913 && REGNO (operands[
0]) == REGNO (operands[
2]))
914 ? "srl
\t%
3,%L0,
31\;sll
\t%M0,%M0,
1\;sll
\t%L0,%L1,
1\;addu
\t%M0,%M0,%
3"
915 : "addu
\t%L0,%L1,%L2\;sltu
\t%
3,%L0,%L2\;addu
\t%M0,%M1,%M2\;addu
\t%M0,%M0,%
3";
917 [(set_attr "type" "darith")
918 (set_attr "mode" "DI")
919 (set_attr "length" "
16")])
922 [(set (match_operand:DI
0 "register_operand" "")
923 (plus:DI (match_operand:DI
1 "register_operand" "")
924 (match_operand:DI
2 "register_operand" "")))
925 (clobber (match_operand:SI
3 "register_operand" ""))]
926 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
927 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
928 && GET_CODE (operands[
0]) == REG && GP_REG_P (REGNO (operands[
0]))
929 && GET_CODE (operands[
1]) == REG && GP_REG_P (REGNO (operands[
1]))
930 && GET_CODE (operands[
2]) == REG && GP_REG_P (REGNO (operands[
2]))
931 && (REGNO (operands[
0]) != REGNO (operands[
1])
932 || REGNO (operands[
0]) != REGNO (operands[
2]))"
934 [(set (subreg:SI (match_dup
0)
0)
935 (plus:SI (subreg:SI (match_dup
1)
0)
936 (subreg:SI (match_dup
2)
0)))
939 (ltu:SI (subreg:SI (match_dup
0)
0)
940 (subreg:SI (match_dup
2)
0)))
942 (set (subreg:SI (match_dup
0)
4)
943 (plus:SI (subreg:SI (match_dup
1)
4)
944 (subreg:SI (match_dup
2)
4)))
946 (set (subreg:SI (match_dup
0)
4)
947 (plus:SI (subreg:SI (match_dup
0)
4)
952 [(set (match_operand:DI
0 "register_operand" "")
953 (plus:DI (match_operand:DI
1 "register_operand" "")
954 (match_operand:DI
2 "register_operand" "")))
955 (clobber (match_operand:SI
3 "register_operand" ""))]
956 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
957 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
958 && GET_CODE (operands[
0]) == REG && GP_REG_P (REGNO (operands[
0]))
959 && GET_CODE (operands[
1]) == REG && GP_REG_P (REGNO (operands[
1]))
960 && GET_CODE (operands[
2]) == REG && GP_REG_P (REGNO (operands[
2]))
961 && (REGNO (operands[
0]) != REGNO (operands[
1])
962 || REGNO (operands[
0]) != REGNO (operands[
2]))"
964 [(set (subreg:SI (match_dup
0)
4)
965 (plus:SI (subreg:SI (match_dup
1)
4)
966 (subreg:SI (match_dup
2)
4)))
969 (ltu:SI (subreg:SI (match_dup
0)
4)
970 (subreg:SI (match_dup
2)
4)))
972 (set (subreg:SI (match_dup
0)
0)
973 (plus:SI (subreg:SI (match_dup
1)
0)
974 (subreg:SI (match_dup
2)
0)))
976 (set (subreg:SI (match_dup
0)
0)
977 (plus:SI (subreg:SI (match_dup
0)
0)
981 (define_insn "adddi3_internal_2"
982 [(set (match_operand:DI
0 "register_operand" "=d,d,d")
983 (plus:DI (match_operand:DI
1 "register_operand" "%d,d,d")
984 (match_operand:DI
2 "small_int" "P,J,N")))
985 (clobber (match_operand:SI
3 "register_operand" "=d,d,d"))]
986 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
988 addu
\t%L0,%L1,%
2\;sltu
\t%
3,%L0,%
2\;addu
\t%M0,%M1,%
3
989 move
\t%L0,%L1\;move
\t%M0,%M1
990 subu
\t%L0,%L1,%n2\;sltu
\t%
3,%L0,%
2\;subu
\t%M0,%M1,
1\;addu
\t%M0,%M0,%
3"
991 [(set_attr "type" "darith")
992 (set_attr "mode" "DI")
993 (set_attr "length" "
12,
8,
16")])
996 [(set (match_operand:DI
0 "register_operand" "")
997 (plus:DI (match_operand:DI
1 "register_operand" "")
998 (match_operand:DI
2 "small_int" "")))
999 (clobber (match_operand:SI
3 "register_operand" ""))]
1000 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1001 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1002 && GET_CODE (operands[
0]) == REG && GP_REG_P (REGNO (operands[
0]))
1003 && GET_CODE (operands[
1]) == REG && GP_REG_P (REGNO (operands[
1]))
1004 && INTVAL (operands[
2]) >
0"
1006 [(set (subreg:SI (match_dup
0)
0)
1007 (plus:SI (subreg:SI (match_dup
1)
0)
1011 (ltu:SI (subreg:SI (match_dup
0)
0)
1014 (set (subreg:SI (match_dup
0)
4)
1015 (plus:SI (subreg:SI (match_dup
1)
4)
1020 [(set (match_operand:DI
0 "register_operand" "")
1021 (plus:DI (match_operand:DI
1 "register_operand" "")
1022 (match_operand:DI
2 "small_int" "")))
1023 (clobber (match_operand:SI
3 "register_operand" ""))]
1024 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1025 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1026 && GET_CODE (operands[
0]) == REG && GP_REG_P (REGNO (operands[
0]))
1027 && GET_CODE (operands[
1]) == REG && GP_REG_P (REGNO (operands[
1]))
1028 && INTVAL (operands[
2]) >
0"
1030 [(set (subreg:SI (match_dup
0)
4)
1031 (plus:SI (subreg:SI (match_dup
1)
4)
1035 (ltu:SI (subreg:SI (match_dup
0)
4)
1038 (set (subreg:SI (match_dup
0)
0)
1039 (plus:SI (subreg:SI (match_dup
1)
0)
1043 (define_insn "adddi3_internal_3"
1044 [(set (match_operand:DI
0 "register_operand" "=d,d")
1045 (plus:DI (match_operand:DI
1 "reg_or_0_operand" "dJ,dJ")
1046 (match_operand:DI
2 "arith_operand" "d,Q")))]
1047 "TARGET_64BIT && !TARGET_MIPS16"
1051 [(set_attr "type" "darith")
1052 (set_attr "mode" "DI")])
1054 ;; For the mips16, we need to recognize stack pointer additions
1055 ;; explicitly, since we don't have a constraint for $sp. These insns
1056 ;; will be generated by the save_restore_insns functions.
1060 (plus:DI (reg:DI
29)
1061 (match_operand:DI
0 "small_int" "I")))]
1062 "TARGET_MIPS16 && TARGET_64BIT"
1064 [(set_attr "type" "arith")
1065 (set_attr "mode" "DI")
1066 (set (attr "length") (if_then_else (match_operand:VOID
0 "m16_simm8_8" "")
1071 [(set (match_operand:DI
0 "register_operand" "=d")
1072 (plus:DI (reg:DI
29)
1073 (match_operand:DI
1 "small_int" "I")))]
1074 "TARGET_MIPS16 && TARGET_64BIT"
1076 [(set_attr "type" "arith")
1077 (set_attr "mode" "DI")
1078 (set (attr "length") (if_then_else (match_operand:VOID
0 "m16_uimm5_4" "")
1083 [(set (match_operand:DI
0 "register_operand" "=d,d,d")
1084 (plus:DI (match_operand:DI
1 "register_operand" "
0,d,d")
1085 (match_operand:DI
2 "arith_operand" "Q,O,d")))]
1086 "TARGET_MIPS16 && TARGET_64BIT
1087 && (GET_CODE (operands[
1]) != REG
1088 || REGNO (operands[
1]) >= FIRST_PSEUDO_REGISTER
1089 || M16_REG_P (REGNO (operands[
1]))
1090 || REGNO (operands[
1]) == ARG_POINTER_REGNUM
1091 || REGNO (operands[
1]) == FRAME_POINTER_REGNUM
1092 || REGNO (operands[
1]) == STACK_POINTER_REGNUM)
1093 && (GET_CODE (operands[
2]) != REG
1094 || REGNO (operands[
2]) >= FIRST_PSEUDO_REGISTER
1095 || M16_REG_P (REGNO (operands[
2]))
1096 || REGNO (operands[
2]) == ARG_POINTER_REGNUM
1097 || REGNO (operands[
2]) == FRAME_POINTER_REGNUM
1098 || REGNO (operands[
2]) == STACK_POINTER_REGNUM)"
1100 if (REGNO (operands[
0]) == REGNO (operands[
1]))
1101 return "daddu
\t%
0,%
2";
1103 return "daddu
\t%
0,%
1,%
2";
1105 [(set_attr "type" "arith")
1106 (set_attr "mode" "DI")
1107 (set_attr_alternative "length"
1108 [(if_then_else (match_operand:VOID
2 "m16_simm5_1" "")
1111 (if_then_else (match_operand:VOID
2 "m16_simm4_1" "")
1117 ;; On the mips16, we can sometimes split an add of a constant which is
1118 ;; a
4 byte instruction into two adds which are both
2 byte
1119 ;; instructions. There are two cases: one where we are adding a
1120 ;; constant plus a register to another register, and one where we are
1121 ;; simply adding a constant to a register.
1124 [(set (match_operand:DI
0 "register_operand" "")
1125 (plus:DI (match_dup
0)
1126 (match_operand:DI
1 "const_int_operand" "")))]
1127 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1128 && GET_CODE (operands[
0]) == REG
1129 && M16_REG_P (REGNO (operands[
0]))
1130 && GET_CODE (operands[
1]) == CONST_INT
1131 && ((INTVAL (operands[
1]) >
0xf
1132 && INTVAL (operands[
1]) <=
0xf +
0xf)
1133 || (INTVAL (operands[
1]) < -
0x10
1134 && INTVAL (operands[
1]) >= -
0x10 -
0x10))"
1135 [(set (match_dup
0) (plus:DI (match_dup
0) (match_dup
1)))
1136 (set (match_dup
0) (plus:DI (match_dup
0) (match_dup
2)))]
1138 HOST_WIDE_INT val = INTVAL (operands[
1]);
1142 operands[
1] = GEN_INT (
0xf);
1143 operands[
2] = GEN_INT (val -
0xf);
1147 operands[
1] = GEN_INT (-
0x10);
1148 operands[
2] = GEN_INT (val +
0x10);
1153 [(set (match_operand:DI
0 "register_operand" "")
1154 (plus:DI (match_operand:DI
1 "register_operand" "")
1155 (match_operand:DI
2 "const_int_operand" "")))]
1156 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1157 && GET_CODE (operands[
0]) == REG
1158 && M16_REG_P (REGNO (operands[
0]))
1159 && GET_CODE (operands[
1]) == REG
1160 && M16_REG_P (REGNO (operands[
1]))
1161 && REGNO (operands[
0]) != REGNO (operands[
1])
1162 && GET_CODE (operands[
2]) == CONST_INT
1163 && ((INTVAL (operands[
2]) >
0x7
1164 && INTVAL (operands[
2]) <=
0x7 +
0xf)
1165 || (INTVAL (operands[
2]) < -
0x8
1166 && INTVAL (operands[
2]) >= -
0x8 -
0x10))"
1167 [(set (match_dup
0) (plus:DI (match_dup
1) (match_dup
2)))
1168 (set (match_dup
0) (plus:DI (match_dup
0) (match_dup
3)))]
1170 HOST_WIDE_INT val = INTVAL (operands[
2]);
1174 operands[
2] = GEN_INT (
0x7);
1175 operands[
3] = GEN_INT (val -
0x7);
1179 operands[
2] = GEN_INT (-
0x8);
1180 operands[
3] = GEN_INT (val +
0x8);
1184 (define_insn "addsi3_internal_2"
1185 [(set (match_operand:DI
0 "register_operand" "=d,d")
1186 (sign_extend:DI (plus:SI (match_operand:SI
1 "reg_or_0_operand" "dJ,dJ")
1187 (match_operand:SI
2 "arith_operand" "d,Q"))))]
1188 "TARGET_64BIT && !TARGET_MIPS16"
1192 [(set_attr "type" "arith")
1193 (set_attr "mode" "SI")])
1196 [(set (match_operand:DI
0 "register_operand" "=d,d,d")
1197 (sign_extend:DI (plus:SI (match_operand:SI
1 "register_operand" "
0,d,d")
1198 (match_operand:SI
2 "arith_operand" "Q,O,d"))))]
1199 "TARGET_MIPS16 && TARGET_64BIT"
1201 if (REGNO (operands[
0]) == REGNO (operands[
1]))
1202 return "addu
\t%
0,%
2";
1204 return "addu
\t%
0,%
1,%
2";
1206 [(set_attr "type" "arith")
1207 (set_attr "mode" "SI")
1208 (set_attr_alternative "length"
1209 [(if_then_else (match_operand:VOID
2 "m16_simm8_1" "")
1212 (if_then_else (match_operand:VOID
2 "m16_simm4_1" "")
1218 ;; ....................
1222 ;; ....................
1225 (define_insn "subdf3"
1226 [(set (match_operand:DF
0 "register_operand" "=f")
1227 (minus:DF (match_operand:DF
1 "register_operand" "f")
1228 (match_operand:DF
2 "register_operand" "f")))]
1229 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1231 [(set_attr "type" "fadd")
1232 (set_attr "mode" "DF")])
1234 (define_insn "subsf3"
1235 [(set (match_operand:SF
0 "register_operand" "=f")
1236 (minus:SF (match_operand:SF
1 "register_operand" "f")
1237 (match_operand:SF
2 "register_operand" "f")))]
1240 [(set_attr "type" "fadd")
1241 (set_attr "mode" "SF")])
1243 (define_expand "subsi3"
1244 [(set (match_operand:SI
0 "register_operand" "")
1245 (minus:SI (match_operand:SI
1 "register_operand" "")
1246 (match_operand:SI
2 "register_operand" "")))]
1250 (define_insn "subsi3_internal"
1251 [(set (match_operand:SI
0 "register_operand" "=d")
1252 (minus:SI (match_operand:SI
1 "register_operand" "d")
1253 (match_operand:SI
2 "register_operand" "d")))]
1256 [(set_attr "type" "arith")
1257 (set_attr "mode" "SI")])
1259 (define_expand "subdi3"
1260 [(parallel [(set (match_operand:DI
0 "register_operand" "=d")
1261 (minus:DI (match_operand:DI
1 "register_operand" "d")
1262 (match_operand:DI
2 "register_operand" "d")))
1263 (clobber (match_dup
3))])]
1264 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
1268 emit_insn (gen_subdi3_internal_3 (operands[
0], operands[
1],
1273 operands[
3] = gen_reg_rtx (SImode);
1276 (define_insn "subdi3_internal"
1277 [(set (match_operand:DI
0 "register_operand" "=d")
1278 (minus:DI (match_operand:DI
1 "register_operand" "d")
1279 (match_operand:DI
2 "register_operand" "d")))
1280 (clobber (match_operand:SI
3 "register_operand" "=d"))]
1281 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
1282 "sltu
\t%
3,%L1,%L2\;subu
\t%L0,%L1,%L2\;subu
\t%M0,%M1,%M2\;subu
\t%M0,%M0,%
3"
1283 [(set_attr "type" "darith")
1284 (set_attr "mode" "DI")
1285 (set_attr "length" "
16")])
1288 [(set (match_operand:DI
0 "register_operand" "")
1289 (minus:DI (match_operand:DI
1 "register_operand" "")
1290 (match_operand:DI
2 "register_operand" "")))
1291 (clobber (match_operand:SI
3 "register_operand" ""))]
1292 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1293 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1294 && GET_CODE (operands[
0]) == REG && GP_REG_P (REGNO (operands[
0]))
1295 && GET_CODE (operands[
1]) == REG && GP_REG_P (REGNO (operands[
1]))
1296 && GET_CODE (operands[
2]) == REG && GP_REG_P (REGNO (operands[
2]))"
1299 (ltu:SI (subreg:SI (match_dup
1)
0)
1300 (subreg:SI (match_dup
2)
0)))
1302 (set (subreg:SI (match_dup
0)
0)
1303 (minus:SI (subreg:SI (match_dup
1)
0)
1304 (subreg:SI (match_dup
2)
0)))
1306 (set (subreg:SI (match_dup
0)
4)
1307 (minus:SI (subreg:SI (match_dup
1)
4)
1308 (subreg:SI (match_dup
2)
4)))
1310 (set (subreg:SI (match_dup
0)
4)
1311 (minus:SI (subreg:SI (match_dup
0)
4)
1316 [(set (match_operand:DI
0 "register_operand" "")
1317 (minus:DI (match_operand:DI
1 "register_operand" "")
1318 (match_operand:DI
2 "register_operand" "")))
1319 (clobber (match_operand:SI
3 "register_operand" ""))]
1320 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1321 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1322 && GET_CODE (operands[
0]) == REG && GP_REG_P (REGNO (operands[
0]))
1323 && GET_CODE (operands[
1]) == REG && GP_REG_P (REGNO (operands[
1]))
1324 && GET_CODE (operands[
2]) == REG && GP_REG_P (REGNO (operands[
2]))"
1327 (ltu:SI (subreg:SI (match_dup
1)
4)
1328 (subreg:SI (match_dup
2)
4)))
1330 (set (subreg:SI (match_dup
0)
4)
1331 (minus:SI (subreg:SI (match_dup
1)
4)
1332 (subreg:SI (match_dup
2)
4)))
1334 (set (subreg:SI (match_dup
0)
0)
1335 (minus:SI (subreg:SI (match_dup
1)
0)
1336 (subreg:SI (match_dup
2)
0)))
1338 (set (subreg:SI (match_dup
0)
0)
1339 (minus:SI (subreg:SI (match_dup
0)
0)
1343 (define_insn "subdi3_internal_3"
1344 [(set (match_operand:DI
0 "register_operand" "=d")
1345 (minus:DI (match_operand:DI
1 "register_operand" "d")
1346 (match_operand:DI
2 "register_operand" "d")))]
1349 [(set_attr "type" "darith")
1350 (set_attr "mode" "DI")])
1352 (define_insn "subsi3_internal_2"
1353 [(set (match_operand:DI
0 "register_operand" "=d")
1355 (minus:SI (match_operand:SI
1 "register_operand" "d")
1356 (match_operand:SI
2 "register_operand" "d"))))]
1359 [(set_attr "type" "arith")
1360 (set_attr "mode" "DI")])
1363 ;; ....................
1367 ;; ....................
1370 (define_expand "muldf3"
1371 [(set (match_operand:DF
0 "register_operand" "=f")
1372 (mult:DF (match_operand:DF
1 "register_operand" "f")
1373 (match_operand:DF
2 "register_operand" "f")))]
1374 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1377 (define_insn "muldf3_internal"
1378 [(set (match_operand:DF
0 "register_operand" "=f")
1379 (mult:DF (match_operand:DF
1 "register_operand" "f")
1380 (match_operand:DF
2 "register_operand" "f")))]
1381 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_4300_MUL_FIX"
1383 [(set_attr "type" "fmul")
1384 (set_attr "mode" "DF")])
1386 ;; Early VR4300 silicon has a CPU bug where multiplies with certain
1387 ;; operands may corrupt immediately following multiplies. This is a
1388 ;; simple fix to insert NOPs.
1390 (define_insn "muldf3_r4300"
1391 [(set (match_operand:DF
0 "register_operand" "=f")
1392 (mult:DF (match_operand:DF
1 "register_operand" "f")
1393 (match_operand:DF
2 "register_operand" "f")))]
1394 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_4300_MUL_FIX"
1395 "mul.d
\t%
0,%
1,%
2\;nop"
1396 [(set_attr "type" "fmul")
1397 (set_attr "mode" "DF")
1398 (set_attr "length" "
8")])
1400 (define_expand "mulsf3"
1401 [(set (match_operand:SF
0 "register_operand" "=f")
1402 (mult:SF (match_operand:SF
1 "register_operand" "f")
1403 (match_operand:SF
2 "register_operand" "f")))]
1407 (define_insn "mulsf3_internal"
1408 [(set (match_operand:SF
0 "register_operand" "=f")
1409 (mult:SF (match_operand:SF
1 "register_operand" "f")
1410 (match_operand:SF
2 "register_operand" "f")))]
1411 "TARGET_HARD_FLOAT && !TARGET_4300_MUL_FIX"
1413 [(set_attr "type" "fmul")
1414 (set_attr "mode" "SF")])
1416 ;; See muldf3_r4300.
1418 (define_insn "mulsf3_r4300"
1419 [(set (match_operand:SF
0 "register_operand" "=f")
1420 (mult:SF (match_operand:SF
1 "register_operand" "f")
1421 (match_operand:SF
2 "register_operand" "f")))]
1422 "TARGET_HARD_FLOAT && TARGET_4300_MUL_FIX"
1423 "mul.s
\t%
0,%
1,%
2\;nop"
1424 [(set_attr "type" "fmul")
1425 (set_attr "mode" "SF")
1426 (set_attr "length" "
8")])
1429 ;; The original R4000 has a cpu bug. If a double-word or a variable
1430 ;; shift executes while an integer multiplication is in progress, the
1431 ;; shift may give an incorrect result. Avoid this by keeping the mflo
1432 ;; with the mult on the R4000.
1434 ;; From "MIPS R4000PC/SC Errata, Processor Revision
2.2 and
3.0"
1435 ;; (also valid for MIPS R4000MC processors):
1437 ;; "
16. R4000PC, R4000SC: Please refer to errata
28 for an update to
1438 ;; this errata description.
1439 ;; The following code sequence causes the R4000 to incorrectly
1440 ;; execute the Double Shift Right Arithmetic
32 (dsra32)
1441 ;; instruction. If the dsra32 instruction is executed during an
1442 ;; integer multiply, the dsra32 will only shift by the amount in
1443 ;; specified in the instruction rather than the amount plus
32
1445 ;; instruction
1: mult rs,rt integer multiply
1446 ;; instruction
2-
12: dsra32 rd,rt,rs doubleword shift
1447 ;; right arithmetic +
32
1448 ;; Workaround: A dsra32 instruction placed after an integer
1449 ;; multiply should not be one of the
11 instructions after the
1450 ;; multiply instruction."
1454 ;; "
28. R4000PC, R4000SC: The text from errata
16 should be replaced by
1455 ;; the following description.
1456 ;; All extended shifts (shift by n+
32) and variable shifts (
32 and
1457 ;;
64-bit versions) may produce incorrect results under the
1458 ;; following conditions:
1459 ;;
1) An integer multiply is currently executing
1460 ;;
2) These types of shift instructions are executed immediately
1461 ;; following an integer divide instruction.
1463 ;;
1) Make sure no integer multiply is running wihen these
1464 ;; instruction are executed. If this cannot be predicted at
1465 ;; compile time, then insert a "mfhi" to R0 instruction
1466 ;; immediately after the integer multiply instruction. This
1467 ;; will cause the integer multiply to complete before the shift
1469 ;;
2) Separate integer divide and these two classes of shift
1470 ;; instructions by another instruction or a noop."
1472 ;; These processors have PRId values of
0x00004220 and
0x00004300,
1475 (define_expand "mulsi3"
1476 [(set (match_operand:SI
0 "register_operand" "")
1477 (mult:SI (match_operand:SI
1 "register_operand" "")
1478 (match_operand:SI
2 "register_operand" "")))]
1481 if (GENERATE_MULT3_SI || TARGET_MAD)
1482 emit_insn (gen_mulsi3_mult3 (operands[
0], operands[
1], operands[
2]));
1483 else if (!TARGET_FIX_R4000)
1484 emit_insn (gen_mulsi3_internal (operands[
0], operands[
1], operands[
2]));
1486 emit_insn (gen_mulsi3_r4000 (operands[
0], operands[
1], operands[
2]));
1490 (define_insn "mulsi3_mult3"
1491 [(set (match_operand:SI
0 "register_operand" "=d,l")
1492 (mult:SI (match_operand:SI
1 "register_operand" "d,d")
1493 (match_operand:SI
2 "register_operand" "d,d")))
1494 (clobber (match_scratch:SI
3 "=h,h"))
1495 (clobber (match_scratch:SI
4 "=l,X"))]
1499 if (which_alternative ==
1)
1500 return "mult
\t%
1,%
2";
1509 return "mul
\t%
0,%
1,%
2";
1510 return "mult
\t%
0,%
1,%
2";
1512 [(set_attr "type" "imul")
1513 (set_attr "mode" "SI")])
1515 ;; If a register gets allocated to LO, and we spill to memory, the reload
1516 ;; will include a move from LO to a GPR. Merge it into the multiplication
1517 ;; if it can set the GPR directly.
1520 ;; Operand
1: GPR (
1st multiplication operand)
1521 ;; Operand
2: GPR (
2nd multiplication operand)
1523 ;; Operand
4: GPR (destination)
1526 [(set (match_operand:SI
0 "register_operand" "")
1527 (mult:SI (match_operand:SI
1 "register_operand" "")
1528 (match_operand:SI
2 "register_operand" "")))
1529 (clobber (match_operand:SI
3 "register_operand" ""))
1530 (clobber (scratch:SI))])
1531 (set (match_operand:SI
4 "register_operand" "")
1534 && true_regnum (operands[
0]) == LO_REGNUM
1535 && GP_REG_P (true_regnum (operands[
4]))
1536 && peep2_reg_dead_p (
2, operands[
0])"
1539 (mult:SI (match_dup
1)
1541 (clobber (match_dup
3))
1542 (clobber (match_dup
0))])])
1544 (define_insn "mulsi3_internal"
1545 [(set (match_operand:SI
0 "register_operand" "=l")
1546 (mult:SI (match_operand:SI
1 "register_operand" "d")
1547 (match_operand:SI
2 "register_operand" "d")))
1548 (clobber (match_scratch:SI
3 "=h"))]
1551 [(set_attr "type" "imul")
1552 (set_attr "mode" "SI")])
1554 (define_insn "mulsi3_r4000"
1555 [(set (match_operand:SI
0 "register_operand" "=d")
1556 (mult:SI (match_operand:SI
1 "register_operand" "d")
1557 (match_operand:SI
2 "register_operand" "d")))
1558 (clobber (match_scratch:SI
3 "=h"))
1559 (clobber (match_scratch:SI
4 "=l"))]
1561 "mult
\t%
1,%
2\;mflo
\t%
0"
1562 [(set_attr "type" "imul")
1563 (set_attr "mode" "SI")
1564 (set_attr "length" "
8")])
1566 ;; Multiply-accumulate patterns
1568 ;; For processors that can copy the output to a general register:
1570 ;; The all-d alternative is needed because the combiner will find this
1571 ;; pattern and then register alloc/reload will move registers around to
1572 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
1574 ;; The last alternative should be made slightly less desirable, but adding
1575 ;; "?" to the constraint is too strong, and causes values to be loaded into
1576 ;; LO even when that's more costly. For now, using "*d" mostly does the
1578 (define_insn "*mul_acc_si"
1579 [(set (match_operand:SI
0 "register_operand" "=l,*d,*d")
1580 (plus:SI (mult:SI (match_operand:SI
1 "register_operand" "d,d,d")
1581 (match_operand:SI
2 "register_operand" "d,d,d"))
1582 (match_operand:SI
3 "register_operand" "
0,l,*d")))
1583 (clobber (match_scratch:SI
4 "=h,h,h"))
1584 (clobber (match_scratch:SI
5 "=X,
3,l"))
1585 (clobber (match_scratch:SI
6 "=X,X,&d"))]
1587 || ISA_HAS_MADD_MSUB)
1590 static const char *const madd[] = { "madd
\t%
1,%
2", "madd
\t%
0,%
1,%
2" };
1591 if (which_alternative ==
2)
1593 if (ISA_HAS_MADD_MSUB && which_alternative !=
0)
1595 return madd[which_alternative];
1597 [(set_attr "type" "imadd,imadd,multi")
1598 (set_attr "mode" "SI")
1599 (set_attr "length" "
4,
4,
8")])
1601 ;; Split the above insn if we failed to get LO allocated.
1603 [(set (match_operand:SI
0 "register_operand" "")
1604 (plus:SI (mult:SI (match_operand:SI
1 "register_operand" "")
1605 (match_operand:SI
2 "register_operand" ""))
1606 (match_operand:SI
3 "register_operand" "")))
1607 (clobber (match_scratch:SI
4 ""))
1608 (clobber (match_scratch:SI
5 ""))
1609 (clobber (match_scratch:SI
6 ""))]
1610 "reload_completed && !TARGET_DEBUG_D_MODE
1611 && GP_REG_P (true_regnum (operands[
0]))
1612 && GP_REG_P (true_regnum (operands[
3]))"
1613 [(parallel [(set (match_dup
6)
1614 (mult:SI (match_dup
1) (match_dup
2)))
1615 (clobber (match_dup
4))
1616 (clobber (match_dup
5))])
1617 (set (match_dup
0) (plus:SI (match_dup
6) (match_dup
3)))]
1620 ;; Splitter to copy result of MADD to a general register
1622 [(set (match_operand:SI
0 "register_operand" "")
1623 (plus:SI (mult:SI (match_operand:SI
1 "register_operand" "")
1624 (match_operand:SI
2 "register_operand" ""))
1625 (match_operand:SI
3 "register_operand" "")))
1626 (clobber (match_scratch:SI
4 ""))
1627 (clobber (match_scratch:SI
5 ""))
1628 (clobber (match_scratch:SI
6 ""))]
1629 "reload_completed && !TARGET_DEBUG_D_MODE
1630 && GP_REG_P (true_regnum (operands[
0]))
1631 && true_regnum (operands[
3]) == LO_REGNUM"
1632 [(parallel [(set (match_dup
3)
1633 (plus:SI (mult:SI (match_dup
1) (match_dup
2))
1635 (clobber (match_dup
4))
1636 (clobber (match_dup
5))
1637 (clobber (match_dup
6))])
1638 (set (match_dup
0) (match_dup
3))]
1641 (define_insn "*macc"
1642 [(set (match_operand:SI
0 "register_operand" "=l,d")
1643 (plus:SI (mult:SI (match_operand:SI
1 "register_operand" "d,d")
1644 (match_operand:SI
2 "register_operand" "d,d"))
1645 (match_operand:SI
3 "register_operand" "
0,l")))
1646 (clobber (match_scratch:SI
4 "=h,h"))
1647 (clobber (match_scratch:SI
5 "=X,
3"))]
1650 if (which_alternative ==
1)
1651 return "macc
\t%
0,%
1,%
2";
1652 else if (TARGET_MIPS5500)
1653 return "madd
\t%
1,%
2";
1655 return "macc
\t%.,%
1,%
2";
1657 [(set_attr "type" "imadd")
1658 (set_attr "mode" "SI")])
1660 ;; Pattern generated by define_peephole2 below
1661 (define_insn "*macc2"
1662 [(set (match_operand:SI
0 "register_operand" "=l")
1663 (plus:SI (mult:SI (match_operand:SI
1 "register_operand" "d")
1664 (match_operand:SI
2 "register_operand" "d"))
1666 (set (match_operand:SI
3 "register_operand" "=d")
1667 (plus:SI (mult:SI (match_dup
1)
1670 (clobber (match_scratch:SI
4 "=h"))]
1671 "ISA_HAS_MACC && reload_completed"
1673 [(set_attr "type" "imadd")
1674 (set_attr "mode" "SI")])
1676 ;; Convert macc $
0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1679 ;; Operand
1: GPR (
1st multiplication operand)
1680 ;; Operand
2: GPR (
2nd multiplication operand)
1682 ;; Operand
4: GPR (destination)
1685 [(set (match_operand:SI
0 "register_operand" "")
1686 (plus:SI (mult:SI (match_operand:SI
1 "register_operand" "")
1687 (match_operand:SI
2 "register_operand" ""))
1689 (clobber (match_operand:SI
3 "register_operand" ""))
1690 (clobber (scratch:SI))])
1691 (set (match_operand:SI
4 "register_operand" "")
1694 && true_regnum (operands[
0]) == LO_REGNUM
1695 && GP_REG_P (true_regnum (operands[
4]))"
1696 [(parallel [(set (match_dup
0)
1697 (plus:SI (mult:SI (match_dup
1)
1701 (plus:SI (mult:SI (match_dup
1)
1704 (clobber (match_dup
3))])]
1707 ;; When we have a three-address multiplication instruction, it should
1708 ;; be faster to do a separate multiply and add, rather than moving
1709 ;; something into LO in order to use a macc instruction.
1711 ;; This peephole needs a scratch register to cater for the case when one
1712 ;; of the multiplication operands is the same as the destination.
1714 ;; Operand
0: GPR (scratch)
1716 ;; Operand
2: GPR (addend)
1717 ;; Operand
3: GPR (destination)
1718 ;; Operand
4: GPR (
1st multiplication operand)
1719 ;; Operand
5: GPR (
2nd multiplication operand)
1722 [(match_scratch:SI
0 "d")
1723 (set (match_operand:SI
1 "register_operand" "")
1724 (match_operand:SI
2 "register_operand" ""))
1727 [(set (match_operand:SI
3 "register_operand" "")
1728 (plus:SI (mult:SI (match_operand:SI
4 "register_operand" "")
1729 (match_operand:SI
5 "register_operand" ""))
1731 (clobber (match_operand:SI
6 "register_operand" ""))
1732 (clobber (match_dup
1))])]
1733 "ISA_HAS_MACC && GENERATE_MULT3_SI
1734 && true_regnum (operands[
1]) == LO_REGNUM
1735 && peep2_reg_dead_p (
2, operands[
1])
1736 && GP_REG_P (true_regnum (operands[
3]))"
1737 [(parallel [(set (match_dup
0)
1738 (mult:SI (match_dup
4)
1740 (clobber (match_dup
6))
1741 (clobber (match_dup
1))])
1743 (plus:SI (match_dup
0)
1747 ;; Same as above, except LO is the initial target of the macc.
1749 ;; Operand
0: GPR (scratch)
1751 ;; Operand
2: GPR (addend)
1752 ;; Operand
3: GPR (
1st multiplication operand)
1753 ;; Operand
4: GPR (
2nd multiplication operand)
1755 ;; Operand
6: GPR (destination)
1757 [(match_scratch:SI
0 "d")
1758 (set (match_operand:SI
1 "register_operand" "")
1759 (match_operand:SI
2 "register_operand" ""))
1763 (plus:SI (mult:SI (match_operand:SI
3 "register_operand" "")
1764 (match_operand:SI
4 "register_operand" ""))
1766 (clobber (match_operand:SI
5 "register_operand" ""))
1767 (clobber (scratch:SI))])
1769 (set (match_operand:SI
6 "register_operand" "")
1771 "ISA_HAS_MACC && GENERATE_MULT3_SI
1772 && true_regnum (operands[
1]) == LO_REGNUM
1773 && peep2_reg_dead_p (
3, operands[
1])
1774 && GP_REG_P (true_regnum (operands[
6]))"
1775 [(parallel [(set (match_dup
0)
1776 (mult:SI (match_dup
3)
1778 (clobber (match_dup
5))
1779 (clobber (match_dup
1))])
1781 (plus:SI (match_dup
0)
1785 (define_insn "*mul_sub_si"
1786 [(set (match_operand:SI
0 "register_operand" "=l,*d,*d")
1787 (minus:SI (match_operand:SI
1 "register_operand" "
0,l,*d")
1788 (mult:SI (match_operand:SI
2 "register_operand" "d,d,d")
1789 (match_operand:SI
3 "register_operand" "d,d,d"))))
1790 (clobber (match_scratch:SI
4 "=h,h,h"))
1791 (clobber (match_scratch:SI
5 "=X,
1,l"))
1792 (clobber (match_scratch:SI
6 "=X,X,&d"))]
1798 [(set_attr "type" "imadd,multi,multi")
1799 (set_attr "mode" "SI")
1800 (set_attr "length" "
4,
8,
8")])
1802 ;; Split the above insn if we failed to get LO allocated.
1804 [(set (match_operand:SI
0 "register_operand" "")
1805 (minus:SI (match_operand:SI
1 "register_operand" "")
1806 (mult:SI (match_operand:SI
2 "register_operand" "")
1807 (match_operand:SI
3 "register_operand" ""))))
1808 (clobber (match_scratch:SI
4 ""))
1809 (clobber (match_scratch:SI
5 ""))
1810 (clobber (match_scratch:SI
6 ""))]
1811 "reload_completed && !TARGET_DEBUG_D_MODE
1812 && GP_REG_P (true_regnum (operands[
0]))
1813 && GP_REG_P (true_regnum (operands[
1]))"
1814 [(parallel [(set (match_dup
6)
1815 (mult:SI (match_dup
2) (match_dup
3)))
1816 (clobber (match_dup
4))
1817 (clobber (match_dup
5))])
1818 (set (match_dup
0) (minus:SI (match_dup
1) (match_dup
6)))]
1821 ;; Splitter to copy result of MSUB to a general register
1823 [(set (match_operand:SI
0 "register_operand" "")
1824 (minus:SI (match_operand:SI
1 "register_operand" "")
1825 (mult:SI (match_operand:SI
2 "register_operand" "")
1826 (match_operand:SI
3 "register_operand" ""))))
1827 (clobber (match_scratch:SI
4 ""))
1828 (clobber (match_scratch:SI
5 ""))
1829 (clobber (match_scratch:SI
6 ""))]
1830 "reload_completed && !TARGET_DEBUG_D_MODE
1831 && GP_REG_P (true_regnum (operands[
0]))
1832 && true_regnum (operands[
1]) == LO_REGNUM"
1833 [(parallel [(set (match_dup
1)
1834 (minus:SI (match_dup
1)
1835 (mult:SI (match_dup
2) (match_dup
3))))
1836 (clobber (match_dup
4))
1837 (clobber (match_dup
5))
1838 (clobber (match_dup
6))])
1839 (set (match_dup
0) (match_dup
1))]
1842 (define_insn "*muls"
1843 [(set (match_operand:SI
0 "register_operand" "=l,d")
1844 (neg:SI (mult:SI (match_operand:SI
1 "register_operand" "d,d")
1845 (match_operand:SI
2 "register_operand" "d,d"))))
1846 (clobber (match_scratch:SI
3 "=h,h"))
1847 (clobber (match_scratch:SI
4 "=X,l"))]
1852 [(set_attr "type" "imul")
1853 (set_attr "mode" "SI")])
1855 (define_insn "*msac"
1856 [(set (match_operand:SI
0 "register_operand" "=l,d")
1857 (minus:SI (match_operand:SI
1 "register_operand" "
0,l")
1858 (mult:SI (match_operand:SI
2 "register_operand" "d,d")
1859 (match_operand:SI
3 "register_operand" "d,d"))))
1860 (clobber (match_scratch:SI
4 "=h,h"))
1861 (clobber (match_scratch:SI
5 "=X,
1"))]
1864 if (which_alternative ==
1)
1865 return "msac
\t%
0,%
2,%
3";
1866 else if (TARGET_MIPS5500)
1867 return "msub
\t%
2,%
3";
1869 return "msac
\t$
0,%
2,%
3";
1871 [(set_attr "type" "imadd")
1872 (set_attr "mode" "SI")])
1874 (define_expand "muldi3"
1875 [(set (match_operand:DI
0 "register_operand" "")
1876 (mult:DI (match_operand:DI
1 "register_operand" "")
1877 (match_operand:DI
2 "register_operand" "")))]
1880 if (GENERATE_MULT3_DI)
1881 emit_insn (gen_muldi3_mult3 (operands[
0], operands[
1], operands[
2]));
1882 else if (!TARGET_FIX_R4000)
1883 emit_insn (gen_muldi3_internal (operands[
0], operands[
1], operands[
2]));
1885 emit_insn (gen_muldi3_r4000 (operands[
0], operands[
1], operands[
2]));
1889 (define_insn "muldi3_mult3"
1890 [(set (match_operand:DI
0 "register_operand" "=d")
1891 (mult:DI (match_operand:DI
1 "register_operand" "d")
1892 (match_operand:DI
2 "register_operand" "d")))
1893 (clobber (match_scratch:DI
3 "=h"))
1894 (clobber (match_scratch:DI
4 "=l"))]
1895 "TARGET_64BIT && GENERATE_MULT3_DI"
1897 [(set_attr "type" "imul")
1898 (set_attr "mode" "DI")])
1900 (define_insn "muldi3_internal"
1901 [(set (match_operand:DI
0 "register_operand" "=l")
1902 (mult:DI (match_operand:DI
1 "register_operand" "d")
1903 (match_operand:DI
2 "register_operand" "d")))
1904 (clobber (match_scratch:DI
3 "=h"))]
1905 "TARGET_64BIT && !TARGET_FIX_R4000"
1907 [(set_attr "type" "imul")
1908 (set_attr "mode" "DI")])
1910 (define_insn "muldi3_r4000"
1911 [(set (match_operand:DI
0 "register_operand" "=d")
1912 (mult:DI (match_operand:DI
1 "register_operand" "d")
1913 (match_operand:DI
2 "register_operand" "d")))
1914 (clobber (match_scratch:DI
3 "=h"))
1915 (clobber (match_scratch:DI
4 "=l"))]
1916 "TARGET_64BIT && TARGET_FIX_R4000"
1917 "dmult
\t%
1,%
2\;mflo
\t%
0"
1918 [(set_attr "type" "imul")
1919 (set_attr "mode" "DI")
1920 (set_attr "length" "
8")])
1922 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1924 (define_expand "mulsidi3"
1926 [(set (match_operand:DI
0 "register_operand" "")
1928 (sign_extend:DI (match_operand:SI
1 "register_operand" ""))
1929 (sign_extend:DI (match_operand:SI
2 "register_operand" ""))))
1930 (clobber (scratch:DI))
1931 (clobber (scratch:DI))
1932 (clobber (scratch:DI))])]
1933 "!TARGET_64BIT || !TARGET_FIX_R4000"
1937 if (!TARGET_FIX_R4000)
1938 emit_insn (gen_mulsidi3_32bit_internal (operands[
0], operands[
1],
1941 emit_insn (gen_mulsidi3_32bit_r4000 (operands[
0], operands[
1],
1947 (define_insn "mulsidi3_32bit_internal"
1948 [(set (match_operand:DI
0 "register_operand" "=x")
1950 (sign_extend:DI (match_operand:SI
1 "register_operand" "d"))
1951 (sign_extend:DI (match_operand:SI
2 "register_operand" "d"))))]
1952 "!TARGET_64BIT && !TARGET_FIX_R4000"
1954 [(set_attr "type" "imul")
1955 (set_attr "mode" "SI")])
1957 (define_insn "mulsidi3_32bit_r4000"
1958 [(set (match_operand:DI
0 "register_operand" "=d")
1960 (sign_extend:DI (match_operand:SI
1 "register_operand" "d"))
1961 (sign_extend:DI (match_operand:SI
2 "register_operand" "d"))))
1962 (clobber (match_scratch:DI
3 "=l"))
1963 (clobber (match_scratch:DI
4 "=h"))]
1964 "!TARGET_64BIT && TARGET_FIX_R4000"
1965 "mult
\t%
1,%
2\;mflo
\t%L0;mfhi
\t%M0"
1966 [(set_attr "type" "imul")
1967 (set_attr "mode" "SI")
1968 (set_attr "length" "
12")])
1970 (define_insn_and_split "*mulsidi3_64bit"
1971 [(set (match_operand:DI
0 "register_operand" "=d")
1972 (mult:DI (match_operator:DI
1 "extend_operator"
1973 [(match_operand:SI
3 "register_operand" "d")])
1974 (match_operator:DI
2 "extend_operator"
1975 [(match_operand:SI
4 "register_operand" "d")])))
1976 (clobber (match_scratch:DI
5 "=l"))
1977 (clobber (match_scratch:DI
6 "=h"))
1978 (clobber (match_scratch:DI
7 "=d"))]
1979 "TARGET_64BIT && !TARGET_FIX_R4000
1980 && GET_CODE (operands[
1]) == GET_CODE (operands[
2])"
1982 "&& reload_completed"
1986 (mult:SI (match_dup
3)
1990 (mult:DI (match_dup
1)
1994 ;; OP7 <- LO, OP0 <- HI
1995 (set (match_dup
7) (match_dup
5))
1996 (set (match_dup
0) (match_dup
6))
2000 (ashift:DI (match_dup
7)
2003 (lshiftrt:DI (match_dup
7)
2006 ;; Shift OP0 into place.
2008 (ashift:DI (match_dup
0)
2011 ;; OR the two halves together
2013 (ior:DI (match_dup
0)
2016 [(set_attr "type" "imul")
2017 (set_attr "mode" "SI")
2018 (set_attr "length" "
24")])
2020 (define_insn "*mulsidi3_64bit_parts"
2021 [(set (match_operand:DI
0 "register_operand" "=l")
2023 (mult:SI (match_operand:SI
2 "register_operand" "d")
2024 (match_operand:SI
3 "register_operand" "d"))))
2025 (set (match_operand:DI
1 "register_operand" "=h")
2028 (match_operator:DI
4 "extend_operator" [(match_dup
2)])
2029 (match_operator:DI
5 "extend_operator" [(match_dup
3)]))
2031 "TARGET_64BIT && !TARGET_FIX_R4000
2032 && GET_CODE (operands[
4]) == GET_CODE (operands[
5])"
2034 if (GET_CODE (operands[
4]) == SIGN_EXTEND)
2035 return "mult
\t%
2,%
3";
2037 return "multu
\t%
2,%
3";
2039 [(set_attr "type" "imul")
2040 (set_attr "mode" "SI")])
2042 (define_expand "umulsidi3"
2044 [(set (match_operand:DI
0 "register_operand" "")
2046 (zero_extend:DI (match_operand:SI
1 "register_operand" ""))
2047 (zero_extend:DI (match_operand:SI
2 "register_operand" ""))))
2048 (clobber (scratch:DI))
2049 (clobber (scratch:DI))
2050 (clobber (scratch:DI))])]
2051 "!TARGET_64BIT || !TARGET_FIX_R4000"
2055 if (!TARGET_FIX_R4000)
2056 emit_insn (gen_umulsidi3_32bit_internal (operands[
0], operands[
1],
2059 emit_insn (gen_umulsidi3_32bit_r4000 (operands[
0], operands[
1],
2065 (define_insn "umulsidi3_32bit_internal"
2066 [(set (match_operand:DI
0 "register_operand" "=x")
2068 (zero_extend:DI (match_operand:SI
1 "register_operand" "d"))
2069 (zero_extend:DI (match_operand:SI
2 "register_operand" "d"))))]
2070 "!TARGET_64BIT && !TARGET_FIX_R4000"
2072 [(set_attr "type" "imul")
2073 (set_attr "mode" "SI")])
2075 (define_insn "umulsidi3_32bit_r4000"
2076 [(set (match_operand:DI
0 "register_operand" "=d")
2078 (zero_extend:DI (match_operand:SI
1 "register_operand" "d"))
2079 (zero_extend:DI (match_operand:SI
2 "register_operand" "d"))))
2080 (clobber (match_scratch:DI
3 "=l"))
2081 (clobber (match_scratch:DI
4 "=h"))]
2082 "!TARGET_64BIT && TARGET_FIX_R4000"
2083 "multu
\t%
1,%
2\;mflo
\t%L0;mfhi
\t%M0"
2084 [(set_attr "type" "imul")
2085 (set_attr "mode" "SI")
2086 (set_attr "length" "
12")])
2088 ;; Widening multiply with negation.
2089 (define_insn "*muls_di"
2090 [(set (match_operand:DI
0 "register_operand" "=x")
2093 (sign_extend:DI (match_operand:SI
1 "register_operand" "d"))
2094 (sign_extend:DI (match_operand:SI
2 "register_operand" "d")))))]
2095 "!TARGET_64BIT && ISA_HAS_MULS"
2097 [(set_attr "type" "imul")
2098 (set_attr "length" "
4")
2099 (set_attr "mode" "SI")])
2101 (define_insn "*umuls_di"
2102 [(set (match_operand:DI
0 "register_operand" "=x")
2105 (zero_extend:DI (match_operand:SI
1 "register_operand" "d"))
2106 (zero_extend:DI (match_operand:SI
2 "register_operand" "d")))))]
2107 "!TARGET_64BIT && ISA_HAS_MULS"
2109 [(set_attr "type" "imul")
2110 (set_attr "length" "
4")
2111 (set_attr "mode" "SI")])
2113 (define_insn "*smsac_di"
2114 [(set (match_operand:DI
0 "register_operand" "=x")
2116 (match_operand:DI
3 "register_operand" "
0")
2118 (sign_extend:DI (match_operand:SI
1 "register_operand" "d"))
2119 (sign_extend:DI (match_operand:SI
2 "register_operand" "d")))))]
2120 "!TARGET_64BIT && ISA_HAS_MSAC"
2122 if (TARGET_MIPS5500)
2123 return "msub
\t%
1,%
2";
2125 return "msac
\t$
0,%
1,%
2";
2127 [(set_attr "type" "imadd")
2128 (set_attr "length" "
4")
2129 (set_attr "mode" "SI")])
2131 (define_insn "*umsac_di"
2132 [(set (match_operand:DI
0 "register_operand" "=x")
2134 (match_operand:DI
3 "register_operand" "
0")
2136 (zero_extend:DI (match_operand:SI
1 "register_operand" "d"))
2137 (zero_extend:DI (match_operand:SI
2 "register_operand" "d")))))]
2138 "!TARGET_64BIT && ISA_HAS_MSAC"
2140 if (TARGET_MIPS5500)
2141 return "msubu
\t%
1,%
2";
2143 return "msacu
\t$
0,%
1,%
2";
2145 [(set_attr "type" "imadd")
2146 (set_attr "length" "
4")
2147 (set_attr "mode" "SI")])
2149 ;; _highpart patterns
2150 (define_expand "umulsi3_highpart"
2151 [(set (match_operand:SI
0 "register_operand" "")
2154 (mult:DI (zero_extend:DI (match_operand:SI
1 "register_operand" ""))
2155 (zero_extend:DI (match_operand:SI
2 "register_operand" "")))
2157 "ISA_HAS_MULHI || !TARGET_FIX_R4000"
2160 emit_insn (gen_umulsi3_highpart_mulhi_internal (operands[
0], operands[
1],
2163 emit_insn (gen_umulsi3_highpart_internal (operands[
0], operands[
1],
2168 (define_insn "umulsi3_highpart_internal"
2169 [(set (match_operand:SI
0 "register_operand" "=h")
2172 (mult:DI (zero_extend:DI (match_operand:SI
1 "register_operand" "d"))
2173 (zero_extend:DI (match_operand:SI
2 "register_operand" "d")))
2175 (clobber (match_scratch:SI
3 "=l"))]
2176 "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
2178 [(set_attr "type" "imul")
2179 (set_attr "mode" "SI")
2180 (set_attr "length" "
4")])
2182 (define_insn "umulsi3_highpart_mulhi_internal"
2183 [(set (match_operand:SI
0 "register_operand" "=h,d")
2186 (mult:DI (zero_extend:DI (match_operand:SI
1 "register_operand" "d,d"))
2187 (zero_extend:DI (match_operand:SI
2 "register_operand" "d,d")))
2189 (clobber (match_scratch:SI
3 "=l,l"))
2190 (clobber (match_scratch:SI
4 "=X,h"))]
2195 [(set_attr "type" "imul")
2196 (set_attr "mode" "SI")
2197 (set_attr "length" "
4")])
2199 (define_insn "umulsi3_highpart_neg_mulhi_internal"
2200 [(set (match_operand:SI
0 "register_operand" "=h,d")
2204 (mult:DI (zero_extend:DI (match_operand:SI
1 "register_operand" "d,d"))
2205 (zero_extend:DI (match_operand:SI
2 "register_operand" "d,d"))))
2207 (clobber (match_scratch:SI
3 "=l,l"))
2208 (clobber (match_scratch:SI
4 "=X,h"))]
2213 [(set_attr "type" "imul")
2214 (set_attr "mode" "SI")
2215 (set_attr "length" "
4")])
2217 (define_expand "smulsi3_highpart"
2218 [(set (match_operand:SI
0 "register_operand" "")
2221 (mult:DI (sign_extend:DI (match_operand:SI
1 "register_operand" ""))
2222 (sign_extend:DI (match_operand:SI
2 "register_operand" "")))
2224 "ISA_HAS_MULHI || !TARGET_FIX_R4000"
2227 emit_insn (gen_smulsi3_highpart_mulhi_internal (operands[
0], operands[
1],
2230 emit_insn (gen_smulsi3_highpart_internal (operands[
0], operands[
1],
2235 (define_insn "smulsi3_highpart_internal"
2236 [(set (match_operand:SI
0 "register_operand" "=h")
2239 (mult:DI (sign_extend:DI (match_operand:SI
1 "register_operand" "d"))
2240 (sign_extend:DI (match_operand:SI
2 "register_operand" "d")))
2242 (clobber (match_scratch:SI
3 "=l"))]
2243 "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
2245 [(set_attr "type" "imul")
2246 (set_attr "mode" "SI")
2247 (set_attr "length" "
4")])
2249 (define_insn "smulsi3_highpart_mulhi_internal"
2250 [(set (match_operand:SI
0 "register_operand" "=h,d")
2253 (mult:DI (sign_extend:DI (match_operand:SI
1 "register_operand" "d,d"))
2254 (sign_extend:DI (match_operand:SI
2 "register_operand" "d,d")))
2256 (clobber (match_scratch:SI
3 "=l,l"))
2257 (clobber (match_scratch:SI
4 "=X,h"))]
2262 [(set_attr "type" "imul")
2263 (set_attr "mode" "SI")
2264 (set_attr "length" "
4")])
2266 (define_insn "smulsi3_highpart_neg_mulhi_internal"
2267 [(set (match_operand:SI
0 "register_operand" "=h,d")
2271 (mult:DI (sign_extend:DI (match_operand:SI
1 "register_operand" "d,d"))
2272 (sign_extend:DI (match_operand:SI
2 "register_operand" "d,d"))))
2274 (clobber (match_scratch:SI
3 "=l,l"))
2275 (clobber (match_scratch:SI
4 "=X,h"))]
2280 [(set_attr "type" "imul")
2281 (set_attr "mode" "SI")])
2283 (define_insn "smuldi3_highpart"
2284 [(set (match_operand:DI
0 "register_operand" "=h")
2288 (sign_extend:TI (match_operand:DI
1 "register_operand" "d"))
2289 (sign_extend:TI (match_operand:DI
2 "register_operand" "d")))
2291 (clobber (match_scratch:DI
3 "=l"))]
2292 "TARGET_64BIT && !TARGET_FIX_R4000"
2294 [(set_attr "type" "imul")
2295 (set_attr "mode" "DI")])
2297 (define_insn "umuldi3_highpart"
2298 [(set (match_operand:DI
0 "register_operand" "=h")
2302 (zero_extend:TI (match_operand:DI
1 "register_operand" "d"))
2303 (zero_extend:TI (match_operand:DI
2 "register_operand" "d")))
2305 (clobber (match_scratch:DI
3 "=l"))]
2306 "TARGET_64BIT && !TARGET_FIX_R4000"
2308 [(set_attr "type" "imul")
2309 (set_attr "mode" "DI")])
2312 ;; The R4650 supports a
32 bit multiply/
64 bit accumulate
2313 ;; instruction. The HI/LO registers are used as a
64 bit accumulator.
2315 (define_insn "madsi"
2316 [(set (match_operand:SI
0 "register_operand" "+l")
2317 (plus:SI (mult:SI (match_operand:SI
1 "register_operand" "d")
2318 (match_operand:SI
2 "register_operand" "d"))
2320 (clobber (match_scratch:SI
3 "=h"))]
2323 [(set_attr "type" "imadd")
2324 (set_attr "mode" "SI")])
2326 (define_insn "*umul_acc_di"
2327 [(set (match_operand:DI
0 "register_operand" "=x")
2329 (mult:DI (zero_extend:DI (match_operand:SI
1 "register_operand" "d"))
2330 (zero_extend:DI (match_operand:SI
2 "register_operand" "d")))
2331 (match_operand:DI
3 "register_operand" "
0")))]
2332 "(TARGET_MAD || ISA_HAS_MACC)
2336 return "madu
\t%
1,%
2";
2337 else if (TARGET_MIPS5500)
2338 return "maddu
\t%
1,%
2";
2340 return "maccu
\t%.,%
1,%
2";
2342 [(set_attr "type" "imadd")
2343 (set_attr "mode" "SI")])
2346 (define_insn "*smul_acc_di"
2347 [(set (match_operand:DI
0 "register_operand" "=x")
2349 (mult:DI (sign_extend:DI (match_operand:SI
1 "register_operand" "d"))
2350 (sign_extend:DI (match_operand:SI
2 "register_operand" "d")))
2351 (match_operand:DI
3 "register_operand" "
0")))]
2352 "(TARGET_MAD || ISA_HAS_MACC)
2356 return "mad
\t%
1,%
2";
2357 else if (TARGET_MIPS5500)
2358 return "madd
\t%
1,%
2";
2360 return "macc
\t%.,%
1,%
2";
2362 [(set_attr "type" "imadd")
2363 (set_attr "mode" "SI")])
2365 ;; Floating point multiply accumulate instructions.
2368 [(set (match_operand:DF
0 "register_operand" "=f")
2369 (plus:DF (mult:DF (match_operand:DF
1 "register_operand" "f")
2370 (match_operand:DF
2 "register_operand" "f"))
2371 (match_operand:DF
3 "register_operand" "f")))]
2372 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2373 "madd.d
\t%
0,%
3,%
1,%
2"
2374 [(set_attr "type" "fmadd")
2375 (set_attr "mode" "DF")])
2378 [(set (match_operand:SF
0 "register_operand" "=f")
2379 (plus:SF (mult:SF (match_operand:SF
1 "register_operand" "f")
2380 (match_operand:SF
2 "register_operand" "f"))
2381 (match_operand:SF
3 "register_operand" "f")))]
2382 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2383 "madd.s
\t%
0,%
3,%
1,%
2"
2384 [(set_attr "type" "fmadd")
2385 (set_attr "mode" "SF")])
2388 [(set (match_operand:DF
0 "register_operand" "=f")
2389 (minus:DF (mult:DF (match_operand:DF
1 "register_operand" "f")
2390 (match_operand:DF
2 "register_operand" "f"))
2391 (match_operand:DF
3 "register_operand" "f")))]
2392 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2393 "msub.d
\t%
0,%
3,%
1,%
2"
2394 [(set_attr "type" "fmadd")
2395 (set_attr "mode" "DF")])
2398 [(set (match_operand:SF
0 "register_operand" "=f")
2399 (minus:SF (mult:SF (match_operand:SF
1 "register_operand" "f")
2400 (match_operand:SF
2 "register_operand" "f"))
2401 (match_operand:SF
3 "register_operand" "f")))]
2403 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2404 "msub.s
\t%
0,%
3,%
1,%
2"
2405 [(set_attr "type" "fmadd")
2406 (set_attr "mode" "SF")])
2409 [(set (match_operand:DF
0 "register_operand" "=f")
2410 (neg:DF (plus:DF (mult:DF (match_operand:DF
1 "register_operand" "f")
2411 (match_operand:DF
2 "register_operand" "f"))
2412 (match_operand:DF
3 "register_operand" "f"))))]
2413 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2414 "nmadd.d
\t%
0,%
3,%
1,%
2"
2415 [(set_attr "type" "fmadd")
2416 (set_attr "mode" "DF")])
2419 [(set (match_operand:SF
0 "register_operand" "=f")
2420 (neg:SF (plus:SF (mult:SF (match_operand:SF
1 "register_operand" "f")
2421 (match_operand:SF
2 "register_operand" "f"))
2422 (match_operand:SF
3 "register_operand" "f"))))]
2423 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2424 "nmadd.s
\t%
0,%
3,%
1,%
2"
2425 [(set_attr "type" "fmadd")
2426 (set_attr "mode" "SF")])
2429 [(set (match_operand:DF
0 "register_operand" "=f")
2430 (minus:DF (match_operand:DF
1 "register_operand" "f")
2431 (mult:DF (match_operand:DF
2 "register_operand" "f")
2432 (match_operand:DF
3 "register_operand" "f"))))]
2433 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2434 "nmsub.d
\t%
0,%
1,%
2,%
3"
2435 [(set_attr "type" "fmadd")
2436 (set_attr "mode" "DF")])
2439 [(set (match_operand:SF
0 "register_operand" "=f")
2440 (minus:SF (match_operand:SF
1 "register_operand" "f")
2441 (mult:SF (match_operand:SF
2 "register_operand" "f")
2442 (match_operand:SF
3 "register_operand" "f"))))]
2443 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2444 "nmsub.s
\t%
0,%
1,%
2,%
3"
2445 [(set_attr "type" "fmadd")
2446 (set_attr "mode" "SF")])
2449 ;; ....................
2451 ;; DIVISION and REMAINDER
2453 ;; ....................
2456 (define_expand "divdf3"
2457 [(set (match_operand:DF
0 "register_operand" "")
2458 (div:DF (match_operand:DF
1 "reg_or_const_float_1_operand" "")
2459 (match_operand:DF
2 "register_operand" "")))]
2460 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2462 if (const_float_1_operand (operands[
1], DFmode))
2463 if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
2467 ;; This pattern works around the early SB-
1 rev2 core "F1" erratum:
2469 ;; If an mfc1 or dmfc1 happens to access the floating point register
2470 ;; file at the same time a long latency operation (div, sqrt, recip,
2471 ;; sqrt) iterates an intermediate result back through the floating
2472 ;; point register file bypass, then instead returning the correct
2473 ;; register value the mfc1 or dmfc1 operation returns the intermediate
2474 ;; result of the long latency operation.
2476 ;; The workaround is to insert an unconditional 'mov' from/to the
2477 ;; long latency op destination register.
2479 (define_insn "*divdf3"
2480 [(set (match_operand:DF
0 "register_operand" "=f")
2481 (div:DF (match_operand:DF
1 "register_operand" "f")
2482 (match_operand:DF
2 "register_operand" "f")))]
2483 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2486 return "div.d
\t%
0,%
1,%
2\;mov.d
\t%
0,%
0";
2488 return "div.d
\t%
0,%
1,%
2";
2490 [(set_attr "type" "fdiv")
2491 (set_attr "mode" "DF")
2492 (set (attr "length")
2493 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int
0))
2498 ;; This pattern works around the early SB-
1 rev2 core "F2" erratum:
2500 ;; In certain cases, div.s and div.ps may have a rounding error
2501 ;; and/or wrong inexact flag.
2503 ;; Therefore, we only allow div.s if not working around SB-
1 rev2
2504 ;; errata, or if working around those errata and a slight loss of
2505 ;; precision is OK (i.e., flag_unsafe_math_optimizations is set).
2506 (define_expand "divsf3"
2507 [(set (match_operand:SF
0 "register_operand" "")
2508 (div:SF (match_operand:SF
1 "reg_or_const_float_1_operand" "")
2509 (match_operand:SF
2 "register_operand" "")))]
2510 "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
2512 if (const_float_1_operand (operands[
1], SFmode))
2513 if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
2517 ;; This pattern works around the early SB-
1 rev2 core "F1" erratum (see
2518 ;; "divdf3" comment for details).
2520 ;; This pattern works around the early SB-
1 rev2 core "F2" erratum (see
2521 ;; "divsf3" comment for details).
2522 (define_insn "*divsf3"
2523 [(set (match_operand:SF
0 "register_operand" "=f")
2524 (div:SF (match_operand:SF
1 "register_operand" "f")
2525 (match_operand:SF
2 "register_operand" "f")))]
2526 "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
2529 return "div.s
\t%
0,%
1,%
2\;mov.s
\t%
0,%
0";
2531 return "div.s
\t%
0,%
1,%
2";
2533 [(set_attr "type" "fdiv")
2534 (set_attr "mode" "SF")
2535 (set (attr "length")
2536 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int
0))
2540 ;; This pattern works around the early SB-
1 rev2 core "F1" erratum (see
2541 ;; "divdf3" comment for details).
2543 [(set (match_operand:DF
0 "register_operand" "=f")
2544 (div:DF (match_operand:DF
1 "const_float_1_operand" "")
2545 (match_operand:DF
2 "register_operand" "f")))]
2546 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2549 return "recip.d
\t%
0,%
2\;mov.d
\t%
0,%
0";
2551 return "recip.d
\t%
0,%
2";
2553 [(set_attr "type" "fdiv")
2554 (set_attr "mode" "DF")
2555 (set (attr "length")
2556 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int
0))
2560 ;; This pattern works around the early SB-
1 rev2 core "F1" erratum (see
2561 ;; "divdf3" comment for details).
2563 [(set (match_operand:SF
0 "register_operand" "=f")
2564 (div:SF (match_operand:SF
1 "const_float_1_operand" "")
2565 (match_operand:SF
2 "register_operand" "f")))]
2566 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2569 return "recip.s
\t%
0,%
2\;mov.s
\t%
0,%
0";
2571 return "recip.s
\t%
0,%
2";
2573 [(set_attr "type" "fdiv")
2574 (set_attr "mode" "SF")
2575 (set (attr "length")
2576 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int
0))
2580 (define_insn "divmodsi4"
2581 [(set (match_operand:SI
0 "register_operand" "=l")
2582 (div:SI (match_operand:SI
1 "register_operand" "d")
2583 (match_operand:SI
2 "register_operand" "d")))
2584 (set (match_operand:SI
3 "register_operand" "=h")
2585 (mod:SI (match_dup
1)
2588 { return mips_output_division ("div
\t$
0,%
1,%
2", operands); }
2589 [(set_attr "type" "idiv")
2590 (set_attr "mode" "SI")])
2592 (define_insn "divmoddi4"
2593 [(set (match_operand:DI
0 "register_operand" "=l")
2594 (div:DI (match_operand:DI
1 "register_operand" "d")
2595 (match_operand:DI
2 "register_operand" "d")))
2596 (set (match_operand:DI
3 "register_operand" "=h")
2597 (mod:DI (match_dup
1)
2600 { return mips_output_division ("ddiv
\t$
0,%
1,%
2", operands); }
2601 [(set_attr "type" "idiv")
2602 (set_attr "mode" "DI")])
2604 (define_insn "udivmodsi4"
2605 [(set (match_operand:SI
0 "register_operand" "=l")
2606 (udiv:SI (match_operand:SI
1 "register_operand" "d")
2607 (match_operand:SI
2 "register_operand" "d")))
2608 (set (match_operand:SI
3 "register_operand" "=h")
2609 (umod:SI (match_dup
1)
2612 { return mips_output_division ("divu
\t$
0,%
1,%
2", operands); }
2613 [(set_attr "type" "idiv")
2614 (set_attr "mode" "SI")])
2616 (define_insn "udivmoddi4"
2617 [(set (match_operand:DI
0 "register_operand" "=l")
2618 (udiv:DI (match_operand:DI
1 "register_operand" "d")
2619 (match_operand:DI
2 "register_operand" "d")))
2620 (set (match_operand:DI
3 "register_operand" "=h")
2621 (umod:DI (match_dup
1)
2624 { return mips_output_division ("ddivu
\t$
0,%
1,%
2", operands); }
2625 [(set_attr "type" "idiv")
2626 (set_attr "mode" "DI")])
2629 ;; ....................
2633 ;; ....................
2635 ;; This pattern works around the early SB-
1 rev2 core "F1" erratum (see
2636 ;; "divdf3" comment for details).
2637 (define_insn "sqrtdf2"
2638 [(set (match_operand:DF
0 "register_operand" "=f")
2639 (sqrt:DF (match_operand:DF
1 "register_operand" "f")))]
2640 "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
2643 return "sqrt.d
\t%
0,%
1\;mov.d
\t%
0,%
0";
2645 return "sqrt.d
\t%
0,%
1";
2647 [(set_attr "type" "fsqrt")
2648 (set_attr "mode" "DF")
2649 (set (attr "length")
2650 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int
0))
2654 ;; This pattern works around the early SB-
1 rev2 core "F1" erratum (see
2655 ;; "divdf3" comment for details).
2656 (define_insn "sqrtsf2"
2657 [(set (match_operand:SF
0 "register_operand" "=f")
2658 (sqrt:SF (match_operand:SF
1 "register_operand" "f")))]
2659 "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
2662 return "sqrt.s
\t%
0,%
1\;mov.s
\t%
0,%
0";
2664 return "sqrt.s
\t%
0,%
1";
2666 [(set_attr "type" "fsqrt")
2667 (set_attr "mode" "SF")
2668 (set (attr "length")
2669 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int
0))
2673 ;; This pattern works around the early SB-
1 rev2 core "F1" erratum (see
2674 ;; "divdf3" comment for details).
2676 [(set (match_operand:DF
0 "register_operand" "=f")
2677 (div:DF (match_operand:DF
1 "const_float_1_operand" "")
2678 (sqrt:DF (match_operand:DF
2 "register_operand" "f"))))]
2679 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2682 return "rsqrt.d
\t%
0,%
2\;mov.d
\t%
0,%
0";
2684 return "rsqrt.d
\t%
0,%
2";
2686 [(set_attr "type" "frsqrt")
2687 (set_attr "mode" "DF")
2688 (set (attr "length")
2689 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int
0))
2693 ;; This pattern works around the early SB-
1 rev2 core "F1" erratum (see
2694 ;; "divdf3" comment for details).
2696 [(set (match_operand:SF
0 "register_operand" "=f")
2697 (div:SF (match_operand:SF
1 "const_float_1_operand" "")
2698 (sqrt:SF (match_operand:SF
2 "register_operand" "f"))))]
2699 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2702 return "rsqrt.s
\t%
0,%
2\;mov.s
\t%
0,%
0";
2704 return "rsqrt.s
\t%
0,%
2";
2706 [(set_attr "type" "frsqrt")
2707 (set_attr "mode" "SF")
2708 (set (attr "length")
2709 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int
0))
2714 ;; ....................
2718 ;; ....................
2720 ;; Do not use the integer abs macro instruction, since that signals an
2721 ;; exception on -
2147483648 (sigh).
2723 (define_insn "abssi2"
2724 [(set (match_operand:SI
0 "register_operand" "=d")
2725 (abs:SI (match_operand:SI
1 "register_operand" "d")))]
2728 operands[
2] = const0_rtx;
2730 if (REGNO (operands[
0]) == REGNO (operands[
1]))
2732 if (GENERATE_BRANCHLIKELY)
2733 return "%(bltzl
\t%
1,
1f\;subu
\t%
0,%z2,%
0\n%~
1:%)";
2735 return "bgez
\t%
1,
1f%#\;subu
\t%
0,%z2,%
0\n%~
1:";
2738 return "%(bgez
\t%
1,
1f\;move
\t%
0,%
1\;subu
\t%
0,%z2,%
0\n%~
1:%)";
2740 [(set_attr "type" "multi")
2741 (set_attr "mode" "SI")
2742 (set_attr "length" "
12")])
2744 (define_insn "absdi2"
2745 [(set (match_operand:DI
0 "register_operand" "=d")
2746 (abs:DI (match_operand:DI
1 "register_operand" "d")))]
2747 "TARGET_64BIT && !TARGET_MIPS16"
2749 unsigned int regno1;
2750 operands[
2] = const0_rtx;
2752 if (GET_CODE (operands[
1]) == REG)
2753 regno1 = REGNO (operands[
1]);
2755 regno1 = REGNO (XEXP (operands[
1],
0));
2757 if (REGNO (operands[
0]) == regno1)
2758 return "%(bltzl
\t%
1,
1f\;dsubu
\t%
0,%z2,%
0\n%~
1:%)";
2760 return "%(bgez
\t%
1,
1f\;move
\t%
0,%
1\;dsubu
\t%
0,%z2,%
0\n%~
1:%)";
2762 [(set_attr "type" "multi")
2763 (set_attr "mode" "DI")
2764 (set_attr "length" "
12")])
2766 (define_insn "absdf2"
2767 [(set (match_operand:DF
0 "register_operand" "=f")
2768 (abs:DF (match_operand:DF
1 "register_operand" "f")))]
2769 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2771 [(set_attr "type" "fabs")
2772 (set_attr "mode" "DF")])
2774 (define_insn "abssf2"
2775 [(set (match_operand:SF
0 "register_operand" "=f")
2776 (abs:SF (match_operand:SF
1 "register_operand" "f")))]
2779 [(set_attr "type" "fabs")
2780 (set_attr "mode" "SF")])
2783 ;; ....................
2785 ;; FIND FIRST BIT INSTRUCTION
2787 ;; ....................
2790 (define_insn "ffssi2"
2791 [(set (match_operand:SI
0 "register_operand" "=&d")
2792 (ffs:SI (match_operand:SI
1 "register_operand" "d")))
2793 (clobber (match_scratch:SI
2 "=&d"))
2794 (clobber (match_scratch:SI
3 "=&d"))]
2797 if (optimize && find_reg_note (insn, REG_DEAD, operands[
1]))
2801 %~
1:
\tand
\t%
2,%
1,
0x0001\;\
2811 %~
1:
\tand
\t%
2,%
3,
0x0001\;\
2817 [(set_attr "type" "multi")
2818 (set_attr "mode" "SI")
2819 (set_attr "length" "
28")])
2821 (define_insn "ffsdi2"
2822 [(set (match_operand:DI
0 "register_operand" "=&d")
2823 (ffs:DI (match_operand:DI
1 "register_operand" "d")))
2824 (clobber (match_scratch:DI
2 "=&d"))
2825 (clobber (match_scratch:DI
3 "=&d"))]
2826 "TARGET_64BIT && !TARGET_MIPS16"
2828 if (optimize && find_reg_note (insn, REG_DEAD, operands[
1]))
2832 %~
1:
\tand
\t%
2,%
1,
0x0001\;\
2842 %~
1:
\tand
\t%
2,%
3,
0x0001\;\
2848 [(set_attr "type" "multi")
2849 (set_attr "mode" "DI")
2850 (set_attr "length" "
28")])
2853 ;; ...................
2855 ;; Count leading zeroes.
2857 ;; ...................
2860 (define_insn "clzsi2"
2861 [(set (match_operand:SI
0 "register_operand" "=d")
2862 (clz:SI (match_operand:SI
1 "register_operand" "d")))]
2865 [(set_attr "type" "arith")
2866 (set_attr "mode" "SI")])
2868 (define_insn "clzdi2"
2869 [(set (match_operand:DI
0 "register_operand" "=d")
2870 (clz:DI (match_operand:DI
1 "register_operand" "d")))]
2873 [(set_attr "type" "arith")
2874 (set_attr "mode" "DI")])
2877 ;; ....................
2879 ;; NEGATION and ONE'S COMPLEMENT
2881 ;; ....................
2883 (define_insn "negsi2"
2884 [(set (match_operand:SI
0 "register_operand" "=d")
2885 (neg:SI (match_operand:SI
1 "register_operand" "d")))]
2889 return "neg
\t%
0,%
1";
2891 return "subu
\t%
0,%.,%
1";
2893 [(set_attr "type" "arith")
2894 (set_attr "mode" "SI")])
2896 (define_expand "negdi2"
2897 [(parallel [(set (match_operand:DI
0 "register_operand" "=d")
2898 (neg:DI (match_operand:DI
1 "register_operand" "d")))
2899 (clobber (match_dup
2))])]
2900 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
2904 emit_insn (gen_negdi2_internal_2 (operands[
0], operands[
1]));
2908 operands[
2] = gen_reg_rtx (SImode);
2911 (define_insn "negdi2_internal"
2912 [(set (match_operand:DI
0 "register_operand" "=d")
2913 (neg:DI (match_operand:DI
1 "register_operand" "d")))
2914 (clobber (match_operand:SI
2 "register_operand" "=d"))]
2915 "! TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
2916 "subu
\t%L0,%.,%L1\;subu
\t%M0,%.,%M1\;sltu
\t%
2,%.,%L0\;subu
\t%M0,%M0,%
2"
2917 [(set_attr "type" "darith")
2918 (set_attr "mode" "DI")
2919 (set_attr "length" "
16")])
2921 (define_insn "negdi2_internal_2"
2922 [(set (match_operand:DI
0 "register_operand" "=d")
2923 (neg:DI (match_operand:DI
1 "register_operand" "d")))]
2924 "TARGET_64BIT && !TARGET_MIPS16"
2926 [(set_attr "type" "arith")
2927 (set_attr "mode" "DI")])
2929 (define_insn "negdf2"
2930 [(set (match_operand:DF
0 "register_operand" "=f")
2931 (neg:DF (match_operand:DF
1 "register_operand" "f")))]
2932 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2934 [(set_attr "type" "fneg")
2935 (set_attr "mode" "DF")])
2937 (define_insn "negsf2"
2938 [(set (match_operand:SF
0 "register_operand" "=f")
2939 (neg:SF (match_operand:SF
1 "register_operand" "f")))]
2942 [(set_attr "type" "fneg")
2943 (set_attr "mode" "SF")])
2945 (define_insn "one_cmplsi2"
2946 [(set (match_operand:SI
0 "register_operand" "=d")
2947 (not:SI (match_operand:SI
1 "register_operand" "d")))]
2951 return "not
\t%
0,%
1";
2953 return "nor
\t%
0,%.,%
1";
2955 [(set_attr "type" "arith")
2956 (set_attr "mode" "SI")])
2958 (define_insn "one_cmpldi2"
2959 [(set (match_operand:DI
0 "register_operand" "=d")
2960 (not:DI (match_operand:DI
1 "register_operand" "d")))]
2964 return "not
\t%
0,%
1";
2966 return "nor
\t%
0,%.,%
1";
2968 [(set_attr "type" "darith")
2969 (set_attr "mode" "DI")])
2972 ;; ....................
2976 ;; ....................
2979 ;; Many of these instructions use trivial define_expands, because we
2980 ;; want to use a different set of constraints when TARGET_MIPS16.
2982 (define_expand "andsi3"
2983 [(set (match_operand:SI
0 "register_operand" "=d,d")
2984 (and:SI (match_operand:SI
1 "uns_arith_operand" "%d,d")
2985 (match_operand:SI
2 "uns_arith_operand" "d,K")))]
2990 operands[
1] = force_reg (SImode, operands[
1]);
2991 operands[
2] = force_reg (SImode, operands[
2]);
2996 [(set (match_operand:SI
0 "register_operand" "=d,d")
2997 (and:SI (match_operand:SI
1 "uns_arith_operand" "%d,d")
2998 (match_operand:SI
2 "uns_arith_operand" "d,K")))]
3003 [(set_attr "type" "arith")
3004 (set_attr "mode" "SI")])
3007 [(set (match_operand:SI
0 "register_operand" "=d")
3008 (and:SI (match_operand:SI
1 "register_operand" "%
0")
3009 (match_operand:SI
2 "register_operand" "d")))]
3012 [(set_attr "type" "arith")
3013 (set_attr "mode" "SI")])
3015 (define_expand "anddi3"
3016 [(set (match_operand:DI
0 "register_operand" "")
3017 (and:DI (match_operand:DI
1 "register_operand" "")
3018 (match_operand:DI
2 "uns_arith_operand" "")))]
3023 operands[
1] = force_reg (DImode, operands[
1]);
3024 operands[
2] = force_reg (DImode, operands[
2]);
3029 [(set (match_operand:DI
0 "register_operand" "=d,d")
3030 (and:DI (match_operand:DI
1 "register_operand" "d,d")
3031 (match_operand:DI
2 "uns_arith_operand" "d,K")))]
3032 "TARGET_64BIT && !TARGET_MIPS16"
3036 [(set_attr "type" "darith")
3037 (set_attr "mode" "DI")])
3040 [(set (match_operand:DI
0 "register_operand" "=d")
3041 (and:DI (match_operand:DI
1 "register_operand" "
0")
3042 (match_operand:DI
2 "register_operand" "d")))]
3043 "TARGET_64BIT && TARGET_MIPS16"
3045 [(set_attr "type" "darith")
3046 (set_attr "mode" "DI")])
3048 (define_expand "iorsi3"
3049 [(set (match_operand:SI
0 "register_operand" "=d,d")
3050 (ior:SI (match_operand:SI
1 "uns_arith_operand" "%d,d")
3051 (match_operand:SI
2 "uns_arith_operand" "d,K")))]
3056 operands[
1] = force_reg (SImode, operands[
1]);
3057 operands[
2] = force_reg (SImode, operands[
2]);
3062 [(set (match_operand:SI
0 "register_operand" "=d,d")
3063 (ior:SI (match_operand:SI
1 "uns_arith_operand" "%d,d")
3064 (match_operand:SI
2 "uns_arith_operand" "d,K")))]
3069 [(set_attr "type" "arith")
3070 (set_attr "mode" "SI")])
3073 [(set (match_operand:SI
0 "register_operand" "=d")
3074 (ior:SI (match_operand:SI
1 "register_operand" "%
0")
3075 (match_operand:SI
2 "register_operand" "d")))]
3078 [(set_attr "type" "arith")
3079 (set_attr "mode" "SI")])
3081 (define_expand "iordi3"
3082 [(set (match_operand:DI
0 "register_operand" "")
3083 (ior:DI (match_operand:DI
1 "register_operand" "")
3084 (match_operand:DI
2 "uns_arith_operand" "")))]
3089 operands[
1] = force_reg (DImode, operands[
1]);
3090 operands[
2] = force_reg (DImode, operands[
2]);
3095 [(set (match_operand:DI
0 "register_operand" "=d,d")
3096 (ior:DI (match_operand:DI
1 "register_operand" "d,d")
3097 (match_operand:DI
2 "uns_arith_operand" "d,K")))]
3098 "TARGET_64BIT && !TARGET_MIPS16"
3102 [(set_attr "type" "darith")
3103 (set_attr "mode" "DI")])
3106 [(set (match_operand:DI
0 "register_operand" "=d")
3107 (ior:DI (match_operand:DI
1 "register_operand" "
0")
3108 (match_operand:DI
2 "register_operand" "d")))]
3109 "TARGET_64BIT && TARGET_MIPS16"
3111 [(set_attr "type" "darith")
3112 (set_attr "mode" "DI")])
3114 (define_expand "xorsi3"
3115 [(set (match_operand:SI
0 "register_operand" "=d,d")
3116 (xor:SI (match_operand:SI
1 "uns_arith_operand" "%d,d")
3117 (match_operand:SI
2 "uns_arith_operand" "d,K")))]
3122 [(set (match_operand:SI
0 "register_operand" "=d,d")
3123 (xor:SI (match_operand:SI
1 "uns_arith_operand" "%d,d")
3124 (match_operand:SI
2 "uns_arith_operand" "d,K")))]
3129 [(set_attr "type" "arith")
3130 (set_attr "mode" "SI")])
3133 [(set (match_operand:SI
0 "register_operand" "=d,t,t")
3134 (xor:SI (match_operand:SI
1 "uns_arith_operand" "%
0,d,d")
3135 (match_operand:SI
2 "uns_arith_operand" "d,K,d")))]
3141 [(set_attr "type" "arith")
3142 (set_attr "mode" "SI")
3143 (set_attr_alternative "length"
3145 (if_then_else (match_operand:VOID
2 "m16_uimm8_1" "")
3150 (define_expand "xordi3"
3151 [(set (match_operand:DI
0 "register_operand" "")
3152 (xor:DI (match_operand:DI
1 "register_operand" "")
3153 (match_operand:DI
2 "uns_arith_operand" "")))]
3158 operands[
1] = force_reg (DImode, operands[
1]);
3159 operands[
2] = force_reg (DImode, operands[
2]);
3164 [(set (match_operand:DI
0 "register_operand" "=d,d")
3165 (xor:DI (match_operand:DI
1 "register_operand" "d,d")
3166 (match_operand:DI
2 "uns_arith_operand" "d,K")))]
3167 "TARGET_64BIT && !TARGET_MIPS16"
3171 [(set_attr "type" "darith")
3172 (set_attr "mode" "DI")])
3175 [(set (match_operand:DI
0 "register_operand" "=d,t,t")
3176 (xor:DI (match_operand:DI
1 "register_operand" "%
0,d,d")
3177 (match_operand:DI
2 "uns_arith_operand" "d,K,d")))]
3178 "TARGET_64BIT && TARGET_MIPS16"
3183 [(set_attr "type" "arith")
3184 (set_attr "mode" "DI")
3185 (set_attr_alternative "length"
3187 (if_then_else (match_operand:VOID
2 "m16_uimm8_1" "")
3192 (define_insn "*norsi3"
3193 [(set (match_operand:SI
0 "register_operand" "=d")
3194 (and:SI (not:SI (match_operand:SI
1 "register_operand" "d"))
3195 (not:SI (match_operand:SI
2 "register_operand" "d"))))]
3198 [(set_attr "type" "arith")
3199 (set_attr "mode" "SI")])
3201 (define_insn "*nordi3"
3202 [(set (match_operand:DI
0 "register_operand" "=d")
3203 (and:DI (not:DI (match_operand:DI
1 "register_operand" "d"))
3204 (not:DI (match_operand:DI
2 "register_operand" "d"))))]
3205 "TARGET_64BIT && !TARGET_MIPS16"
3207 [(set_attr "type" "darith")
3208 (set_attr "mode" "DI")])
3211 ;; ....................
3215 ;; ....................
3219 (define_insn "truncdfsf2"
3220 [(set (match_operand:SF
0 "register_operand" "=f")
3221 (float_truncate:SF (match_operand:DF
1 "register_operand" "f")))]
3222 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3224 [(set_attr "type" "fcvt")
3225 (set_attr "mode" "SF")])
3227 ;; Integer truncation patterns. Truncating SImode values to smaller
3228 ;; modes is a no-op, as it is for most other GCC ports. Truncating
3229 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
3230 ;; need to make sure that the lower
32 bits are properly sign-extended
3231 ;; (see TRULY_NOOP_TRUNCATION). Truncating DImode values into modes
3232 ;; smaller than SImode is equivalent to two separate truncations:
3235 ;; DI ---> HI == DI ---> SI ---> HI
3236 ;; DI ---> QI == DI ---> SI ---> QI
3238 ;; Step A needs a real instruction but step B does not.
3240 (define_insn "truncdisi2"
3241 [(set (match_operand:SI
0 "nonimmediate_operand" "=d,m")
3242 (truncate:SI (match_operand:DI
1 "register_operand" "d,d")))]
3247 [(set_attr "type" "darith,store")
3248 (set_attr "mode" "SI")
3249 (set_attr "extended_mips16" "yes,*")])
3251 (define_insn "truncdihi2"
3252 [(set (match_operand:HI
0 "nonimmediate_operand" "=d,m")
3253 (truncate:HI (match_operand:DI
1 "register_operand" "d,d")))]
3258 [(set_attr "type" "darith,store")
3259 (set_attr "mode" "SI")
3260 (set_attr "extended_mips16" "yes,*")])
3262 (define_insn "truncdiqi2"
3263 [(set (match_operand:QI
0 "nonimmediate_operand" "=d,m")
3264 (truncate:QI (match_operand:DI
1 "register_operand" "d,d")))]
3269 [(set_attr "type" "darith,store")
3270 (set_attr "mode" "SI")
3271 (set_attr "extended_mips16" "yes,*")])
3273 ;; Combiner patterns to optimize shift/truncate combinations.
3276 [(set (match_operand:SI
0 "register_operand" "=d")
3277 (truncate:SI (ashiftrt:DI (match_operand:DI
1 "register_operand" "d")
3278 (match_operand:DI
2 "small_int" "I"))))]
3279 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[
2]) >=
32"
3281 [(set_attr "type" "darith")
3282 (set_attr "mode" "SI")])
3285 [(set (match_operand:SI
0 "register_operand" "=d")
3286 (truncate:SI (lshiftrt:DI (match_operand:DI
1 "register_operand" "d")
3288 "TARGET_64BIT && !TARGET_MIPS16"
3290 [(set_attr "type" "darith")
3291 (set_attr "mode" "SI")])
3294 ;; Combiner patterns for truncate/sign_extend combinations. They use
3295 ;; the shift/truncate patterns above.
3297 (define_insn_and_split ""
3298 [(set (match_operand:SI
0 "register_operand" "=d")
3300 (truncate:HI (match_operand:DI
1 "register_operand" "d"))))]
3301 "TARGET_64BIT && !TARGET_MIPS16"
3303 "&& reload_completed"
3305 (ashift:DI (match_dup
1)
3308 (truncate:SI (ashiftrt:DI (match_dup
2)
3310 { operands[
2] = gen_lowpart (DImode, operands[
0]); })
3312 (define_insn_and_split ""
3313 [(set (match_operand:SI
0 "register_operand" "=d")
3315 (truncate:QI (match_operand:DI
1 "register_operand" "d"))))]
3316 "TARGET_64BIT && !TARGET_MIPS16"
3318 "&& reload_completed"
3320 (ashift:DI (match_dup
1)
3323 (truncate:SI (ashiftrt:DI (match_dup
2)
3325 { operands[
2] = gen_lowpart (DImode, operands[
0]); })
3328 ;; Combiner patterns to optimize truncate/zero_extend combinations.
3331 [(set (match_operand:SI
0 "register_operand" "=d")
3332 (zero_extend:SI (truncate:HI
3333 (match_operand:DI
1 "register_operand" "d"))))]
3334 "TARGET_64BIT && !TARGET_MIPS16"
3335 "andi
\t%
0,%
1,
0xffff"
3336 [(set_attr "type" "darith")
3337 (set_attr "mode" "SI")])
3340 [(set (match_operand:SI
0 "register_operand" "=d")
3341 (zero_extend:SI (truncate:QI
3342 (match_operand:DI
1 "register_operand" "d"))))]
3343 "TARGET_64BIT && !TARGET_MIPS16"
3345 [(set_attr "type" "darith")
3346 (set_attr "mode" "SI")])
3349 [(set (match_operand:HI
0 "register_operand" "=d")
3350 (zero_extend:HI (truncate:QI
3351 (match_operand:DI
1 "register_operand" "d"))))]
3352 "TARGET_64BIT && !TARGET_MIPS16"
3354 [(set_attr "type" "darith")
3355 (set_attr "mode" "HI")])
3358 ;; ....................
3362 ;; ....................
3365 ;; Those for integer source operand are ordered widest source type first.
3367 (define_insn_and_split "zero_extendsidi2"
3368 [(set (match_operand:DI
0 "register_operand" "=d")
3369 (zero_extend:DI (match_operand:SI
1 "register_operand" "d")))]
3372 "&& reload_completed"
3374 (ashift:DI (match_dup
1) (const_int
32)))
3376 (lshiftrt:DI (match_dup
0) (const_int
32)))]
3377 "operands[
1] = gen_lowpart (DImode, operands[
1]);"
3378 [(set_attr "type" "arith")
3379 (set_attr "mode" "DI")])
3381 (define_insn "*zero_extendsidi2_mem"
3382 [(set (match_operand:DI
0 "register_operand" "=d")
3383 (zero_extend:DI (match_operand:SI
1 "memory_operand" "W")))]
3386 [(set_attr "type" "load")
3387 (set_attr "mode" "DI")])
3389 (define_expand "zero_extendhisi2"
3390 [(set (match_operand:SI
0 "register_operand" "")
3391 (zero_extend:SI (match_operand:HI
1 "nonimmediate_operand" "")))]
3394 if (TARGET_MIPS16 && GET_CODE (operands[
1]) != MEM)
3396 rtx op = gen_lowpart (SImode, operands[
1]);
3397 rtx temp = force_reg (SImode, GEN_INT (
0xffff));
3399 emit_insn (gen_andsi3 (operands[
0], op, temp));
3405 [(set (match_operand:SI
0 "register_operand" "=d,d")
3406 (zero_extend:SI (match_operand:HI
1 "nonimmediate_operand" "d,m")))]
3411 [(set_attr "type" "arith,load")
3412 (set_attr "mode" "SI")
3413 (set_attr "length" "
4,*")])
3416 [(set (match_operand:SI
0 "register_operand" "=d")
3417 (zero_extend:SI (match_operand:HI
1 "memory_operand" "m")))]
3420 [(set_attr "type" "load")
3421 (set_attr "mode" "SI")])
3423 (define_expand "zero_extendhidi2"
3424 [(set (match_operand:DI
0 "register_operand" "")
3425 (zero_extend:DI (match_operand:HI
1 "nonimmediate_operand" "")))]
3428 if (TARGET_MIPS16 && GET_CODE (operands[
1]) != MEM)
3430 rtx op = gen_lowpart (DImode, operands[
1]);
3431 rtx temp = force_reg (DImode, GEN_INT (
0xffff));
3433 emit_insn (gen_anddi3 (operands[
0], op, temp));
3439 [(set (match_operand:DI
0 "register_operand" "=d,d")
3440 (zero_extend:DI (match_operand:HI
1 "nonimmediate_operand" "d,m")))]
3441 "TARGET_64BIT && !TARGET_MIPS16"
3445 [(set_attr "type" "arith,load")
3446 (set_attr "mode" "DI")
3447 (set_attr "length" "
4,*")])
3450 [(set (match_operand:DI
0 "register_operand" "=d")
3451 (zero_extend:DI (match_operand:HI
1 "memory_operand" "m")))]
3452 "TARGET_64BIT && TARGET_MIPS16"
3454 [(set_attr "type" "load")
3455 (set_attr "mode" "DI")])
3457 (define_expand "zero_extendqihi2"
3458 [(set (match_operand:HI
0 "register_operand" "")
3459 (zero_extend:HI (match_operand:QI
1 "nonimmediate_operand" "")))]
3462 if (TARGET_MIPS16 && GET_CODE (operands[
1]) != MEM)
3464 rtx op0 = gen_lowpart (SImode, operands[
0]);
3465 rtx op1 = gen_lowpart (SImode, operands[
1]);
3466 rtx temp = force_reg (SImode, GEN_INT (
0xff));
3468 emit_insn (gen_andsi3 (op0, op1, temp));
3474 [(set (match_operand:HI
0 "register_operand" "=d,d")
3475 (zero_extend:HI (match_operand:QI
1 "nonimmediate_operand" "d,m")))]
3480 [(set_attr "type" "arith,load")
3481 (set_attr "mode" "HI")
3482 (set_attr "length" "
4,*")])
3485 [(set (match_operand:HI
0 "register_operand" "=d")
3486 (zero_extend:HI (match_operand:QI
1 "memory_operand" "m")))]
3489 [(set_attr "type" "load")
3490 (set_attr "mode" "HI")])
3492 (define_expand "zero_extendqisi2"
3493 [(set (match_operand:SI
0 "register_operand" "")
3494 (zero_extend:SI (match_operand:QI
1 "nonimmediate_operand" "")))]
3497 if (TARGET_MIPS16 && GET_CODE (operands[
1]) != MEM)
3499 rtx op = gen_lowpart (SImode, operands[
1]);
3500 rtx temp = force_reg (SImode, GEN_INT (
0xff));
3502 emit_insn (gen_andsi3 (operands[
0], op, temp));
3508 [(set (match_operand:SI
0 "register_operand" "=d,d")
3509 (zero_extend:SI (match_operand:QI
1 "nonimmediate_operand" "d,m")))]
3514 [(set_attr "type" "arith,load")
3515 (set_attr "mode" "SI")
3516 (set_attr "length" "
4,*")])
3519 [(set (match_operand:SI
0 "register_operand" "=d")
3520 (zero_extend:SI (match_operand:QI
1 "memory_operand" "m")))]
3523 [(set_attr "type" "load")
3524 (set_attr "mode" "SI")])
3526 (define_expand "zero_extendqidi2"
3527 [(set (match_operand:DI
0 "register_operand" "")
3528 (zero_extend:DI (match_operand:QI
1 "nonimmediate_operand" "")))]
3531 if (TARGET_MIPS16 && GET_CODE (operands[
1]) != MEM)
3533 rtx op = gen_lowpart (DImode, operands[
1]);
3534 rtx temp = force_reg (DImode, GEN_INT (
0xff));
3536 emit_insn (gen_anddi3 (operands[
0], op, temp));
3542 [(set (match_operand:DI
0 "register_operand" "=d,d")
3543 (zero_extend:DI (match_operand:QI
1 "nonimmediate_operand" "d,m")))]
3544 "TARGET_64BIT && !TARGET_MIPS16"
3548 [(set_attr "type" "arith,load")
3549 (set_attr "mode" "DI")
3550 (set_attr "length" "
4,*")])
3553 [(set (match_operand:DI
0 "register_operand" "=d")
3554 (zero_extend:DI (match_operand:QI
1 "memory_operand" "m")))]
3555 "TARGET_64BIT && TARGET_MIPS16"
3557 [(set_attr "type" "load")
3558 (set_attr "mode" "DI")])
3561 ;; ....................
3565 ;; ....................
3568 ;; Those for integer source operand are ordered widest source type first.
3570 (define_insn "extendsidi2"
3571 [(set (match_operand:DI
0 "register_operand" "=d,d")
3572 (sign_extend:DI (match_operand:SI
1 "nonimmediate_operand" "d,m")))]
3577 [(set_attr "type" "arith,load")
3578 (set_attr "mode" "DI")
3579 (set_attr "extended_mips16" "yes,*")])
3581 ;; These patterns originally accepted general_operands, however, slightly
3582 ;; better code is generated by only accepting register_operands, and then
3583 ;; letting combine generate the lh and lb insns.
3585 ;; These expanders originally put values in registers first. We split
3586 ;; all non-mem patterns after reload.
3588 (define_expand "extendhidi2"
3589 [(set (match_operand:DI
0 "register_operand" "")
3590 (sign_extend:DI (match_operand:HI
1 "nonimmediate_operand" "")))]
3594 (define_insn "*extendhidi2"
3595 [(set (match_operand:DI
0 "register_operand" "=d")
3596 (sign_extend:DI (match_operand:HI
1 "register_operand" "d")))]
3601 [(set (match_operand:DI
0 "register_operand" "")
3602 (sign_extend:DI (match_operand:HI
1 "register_operand" "")))]
3603 "TARGET_64BIT && reload_completed"
3605 (ashift:DI (match_dup
1) (const_int
48)))
3607 (ashiftrt:DI (match_dup
0) (const_int
48)))]
3608 "operands[
1] = gen_lowpart (DImode, operands[
1]);")
3610 (define_insn "*extendhidi2_mem"
3611 [(set (match_operand:DI
0 "register_operand" "=d")
3612 (sign_extend:DI (match_operand:HI
1 "memory_operand" "m")))]
3615 [(set_attr "type" "load")
3616 (set_attr "mode" "DI")])
3618 (define_expand "extendhisi2"
3619 [(set (match_operand:SI
0 "register_operand" "")
3620 (sign_extend:SI (match_operand:HI
1 "nonimmediate_operand" "")))]
3623 if (ISA_HAS_SEB_SEH)
3625 emit_insn (gen_extendhisi2_hw (operands[
0],
3626 force_reg (HImode, operands[
1])));
3631 (define_insn "*extendhisi2"
3632 [(set (match_operand:SI
0 "register_operand" "=d")
3633 (sign_extend:SI (match_operand:HI
1 "register_operand" "d")))]
3638 [(set (match_operand:SI
0 "register_operand" "")
3639 (sign_extend:SI (match_operand:HI
1 "register_operand" "")))]
3642 (ashift:SI (match_dup
1) (const_int
16)))
3644 (ashiftrt:SI (match_dup
0) (const_int
16)))]
3645 "operands[
1] = gen_lowpart (SImode, operands[
1]);")
3647 (define_insn "extendhisi2_mem"
3648 [(set (match_operand:SI
0 "register_operand" "=d")
3649 (sign_extend:SI (match_operand:HI
1 "memory_operand" "m")))]
3652 [(set_attr "type" "load")
3653 (set_attr "mode" "SI")])
3655 (define_insn "extendhisi2_hw"
3656 [(set (match_operand:SI
0 "register_operand" "=r")
3657 (sign_extend:SI (match_operand:HI
1 "register_operand" "r")))]
3660 [(set_attr "type" "arith")
3661 (set_attr "mode" "SI")])
3663 (define_expand "extendqihi2"
3664 [(set (match_operand:HI
0 "register_operand" "")
3665 (sign_extend:HI (match_operand:QI
1 "nonimmediate_operand" "")))]
3669 (define_insn "*extendqihi2"
3670 [(set (match_operand:HI
0 "register_operand" "=d")
3671 (sign_extend:HI (match_operand:QI
1 "register_operand" "d")))]
3676 [(set (match_operand:HI
0 "register_operand" "")
3677 (sign_extend:HI (match_operand:QI
1 "register_operand" "")))]
3680 (ashift:SI (match_dup
1) (const_int
24)))
3682 (ashiftrt:SI (match_dup
0) (const_int
24)))]
3683 "operands[
0] = gen_lowpart (SImode, operands[
0]);
3684 operands[
1] = gen_lowpart (SImode, operands[
1]);")
3686 (define_insn "*extendqihi2_internal_mem"
3687 [(set (match_operand:HI
0 "register_operand" "=d")
3688 (sign_extend:HI (match_operand:QI
1 "memory_operand" "m")))]
3691 [(set_attr "type" "load")
3692 (set_attr "mode" "SI")])
3695 (define_expand "extendqisi2"
3696 [(set (match_operand:SI
0 "register_operand" "")
3697 (sign_extend:SI (match_operand:QI
1 "nonimmediate_operand" "")))]
3700 if (ISA_HAS_SEB_SEH)
3702 emit_insn (gen_extendqisi2_hw (operands[
0],
3703 force_reg (QImode, operands[
1])));
3708 (define_insn "*extendqisi2"
3709 [(set (match_operand:SI
0 "register_operand" "=d")
3710 (sign_extend:SI (match_operand:QI
1 "register_operand" "d")))]
3715 [(set (match_operand:SI
0 "register_operand" "")
3716 (sign_extend:SI (match_operand:QI
1 "register_operand" "")))]
3719 (ashift:SI (match_dup
1) (const_int
24)))
3721 (ashiftrt:SI (match_dup
0) (const_int
24)))]
3722 "operands[
1] = gen_lowpart (SImode, operands[
1]);")
3724 (define_insn "*extendqisi2_mem"
3725 [(set (match_operand:SI
0 "register_operand" "=d")
3726 (sign_extend:SI (match_operand:QI
1 "memory_operand" "m")))]
3729 [(set_attr "type" "load")
3730 (set_attr "mode" "SI")])
3732 (define_insn "extendqisi2_hw"
3733 [(set (match_operand:SI
0 "register_operand" "=r")
3734 (sign_extend:SI (match_operand:QI
1 "register_operand" "r")))]
3737 [(set_attr "type" "arith")
3738 (set_attr "mode" "SI")])
3740 (define_expand "extendqidi2"
3741 [(set (match_operand:DI
0 "register_operand" "")
3742 (sign_extend:DI (match_operand:QI
1 "nonimmediate_operand" "")))]
3746 (define_insn "*extendqidi2"
3747 [(set (match_operand:DI
0 "register_operand" "=d")
3748 (sign_extend:DI (match_operand:QI
1 "register_operand" "d")))]
3753 [(set (match_operand:DI
0 "register_operand" "")
3754 (sign_extend:DI (match_operand:QI
1 "register_operand" "")))]
3755 "TARGET_64BIT && reload_completed"
3757 (ashift:DI (match_dup
1) (const_int
56)))
3759 (ashiftrt:DI (match_dup
0) (const_int
56)))]
3760 "operands[
1] = gen_lowpart (DImode, operands[
1]);")
3762 (define_insn "*extendqidi2_mem"
3763 [(set (match_operand:DI
0 "register_operand" "=d")
3764 (sign_extend:DI (match_operand:QI
1 "memory_operand" "m")))]
3767 [(set_attr "type" "load")
3768 (set_attr "mode" "DI")])
3770 (define_insn "extendsfdf2"
3771 [(set (match_operand:DF
0 "register_operand" "=f")
3772 (float_extend:DF (match_operand:SF
1 "register_operand" "f")))]
3773 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3775 [(set_attr "type" "fcvt")
3776 (set_attr "mode" "DF")])
3779 ;; ....................
3783 ;; ....................
3785 (define_expand "fix_truncdfsi2"
3786 [(set (match_operand:SI
0 "register_operand" "=f")
3787 (fix:SI (match_operand:DF
1 "register_operand" "f")))]
3788 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3790 if (!ISA_HAS_TRUNC_W)
3792 emit_insn (gen_fix_truncdfsi2_macro (operands[
0], operands[
1]));
3797 (define_insn "fix_truncdfsi2_insn"
3798 [(set (match_operand:SI
0 "register_operand" "=f")
3799 (fix:SI (match_operand:DF
1 "register_operand" "f")))]
3800 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
3802 [(set_attr "type" "fcvt")
3803 (set_attr "mode" "DF")
3804 (set_attr "length" "
4")])
3806 (define_insn "fix_truncdfsi2_macro"
3807 [(set (match_operand:SI
0 "register_operand" "=f")
3808 (fix:SI (match_operand:DF
1 "register_operand" "f")))
3809 (clobber (match_scratch:DF
2 "=d"))]
3810 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
3813 return ".set
\tmacro\;trunc.w.d %
0,%
1,%
2\;.set
\tnomacro";
3815 return "trunc.w.d %
0,%
1,%
2";
3817 [(set_attr "type" "fcvt")
3818 (set_attr "mode" "DF")
3819 (set_attr "length" "
36")])
3821 (define_expand "fix_truncsfsi2"
3822 [(set (match_operand:SI
0 "register_operand" "=f")
3823 (fix:SI (match_operand:SF
1 "register_operand" "f")))]
3826 if (!ISA_HAS_TRUNC_W)
3828 emit_insn (gen_fix_truncsfsi2_macro (operands[
0], operands[
1]));
3833 (define_insn "fix_truncsfsi2_insn"
3834 [(set (match_operand:SI
0 "register_operand" "=f")
3835 (fix:SI (match_operand:SF
1 "register_operand" "f")))]
3836 "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
3838 [(set_attr "type" "fcvt")
3839 (set_attr "mode" "DF")
3840 (set_attr "length" "
4")])
3842 (define_insn "fix_truncsfsi2_macro"
3843 [(set (match_operand:SI
0 "register_operand" "=f")
3844 (fix:SI (match_operand:SF
1 "register_operand" "f")))
3845 (clobber (match_scratch:SF
2 "=d"))]
3846 "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
3849 return ".set
\tmacro\;trunc.w.s %
0,%
1,%
2\;.set
\tnomacro";
3851 return "trunc.w.s %
0,%
1,%
2";
3853 [(set_attr "type" "fcvt")
3854 (set_attr "mode" "DF")
3855 (set_attr "length" "
36")])
3858 (define_insn "fix_truncdfdi2"
3859 [(set (match_operand:DI
0 "register_operand" "=f")
3860 (fix:DI (match_operand:DF
1 "register_operand" "f")))]
3861 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3863 [(set_attr "type" "fcvt")
3864 (set_attr "mode" "DF")
3865 (set_attr "length" "
4")])
3868 (define_insn "fix_truncsfdi2"
3869 [(set (match_operand:DI
0 "register_operand" "=f")
3870 (fix:DI (match_operand:SF
1 "register_operand" "f")))]
3871 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3873 [(set_attr "type" "fcvt")
3874 (set_attr "mode" "SF")
3875 (set_attr "length" "
4")])
3878 (define_insn "floatsidf2"
3879 [(set (match_operand:DF
0 "register_operand" "=f")
3880 (float:DF (match_operand:SI
1 "register_operand" "f")))]
3881 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3883 [(set_attr "type" "fcvt")
3884 (set_attr "mode" "DF")
3885 (set_attr "length" "
4")])
3888 (define_insn "floatdidf2"
3889 [(set (match_operand:DF
0 "register_operand" "=f")
3890 (float:DF (match_operand:DI
1 "register_operand" "f")))]
3891 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3893 [(set_attr "type" "fcvt")
3894 (set_attr "mode" "DF")
3895 (set_attr "length" "
4")])
3898 (define_insn "floatsisf2"
3899 [(set (match_operand:SF
0 "register_operand" "=f")
3900 (float:SF (match_operand:SI
1 "register_operand" "f")))]
3903 [(set_attr "type" "fcvt")
3904 (set_attr "mode" "SF")
3905 (set_attr "length" "
4")])
3908 (define_insn "floatdisf2"
3909 [(set (match_operand:SF
0 "register_operand" "=f")
3910 (float:SF (match_operand:DI
1 "register_operand" "f")))]
3911 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3913 [(set_attr "type" "fcvt")
3914 (set_attr "mode" "SF")
3915 (set_attr "length" "
4")])
3918 (define_expand "fixuns_truncdfsi2"
3919 [(set (match_operand:SI
0 "register_operand" "")
3920 (unsigned_fix:SI (match_operand:DF
1 "register_operand" "")))]
3921 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3923 rtx reg1 = gen_reg_rtx (DFmode);
3924 rtx reg2 = gen_reg_rtx (DFmode);
3925 rtx reg3 = gen_reg_rtx (SImode);
3926 rtx label1 = gen_label_rtx ();
3927 rtx label2 = gen_label_rtx ();
3928 REAL_VALUE_TYPE offset;
3930 real_2expN (&offset,
31);
3932 if (reg1) /* Turn off complaints about unreached code. */
3934 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3935 do_pending_stack_adjust ();
3937 emit_insn (gen_cmpdf (operands[
1], reg1));
3938 emit_jump_insn (gen_bge (label1));
3940 emit_insn (gen_fix_truncdfsi2 (operands[
0], operands[
1]));
3941 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3942 gen_rtx_LABEL_REF (VOIDmode, label2)));
3945 emit_label (label1);
3946 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[
1], reg1));
3947 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
3948 (BITMASK_HIGH, SImode)));
3950 emit_insn (gen_fix_truncdfsi2 (operands[
0], reg2));
3951 emit_insn (gen_iorsi3 (operands[
0], operands[
0], reg3));
3953 emit_label (label2);
3955 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3956 fields, and can't be used for REG_NOTES anyway). */
3957 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3963 (define_expand "fixuns_truncdfdi2"
3964 [(set (match_operand:DI
0 "register_operand" "")
3965 (unsigned_fix:DI (match_operand:DF
1 "register_operand" "")))]
3966 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3968 rtx reg1 = gen_reg_rtx (DFmode);
3969 rtx reg2 = gen_reg_rtx (DFmode);
3970 rtx reg3 = gen_reg_rtx (DImode);
3971 rtx label1 = gen_label_rtx ();
3972 rtx label2 = gen_label_rtx ();
3973 REAL_VALUE_TYPE offset;
3975 real_2expN (&offset,
63);
3977 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3978 do_pending_stack_adjust ();
3980 emit_insn (gen_cmpdf (operands[
1], reg1));
3981 emit_jump_insn (gen_bge (label1));
3983 emit_insn (gen_fix_truncdfdi2 (operands[
0], operands[
1]));
3984 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3985 gen_rtx_LABEL_REF (VOIDmode, label2)));
3988 emit_label (label1);
3989 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[
1], reg1));
3990 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3991 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (
32)));
3993 emit_insn (gen_fix_truncdfdi2 (operands[
0], reg2));
3994 emit_insn (gen_iordi3 (operands[
0], operands[
0], reg3));
3996 emit_label (label2);
3998 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3999 fields, and can't be used for REG_NOTES anyway). */
4000 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4005 (define_expand "fixuns_truncsfsi2"
4006 [(set (match_operand:SI
0 "register_operand" "")
4007 (unsigned_fix:SI (match_operand:SF
1 "register_operand" "")))]
4010 rtx reg1 = gen_reg_rtx (SFmode);
4011 rtx reg2 = gen_reg_rtx (SFmode);
4012 rtx reg3 = gen_reg_rtx (SImode);
4013 rtx label1 = gen_label_rtx ();
4014 rtx label2 = gen_label_rtx ();
4015 REAL_VALUE_TYPE offset;
4017 real_2expN (&offset,
31);
4019 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
4020 do_pending_stack_adjust ();
4022 emit_insn (gen_cmpsf (operands[
1], reg1));
4023 emit_jump_insn (gen_bge (label1));
4025 emit_insn (gen_fix_truncsfsi2 (operands[
0], operands[
1]));
4026 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4027 gen_rtx_LABEL_REF (VOIDmode, label2)));
4030 emit_label (label1);
4031 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[
1], reg1));
4032 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
4033 (BITMASK_HIGH, SImode)));
4035 emit_insn (gen_fix_truncsfsi2 (operands[
0], reg2));
4036 emit_insn (gen_iorsi3 (operands[
0], operands[
0], reg3));
4038 emit_label (label2);
4040 /* Allow REG_NOTES to be set on last insn (labels don't have enough
4041 fields, and can't be used for REG_NOTES anyway). */
4042 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4047 (define_expand "fixuns_truncsfdi2"
4048 [(set (match_operand:DI
0 "register_operand" "")
4049 (unsigned_fix:DI (match_operand:SF
1 "register_operand" "")))]
4050 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4052 rtx reg1 = gen_reg_rtx (SFmode);
4053 rtx reg2 = gen_reg_rtx (SFmode);
4054 rtx reg3 = gen_reg_rtx (DImode);
4055 rtx label1 = gen_label_rtx ();
4056 rtx label2 = gen_label_rtx ();
4057 REAL_VALUE_TYPE offset;
4059 real_2expN (&offset,
63);
4061 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
4062 do_pending_stack_adjust ();
4064 emit_insn (gen_cmpsf (operands[
1], reg1));
4065 emit_jump_insn (gen_bge (label1));
4067 emit_insn (gen_fix_truncsfdi2 (operands[
0], operands[
1]));
4068 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4069 gen_rtx_LABEL_REF (VOIDmode, label2)));
4072 emit_label (label1);
4073 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[
1], reg1));
4074 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
4075 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (
32)));
4077 emit_insn (gen_fix_truncsfdi2 (operands[
0], reg2));
4078 emit_insn (gen_iordi3 (operands[
0], operands[
0], reg3));
4080 emit_label (label2);
4082 /* Allow REG_NOTES to be set on last insn (labels don't have enough
4083 fields, and can't be used for REG_NOTES anyway). */
4084 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4089 ;; ....................
4093 ;; ....................
4095 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
4097 (define_expand "extv"
4098 [(set (match_operand
0 "register_operand" "")
4099 (sign_extract (match_operand:QI
1 "memory_operand" "")
4100 (match_operand
2 "immediate_operand" "")
4101 (match_operand
3 "immediate_operand" "")))]
4104 if (mips_expand_unaligned_load (operands[
0], operands[
1],
4105 INTVAL (operands[
2]),
4106 INTVAL (operands[
3])))
4112 (define_expand "extzv"
4113 [(set (match_operand
0 "register_operand" "")
4114 (zero_extract (match_operand:QI
1 "memory_operand" "")
4115 (match_operand
2 "immediate_operand" "")
4116 (match_operand
3 "immediate_operand" "")))]
4119 if (mips_expand_unaligned_load (operands[
0], operands[
1],
4120 INTVAL (operands[
2]),
4121 INTVAL (operands[
3])))
4127 (define_expand "insv"
4128 [(set (zero_extract (match_operand:QI
0 "memory_operand" "")
4129 (match_operand
1 "immediate_operand" "")
4130 (match_operand
2 "immediate_operand" ""))
4131 (match_operand
3 "reg_or_0_operand" ""))]
4134 if (mips_expand_unaligned_store (operands[
0], operands[
3],
4135 INTVAL (operands[
1]),
4136 INTVAL (operands[
2])))
4142 ;; Unaligned word moves generated by the bit field patterns.
4144 ;; As far as the rtl is concerned, both the left-part and right-part
4145 ;; instructions can access the whole field. However, the real operand
4146 ;; refers to just the first or the last byte (depending on endianness).
4147 ;; We therefore use two memory operands to each instruction, one to
4148 ;; describe the rtl effect and one to use in the assembly output.
4150 ;; Operands
0 and
1 are the rtl-level target and source respectively.
4151 ;; This allows us to use the standard length calculations for the "load"
4152 ;; and "store" type attributes.
4154 (define_insn "mov_lwl"
4155 [(set (match_operand:SI
0 "register_operand" "=d")
4156 (unspec:SI [(match_operand:BLK
1 "memory_operand" "m")
4157 (match_operand:QI
2 "memory_operand" "m")]
4161 [(set_attr "type" "load")
4162 (set_attr "mode" "SI")
4163 (set_attr "hazard" "none")])
4165 (define_insn "mov_lwr"
4166 [(set (match_operand:SI
0 "register_operand" "=d")
4167 (unspec:SI [(match_operand:BLK
1 "memory_operand" "m")
4168 (match_operand:QI
2 "memory_operand" "m")
4169 (match_operand:SI
3 "register_operand" "
0")]
4173 [(set_attr "type" "load")
4174 (set_attr "mode" "SI")])
4177 (define_insn "mov_swl"
4178 [(set (match_operand:BLK
0 "memory_operand" "=m")
4179 (unspec:BLK [(match_operand:SI
1 "reg_or_0_operand" "dJ")
4180 (match_operand:QI
2 "memory_operand" "m")]
4184 [(set_attr "type" "store")
4185 (set_attr "mode" "SI")])
4187 (define_insn "mov_swr"
4188 [(set (match_operand:BLK
0 "memory_operand" "+m")
4189 (unspec:BLK [(match_operand:SI
1 "reg_or_0_operand" "dJ")
4190 (match_operand:QI
2 "memory_operand" "m")
4195 [(set_attr "type" "store")
4196 (set_attr "mode" "SI")])
4199 (define_insn "mov_ldl"
4200 [(set (match_operand:DI
0 "register_operand" "=d")
4201 (unspec:DI [(match_operand:BLK
1 "memory_operand" "m")
4202 (match_operand:QI
2 "memory_operand" "m")]
4204 "TARGET_64BIT && !TARGET_MIPS16"
4206 [(set_attr "type" "load")
4207 (set_attr "mode" "DI")])
4209 (define_insn "mov_ldr"
4210 [(set (match_operand:DI
0 "register_operand" "=d")
4211 (unspec:DI [(match_operand:BLK
1 "memory_operand" "m")
4212 (match_operand:QI
2 "memory_operand" "m")
4213 (match_operand:DI
3 "register_operand" "
0")]
4215 "TARGET_64BIT && !TARGET_MIPS16"
4217 [(set_attr "type" "load")
4218 (set_attr "mode" "DI")])
4221 (define_insn "mov_sdl"
4222 [(set (match_operand:BLK
0 "memory_operand" "=m")
4223 (unspec:BLK [(match_operand:DI
1 "reg_or_0_operand" "dJ")
4224 (match_operand:QI
2 "memory_operand" "m")]
4226 "TARGET_64BIT && !TARGET_MIPS16"
4228 [(set_attr "type" "store")
4229 (set_attr "mode" "DI")])
4231 (define_insn "mov_sdr"
4232 [(set (match_operand:BLK
0 "memory_operand" "+m")
4233 (unspec:BLK [(match_operand:DI
1 "reg_or_0_operand" "dJ")
4234 (match_operand:QI
2 "memory_operand" "m")
4237 "TARGET_64BIT && !TARGET_MIPS16"
4239 [(set_attr "type" "store")
4240 (set_attr "mode" "DI")])
4242 ;; An instruction to calculate the high part of a
64-bit SYMBOL_GENERAL.
4243 ;; The required value is:
4245 ;; (%highest(op1) <<
48) + (%higher(op1) <<
32) + (%hi(op1) <<
16)
4247 ;; which translates to:
4249 ;; lui op0,%highest(op1)
4250 ;; daddiu op0,op0,%higher(op1)
4252 ;; daddiu op0,op0,%hi(op1)
4254 (define_insn_and_split "*lea_high64"
4255 [(set (match_operand:DI
0 "register_operand" "=d")
4256 (high:DI (match_operand:DI
1 "general_symbolic_operand" "")))]
4257 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
4259 "&& reload_completed"
4260 [(set (match_dup
0) (high:DI (match_dup
2)))
4261 (set (match_dup
0) (lo_sum:DI (match_dup
0) (match_dup
2)))
4262 (set (match_dup
0) (ashift:DI (match_dup
0) (const_int
16)))
4263 (set (match_dup
0) (lo_sum:DI (match_dup
0) (match_dup
3)))
4264 (set (match_dup
0) (ashift:DI (match_dup
0) (const_int
16)))]
4266 operands[
2] = mips_unspec_address (operands[
1], SYMBOL_64_HIGH);
4267 operands[
3] = mips_unspec_address (operands[
1], SYMBOL_64_MID);
4269 [(set_attr "length" "
20")])
4271 ;; On most targets, the expansion of (lo_sum (high X) X) for a
64-bit
4272 ;; SYMBOL_GENERAL X will take
6 cycles. This next pattern allows combine
4273 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
4274 ;; used once. We can then use the sequence:
4276 ;; lui op0,%highest(op1)
4278 ;; daddiu op0,op0,%higher(op1)
4279 ;; daddiu op2,op2,%lo(op1)
4281 ;; daddu op0,op0,op2
4283 ;; which takes
4 cycles on most superscalar targets.
4284 (define_insn_and_split "*lea64"
4285 [(set (match_operand:DI
0 "register_operand" "=d")
4286 (match_operand:DI
1 "general_symbolic_operand" ""))
4287 (clobber (match_scratch:DI
2 "=&d"))]
4288 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
4290 "&& reload_completed"
4291 [(set (match_dup
0) (high:DI (match_dup
3)))
4292 (set (match_dup
2) (high:DI (match_dup
4)))
4293 (set (match_dup
0) (lo_sum:DI (match_dup
0) (match_dup
3)))
4294 (set (match_dup
2) (lo_sum:DI (match_dup
2) (match_dup
4)))
4295 (set (match_dup
0) (ashift:DI (match_dup
0) (const_int
32)))
4296 (set (match_dup
0) (plus:DI (match_dup
0) (match_dup
2)))]
4298 operands[
3] = mips_unspec_address (operands[
1], SYMBOL_64_HIGH);
4299 operands[
4] = mips_unspec_address (operands[
1], SYMBOL_64_LOW);
4301 [(set_attr "length" "
24")])
4303 ;; Insns to fetch a global symbol from a big GOT.
4305 (define_insn_and_split "*xgot_hisi"
4306 [(set (match_operand:SI
0 "register_operand" "=d")
4307 (high:SI (match_operand:SI
1 "global_got_operand" "")))]
4308 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
4310 "&& reload_completed"
4311 [(set (match_dup
0) (high:SI (match_dup
2)))
4312 (set (match_dup
0) (plus:SI (match_dup
0) (match_dup
3)))]
4314 operands[
2] = mips_unspec_address (operands[
1], SYMBOL_GOTOFF_GLOBAL);
4315 operands[
3] = pic_offset_table_rtx;
4317 [(set_attr "got" "xgot_high")])
4319 (define_insn_and_split "*xgot_losi"
4320 [(set (match_operand:SI
0 "register_operand" "=d")
4321 (lo_sum:SI (match_operand:SI
1 "register_operand" "d")
4322 (match_operand:SI
2 "global_got_operand" "")))]
4323 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
4325 "&& reload_completed"
4327 (unspec:SI [(match_dup
1) (match_dup
3)] UNSPEC_LOAD_GOT))]
4328 { operands[
3] = mips_unspec_address (operands[
2], SYMBOL_GOTOFF_GLOBAL); }
4329 [(set_attr "got" "load")])
4331 (define_insn_and_split "*xgot_hidi"
4332 [(set (match_operand:DI
0 "register_operand" "=d")
4333 (high:DI (match_operand:DI
1 "global_got_operand" "")))]
4334 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
4336 "&& reload_completed"
4337 [(set (match_dup
0) (high:DI (match_dup
2)))
4338 (set (match_dup
0) (plus:DI (match_dup
0) (match_dup
3)))]
4340 operands[
2] = mips_unspec_address (operands[
1], SYMBOL_GOTOFF_GLOBAL);
4341 operands[
3] = pic_offset_table_rtx;
4343 [(set_attr "got" "xgot_high")])
4345 (define_insn_and_split "*xgot_lodi"
4346 [(set (match_operand:DI
0 "register_operand" "=d")
4347 (lo_sum:DI (match_operand:DI
1 "register_operand" "d")
4348 (match_operand:DI
2 "global_got_operand" "")))]
4349 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
4351 "&& reload_completed"
4353 (unspec:DI [(match_dup
1) (match_dup
3)] UNSPEC_LOAD_GOT))]
4354 { operands[
3] = mips_unspec_address (operands[
2], SYMBOL_GOTOFF_GLOBAL); }
4355 [(set_attr "got" "load")])
4357 ;; Insns to fetch a global symbol from a normal GOT.
4359 (define_insn_and_split "*got_dispsi"
4360 [(set (match_operand:SI
0 "register_operand" "=d")
4361 (match_operand:SI
1 "global_got_operand" ""))]
4362 "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
4364 "&& reload_completed"
4366 (unspec:SI [(match_dup
2) (match_dup
3)] UNSPEC_LOAD_GOT))]
4368 operands[
2] = pic_offset_table_rtx;
4369 operands[
3] = mips_unspec_address (operands[
1], SYMBOL_GOTOFF_GLOBAL);
4371 [(set_attr "got" "load")])
4373 (define_insn_and_split "*got_dispdi"
4374 [(set (match_operand:DI
0 "register_operand" "=d")
4375 (match_operand:DI
1 "global_got_operand" ""))]
4376 "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
4378 "&& reload_completed"
4380 (unspec:DI [(match_dup
2) (match_dup
3)] UNSPEC_LOAD_GOT))]
4382 operands[
2] = pic_offset_table_rtx;
4383 operands[
3] = mips_unspec_address (operands[
1], SYMBOL_GOTOFF_GLOBAL);
4385 [(set_attr "got" "load")])
4387 ;; Insns for loading the high part of a local symbol.
4389 (define_insn_and_split "*got_pagesi"
4390 [(set (match_operand:SI
0 "register_operand" "=d")
4391 (high:SI (match_operand:SI
1 "local_got_operand" "")))]
4392 "TARGET_EXPLICIT_RELOCS"
4394 "&& reload_completed"
4396 (unspec:SI [(match_dup
2) (match_dup
3)] UNSPEC_LOAD_GOT))]
4398 operands[
2] = pic_offset_table_rtx;
4399 operands[
3] = mips_unspec_address (operands[
1], SYMBOL_GOTOFF_PAGE);
4401 [(set_attr "got" "load")])
4403 (define_insn_and_split "*got_pagedi"
4404 [(set (match_operand:DI
0 "register_operand" "=d")
4405 (high:DI (match_operand:DI
1 "local_got_operand" "")))]
4406 "TARGET_EXPLICIT_RELOCS"
4408 "&& reload_completed"
4410 (unspec:DI [(match_dup
2) (match_dup
3)] UNSPEC_LOAD_GOT))]
4412 operands[
2] = pic_offset_table_rtx;
4413 operands[
3] = mips_unspec_address (operands[
1], SYMBOL_GOTOFF_PAGE);
4415 [(set_attr "got" "load")])
4417 ;; Lower-level instructions for loading an address from the GOT.
4418 ;; We could use MEMs, but an unspec gives more optimization
4421 (define_insn "*load_gotsi"
4422 [(set (match_operand:SI
0 "register_operand" "=d")
4423 (unspec:SI [(match_operand:SI
1 "register_operand" "d")
4424 (match_operand:SI
2 "immediate_operand" "")]
4428 [(set_attr "type" "load")
4429 (set_attr "length" "
4")])
4431 (define_insn "*load_gotdi"
4432 [(set (match_operand:DI
0 "register_operand" "=d")
4433 (unspec:DI [(match_operand:DI
1 "register_operand" "d")
4434 (match_operand:DI
2 "immediate_operand" "")]
4438 [(set_attr "type" "load")
4439 (set_attr "length" "
4")])
4441 ;; Instructions for adding the low
16 bits of an address to a register.
4442 ;; Operand
2 is the address: print_operand works out which relocation
4443 ;; should be applied.
4445 (define_insn "*lowsi"
4446 [(set (match_operand:SI
0 "register_operand" "=d")
4447 (lo_sum:SI (match_operand:SI
1 "register_operand" "d")
4448 (match_operand:SI
2 "immediate_operand" "")))]
4451 [(set_attr "type" "arith")
4452 (set_attr "mode" "SI")])
4454 (define_insn "*lowdi"
4455 [(set (match_operand:DI
0 "register_operand" "=d")
4456 (lo_sum:DI (match_operand:DI
1 "register_operand" "d")
4457 (match_operand:DI
2 "immediate_operand" "")))]
4458 "!TARGET_MIPS16 && TARGET_64BIT"
4460 [(set_attr "type" "arith")
4461 (set_attr "mode" "DI")])
4463 (define_insn "*lowsi_mips16"
4464 [(set (match_operand:SI
0 "register_operand" "=d")
4465 (lo_sum:SI (match_operand:SI
1 "register_operand" "
0")
4466 (match_operand:SI
2 "immediate_operand" "")))]
4469 [(set_attr "type" "arith")
4470 (set_attr "mode" "SI")
4471 (set_attr "length" "
8")])
4473 (define_insn "*lowdi_mips16"
4474 [(set (match_operand:DI
0 "register_operand" "=d")
4475 (lo_sum:DI (match_operand:DI
1 "register_operand" "
0")
4476 (match_operand:DI
2 "immediate_operand" "")))]
4477 "TARGET_MIPS16 && TARGET_64BIT"
4479 [(set_attr "type" "arith")
4480 (set_attr "mode" "DI")
4481 (set_attr "length" "
8")])
4483 ;;
64-bit integer moves
4485 ;; Unlike most other insns, the move insns can't be split with
4486 ;; different predicates, because register spilling and other parts of
4487 ;; the compiler, have memoized the insn number already.
4489 (define_expand "movdi"
4490 [(set (match_operand:DI
0 "" "")
4491 (match_operand:DI
1 "" ""))]
4494 if (mips_legitimize_move (DImode, operands[
0], operands[
1]))
4497 /* If we are generating embedded PIC code, and we are referring to a
4498 symbol in the .text section, we must use an offset from the start
4500 if (TARGET_EMBEDDED_PIC
4501 && (GET_CODE (operands[
1]) == LABEL_REF
4502 || (GET_CODE (operands[
1]) == SYMBOL_REF
4503 && ! SYMBOL_REF_FLAG (operands[
1]))))
4507 temp = embedded_pic_offset (operands[
1]);
4508 temp = gen_rtx_PLUS (Pmode, embedded_pic_fnaddr_reg (),
4509 force_reg (DImode, temp));
4510 emit_move_insn (operands[
0], force_reg (DImode, temp));
4515 ;; For mips16, we need a special case to handle storing $
31 into
4516 ;; memory, since we don't have a constraint to match $
31. This
4517 ;; instruction can be generated by save_restore_insns.
4520 [(set (match_operand:DI
0 "stack_operand" "=m")
4522 "TARGET_MIPS16 && TARGET_64BIT"
4524 [(set_attr "type" "store")
4525 (set_attr "mode" "DI")])
4527 (define_insn "*movdi_32bit"
4528 [(set (match_operand:DI
0 "nonimmediate_operand" "=d,d,d,m,*x,*d,*x,*B*C*D,*B*C*D,*d,*m")
4529 (match_operand:DI
1 "move_operand" "d,i,m,d,J,*x,*d,*d,*m,*B*C*D,*B*C*D"))]
4530 "!TARGET_64BIT && !TARGET_MIPS16
4531 && (register_operand (operands[
0], DImode)
4532 || reg_or_0_operand (operands[
1], DImode))"
4533 { return mips_output_move (operands[
0], operands[
1]); }
4534 [(set_attr "type" "move,arith,load,store,hilo,hilo,hilo,xfer,load,xfer,store")
4535 (set_attr "mode" "DI")
4536 (set_attr "length" "
8,
16,*,*,
8,
8,
8,
8,*,
8,*")])
4538 (define_insn "*movdi_32bit_mips16"
4539 [(set (match_operand:DI
0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4540 (match_operand:DI
1 "move_operand" "d,d,y,K,N,m,d,*x"))]
4541 "!TARGET_64BIT && TARGET_MIPS16
4542 && (register_operand (operands[
0], DImode)
4543 || register_operand (operands[
1], DImode))"
4544 { return mips_output_move (operands[
0], operands[
1]); }
4545 [(set_attr "type" "move,move,move,arith,arith,load,store,hilo")
4546 (set_attr "mode" "DI")
4547 (set_attr "length" "
8,
8,
8,
8,
12,*,*,
8")])
4549 (define_insn "*movdi_64bit"
4550 [(set (match_operand:DI
0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*x,*d,*x,*B*C*D,*B*C*D,*d,*m")
4551 (match_operand:DI
1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*J,*x,*d,*d,*m,*B*C*D,*B*C*D"))]
4552 "TARGET_64BIT && !TARGET_MIPS16
4553 && (register_operand (operands[
0], DImode)
4554 || reg_or_0_operand (operands[
1], DImode))"
4555 { return mips_output_move (operands[
0], operands[
1]); }
4556 [(set_attr "type" "move,const,const,load,store,move,xfer,fpload,xfer,fpstore,hilo,hilo,hilo,xfer,load,xfer,store")
4557 (set_attr "mode" "DI")
4558 (set_attr "length" "
4,*,*,*,*,
4,
4,*,
4,*,
4,
4,
4,
8,*,
8,*")])
4560 (define_insn "*movdi_64bit_mips16"
4561 [(set (match_operand:DI
0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m,*d")
4562 (match_operand:DI
1 "move_operand" "d,d,y,K,N,U,m,d,*x"))]
4563 "TARGET_64BIT && TARGET_MIPS16
4564 && (register_operand (operands[
0], DImode)
4565 || register_operand (operands[
1], DImode))"
4566 { return mips_output_move (operands[
0], operands[
1]); }
4567 [(set_attr "type" "move,move,move,arith,arith,const,load,store,hilo")
4568 (set_attr "mode" "DI")
4569 (set_attr_alternative "length"
4573 (if_then_else (match_operand:VOID
1 "m16_uimm8_1" "")
4576 (if_then_else (match_operand:VOID
1 "m16_nuimm8_1" "")
4585 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
4586 ;; when the original load is a
4 byte instruction but the add and the
4587 ;; load are
2 2 byte instructions.
4590 [(set (match_operand:DI
0 "register_operand" "")
4591 (mem:DI (plus:DI (match_dup
0)
4592 (match_operand:DI
1 "const_int_operand" ""))))]
4593 "TARGET_64BIT && TARGET_MIPS16 && reload_completed
4594 && !TARGET_DEBUG_D_MODE
4595 && GET_CODE (operands[
0]) == REG
4596 && M16_REG_P (REGNO (operands[
0]))
4597 && GET_CODE (operands[
1]) == CONST_INT
4598 && ((INTVAL (operands[
1]) <
0
4599 && INTVAL (operands[
1]) >= -
0x10)
4600 || (INTVAL (operands[
1]) >=
32 *
8
4601 && INTVAL (operands[
1]) <=
31 *
8 +
0x8)
4602 || (INTVAL (operands[
1]) >=
0
4603 && INTVAL (operands[
1]) <
32 *
8
4604 && (INTVAL (operands[
1]) &
7) !=
0))"
4605 [(set (match_dup
0) (plus:DI (match_dup
0) (match_dup
1)))
4606 (set (match_dup
0) (mem:DI (plus:DI (match_dup
0) (match_dup
2))))]
4608 HOST_WIDE_INT val = INTVAL (operands[
1]);
4611 operands[
2] = const0_rtx;
4612 else if (val >=
32 *
8)
4616 operands[
1] = GEN_INT (
0x8 + off);
4617 operands[
2] = GEN_INT (val - off -
0x8);
4623 operands[
1] = GEN_INT (off);
4624 operands[
2] = GEN_INT (val - off);
4628 ;;
32-bit Integer moves
4630 ;; Unlike most other insns, the move insns can't be split with
4631 ;; different predicates, because register spilling and other parts of
4632 ;; the compiler, have memoized the insn number already.
4634 (define_expand "movsi"
4635 [(set (match_operand:SI
0 "" "")
4636 (match_operand:SI
1 "" ""))]
4639 if (mips_legitimize_move (SImode, operands[
0], operands[
1]))
4642 /* If we are generating embedded PIC code, and we are referring to a
4643 symbol in the .text section, we must use an offset from the start
4645 if (TARGET_EMBEDDED_PIC
4646 && (GET_CODE (operands[
1]) == LABEL_REF
4647 || (GET_CODE (operands[
1]) == SYMBOL_REF
4648 && ! SYMBOL_REF_FLAG (operands[
1]))))
4652 temp = embedded_pic_offset (operands[
1]);
4653 temp = gen_rtx_PLUS (Pmode, embedded_pic_fnaddr_reg (),
4654 force_reg (SImode, temp));
4655 emit_move_insn (operands[
0], force_reg (SImode, temp));
4660 ;; We can only store $ra directly into a small sp offset.
4663 [(set (match_operand:SI
0 "stack_operand" "=m")
4667 [(set_attr "type" "store")
4668 (set_attr "mode" "SI")])
4670 ;; The difference between these two is whether or not ints are allowed
4671 ;; in FP registers (off by default, use -mdebugh to enable).
4673 (define_insn "*movsi_internal"
4674 [(set (match_operand:SI
0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*d,*z,*x,*d,*x,*B*C*D,*B*C*D,*d,*m")
4675 (match_operand:SI
1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*z,*d,J,*x,*d,*d,*m,*B*C*D,*B*C*D"))]
4677 && (register_operand (operands[
0], SImode)
4678 || reg_or_0_operand (operands[
1], SImode))"
4679 { return mips_output_move (operands[
0], operands[
1]); }
4680 [(set_attr "type" "move,const,const,load,store,move,xfer,fpload,xfer,fpstore,xfer,xfer,hilo,hilo,hilo,xfer,load,xfer,store")
4681 (set_attr "mode" "SI")
4682 (set_attr "length" "
4,*,*,*,*,
4,
4,*,
4,*,
4,
4,
4,
4,
4,
4,*,
4,*")])
4684 (define_insn "*movsi_mips16"
4685 [(set (match_operand:SI
0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m,*d")
4686 (match_operand:SI
1 "move_operand" "d,d,y,K,N,U,m,d,*x"))]
4688 && (register_operand (operands[
0], SImode)
4689 || register_operand (operands[
1], SImode))"
4690 { return mips_output_move (operands[
0], operands[
1]); }
4691 [(set_attr "type" "move,move,move,arith,arith,const,load,store,hilo")
4692 (set_attr "mode" "SI")
4693 (set_attr_alternative "length"
4697 (if_then_else (match_operand:VOID
1 "m16_uimm8_1" "")
4700 (if_then_else (match_operand:VOID
1 "m16_nuimm8_1" "")
4708 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
4709 ;; when the original load is a
4 byte instruction but the add and the
4710 ;; load are
2 2 byte instructions.
4713 [(set (match_operand:SI
0 "register_operand" "")
4714 (mem:SI (plus:SI (match_dup
0)
4715 (match_operand:SI
1 "const_int_operand" ""))))]
4716 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4717 && GET_CODE (operands[
0]) == REG
4718 && M16_REG_P (REGNO (operands[
0]))
4719 && GET_CODE (operands[
1]) == CONST_INT
4720 && ((INTVAL (operands[
1]) <
0
4721 && INTVAL (operands[
1]) >= -
0x80)
4722 || (INTVAL (operands[
1]) >=
32 *
4
4723 && INTVAL (operands[
1]) <=
31 *
4 +
0x7c)
4724 || (INTVAL (operands[
1]) >=
0
4725 && INTVAL (operands[
1]) <
32 *
4
4726 && (INTVAL (operands[
1]) &
3) !=
0))"
4727 [(set (match_dup
0) (plus:SI (match_dup
0) (match_dup
1)))
4728 (set (match_dup
0) (mem:SI (plus:SI (match_dup
0) (match_dup
2))))]
4730 HOST_WIDE_INT val = INTVAL (operands[
1]);
4733 operands[
2] = const0_rtx;
4734 else if (val >=
32 *
4)
4738 operands[
1] = GEN_INT (
0x7c + off);
4739 operands[
2] = GEN_INT (val - off -
0x7c);
4745 operands[
1] = GEN_INT (off);
4746 operands[
2] = GEN_INT (val - off);
4750 ;; On the mips16, we can split a load of certain constants into a load
4751 ;; and an add. This turns a
4 byte instruction into
2 2 byte
4755 [(set (match_operand:SI
0 "register_operand" "")
4756 (match_operand:SI
1 "const_int_operand" ""))]
4757 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4758 && GET_CODE (operands[
0]) == REG
4759 && M16_REG_P (REGNO (operands[
0]))
4760 && GET_CODE (operands[
1]) == CONST_INT
4761 && INTVAL (operands[
1]) >=
0x100
4762 && INTVAL (operands[
1]) <=
0xff +
0x7f"
4763 [(set (match_dup
0) (match_dup
1))
4764 (set (match_dup
0) (plus:SI (match_dup
0) (match_dup
2)))]
4766 int val = INTVAL (operands[
1]);
4768 operands[
1] = GEN_INT (
0xff);
4769 operands[
2] = GEN_INT (val -
0xff);
4772 ;; On the mips16, we can split a load of a negative constant into a
4773 ;; load and a neg. That's what mips_output_move will generate anyhow.
4776 [(set (match_operand:SI
0 "register_operand" "")
4777 (match_operand:SI
1 "const_int_operand" ""))]
4778 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4779 && GET_CODE (operands[
0]) == REG
4780 && M16_REG_P (REGNO (operands[
0]))
4781 && GET_CODE (operands[
1]) == CONST_INT
4782 && INTVAL (operands[
1]) <
0
4783 && INTVAL (operands[
1]) > -
0x8000"
4784 [(set (match_dup
0) (match_dup
1))
4785 (set (match_dup
0) (neg:SI (match_dup
0)))]
4786 { operands[
1] = GEN_INT (- INTVAL (operands[
1])); })
4788 ;; This insn handles moving CCmode values. It's really just a
4789 ;; slightly simplified copy of movsi_internal2, with additional cases
4790 ;; to move a condition register to a general register and to move
4791 ;; between the general registers and the floating point registers.
4793 (define_insn "movcc"
4794 [(set (match_operand:CC
0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m")
4795 (match_operand:CC
1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))]
4796 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4797 { return mips_output_move (operands[
0], operands[
1]); }
4798 [(set_attr "type" "move,move,load,store,xfer,xfer,move,fpload,fpstore")
4799 (set_attr "mode" "SI")
4800 (set_attr "length" "
8,
4,*,*,
4,
4,
4,*,*")])
4802 ;; Reload condition code registers. reload_incc and reload_outcc
4803 ;; both handle moves from arbitrary operands into condition code
4804 ;; registers. reload_incc handles the more common case in which
4805 ;; a source operand is constrained to be in a condition-code
4806 ;; register, but has not been allocated to one.
4808 ;; Sometimes, such as in movcc, we have a CCmode destination whose
4809 ;; constraints do not include 'z'. reload_outcc handles the case
4810 ;; when such an operand is allocated to a condition-code register.
4812 ;; Note that reloads from a condition code register to some
4813 ;; other location can be done using ordinary moves. Moving
4814 ;; into a GPR takes a single movcc, moving elsewhere takes
4815 ;; two. We can leave these cases to the generic reload code.
4816 (define_expand "reload_incc"
4817 [(set (match_operand:CC
0 "fcc_register_operand" "=z")
4818 (match_operand:CC
1 "general_operand" ""))
4819 (clobber (match_operand:TF
2 "register_operand" "=&f"))]
4820 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4822 mips_emit_fcc_reload (operands[
0], operands[
1], operands[
2]);
4826 (define_expand "reload_outcc"
4827 [(set (match_operand:CC
0 "fcc_register_operand" "=z")
4828 (match_operand:CC
1 "register_operand" ""))
4829 (clobber (match_operand:TF
2 "register_operand" "=&f"))]
4830 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4832 mips_emit_fcc_reload (operands[
0], operands[
1], operands[
2]);
4836 ;; MIPS4 supports loading and storing a floating point register from
4837 ;; the sum of two general registers. We use two versions for each of
4838 ;; these four instructions: one where the two general registers are
4839 ;; SImode, and one where they are DImode. This is because general
4840 ;; registers will be in SImode when they hold
32 bit values, but,
4841 ;; since the
32 bit values are always sign extended, the [ls][wd]xc1
4842 ;; instructions will still work correctly.
4844 ;; ??? Perhaps it would be better to support these instructions by
4845 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends. However, since
4846 ;; these instructions can only be used to load and store floating
4847 ;; point registers, that would probably cause trouble in reload.
4850 [(set (match_operand:SF
0 "register_operand" "=f")
4851 (mem:SF (plus:SI (match_operand:SI
1 "register_operand" "d")
4852 (match_operand:SI
2 "register_operand" "d"))))]
4853 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4855 [(set_attr "type" "fpidxload")
4856 (set_attr "mode" "SF")
4857 (set_attr "length" "
4")])
4860 [(set (match_operand:SF
0 "register_operand" "=f")
4861 (mem:SF (plus:DI (match_operand:DI
1 "register_operand" "d")
4862 (match_operand:DI
2 "register_operand" "d"))))]
4863 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4865 [(set_attr "type" "fpidxload")
4866 (set_attr "mode" "SF")
4867 (set_attr "length" "
4")])
4870 [(set (match_operand:DF
0 "register_operand" "=f")
4871 (mem:DF (plus:SI (match_operand:SI
1 "register_operand" "d")
4872 (match_operand:SI
2 "register_operand" "d"))))]
4873 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4875 [(set_attr "type" "fpidxload")
4876 (set_attr "mode" "DF")
4877 (set_attr "length" "
4")])
4880 [(set (match_operand:DF
0 "register_operand" "=f")
4881 (mem:DF (plus:DI (match_operand:DI
1 "register_operand" "d")
4882 (match_operand:DI
2 "register_operand" "d"))))]
4883 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4885 [(set_attr "type" "fpidxload")
4886 (set_attr "mode" "DF")
4887 (set_attr "length" "
4")])
4890 [(set (mem:SF (plus:SI (match_operand:SI
1 "register_operand" "d")
4891 (match_operand:SI
2 "register_operand" "d")))
4892 (match_operand:SF
0 "register_operand" "f"))]
4893 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4895 [(set_attr "type" "fpidxstore")
4896 (set_attr "mode" "SF")
4897 (set_attr "length" "
4")])
4900 [(set (mem:SF (plus:DI (match_operand:DI
1 "register_operand" "d")
4901 (match_operand:DI
2 "register_operand" "d")))
4902 (match_operand:SF
0 "register_operand" "f"))]
4903 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4905 [(set_attr "type" "fpidxstore")
4906 (set_attr "mode" "SF")
4907 (set_attr "length" "
4")])
4910 [(set (mem:DF (plus:SI (match_operand:SI
1 "register_operand" "d")
4911 (match_operand:SI
2 "register_operand" "d")))
4912 (match_operand:DF
0 "register_operand" "f"))]
4913 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4915 [(set_attr "type" "fpidxstore")
4916 (set_attr "mode" "DF")
4917 (set_attr "length" "
4")])
4920 [(set (mem:DF (plus:DI (match_operand:DI
1 "register_operand" "d")
4921 (match_operand:DI
2 "register_operand" "d")))
4922 (match_operand:DF
0 "register_operand" "f"))]
4923 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4925 [(set_attr "type" "fpidxstore")
4926 (set_attr "mode" "DF")
4927 (set_attr "length" "
4")])
4929 ;;
16-bit Integer moves
4931 ;; Unlike most other insns, the move insns can't be split with
4932 ;; different predicates, because register spilling and other parts of
4933 ;; the compiler, have memoized the insn number already.
4934 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4936 (define_expand "movhi"
4937 [(set (match_operand:HI
0 "" "")
4938 (match_operand:HI
1 "" ""))]
4941 if (mips_legitimize_move (HImode, operands[
0], operands[
1]))
4945 (define_insn "*movhi_internal"
4946 [(set (match_operand:HI
0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x,*d")
4947 (match_operand:HI
1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d,*x"))]
4949 && (register_operand (operands[
0], HImode)
4950 || reg_or_0_operand (operands[
1], HImode))"
4961 [(set_attr "type" "move,arith,load,store,xfer,xfer,move,hilo,hilo")
4962 (set_attr "mode" "HI")
4963 (set_attr "length" "
4,
4,*,*,
4,
4,
4,
4,
4")])
4965 (define_insn "*movhi_mips16"
4966 [(set (match_operand:HI
0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4967 (match_operand:HI
1 "move_operand" "d,d,y,K,N,m,d,*x"))]
4969 && (register_operand (operands[
0], HImode)
4970 || register_operand (operands[
1], HImode))"
4980 [(set_attr "type" "move,move,move,arith,arith,load,store,hilo")
4981 (set_attr "mode" "HI")
4982 (set_attr_alternative "length"
4986 (if_then_else (match_operand:VOID
1 "m16_uimm8_1" "")
4989 (if_then_else (match_operand:VOID
1 "m16_nuimm8_1" "")
4997 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
4998 ;; when the original load is a
4 byte instruction but the add and the
4999 ;; load are
2 2 byte instructions.
5002 [(set (match_operand:HI
0 "register_operand" "")
5003 (mem:HI (plus:SI (match_dup
0)
5004 (match_operand:SI
1 "const_int_operand" ""))))]
5005 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5006 && GET_CODE (operands[
0]) == REG
5007 && M16_REG_P (REGNO (operands[
0]))
5008 && GET_CODE (operands[
1]) == CONST_INT
5009 && ((INTVAL (operands[
1]) <
0
5010 && INTVAL (operands[
1]) >= -
0x80)
5011 || (INTVAL (operands[
1]) >=
32 *
2
5012 && INTVAL (operands[
1]) <=
31 *
2 +
0x7e)
5013 || (INTVAL (operands[
1]) >=
0
5014 && INTVAL (operands[
1]) <
32 *
2
5015 && (INTVAL (operands[
1]) &
1) !=
0))"
5016 [(set (match_dup
0) (plus:SI (match_dup
0) (match_dup
1)))
5017 (set (match_dup
0) (mem:HI (plus:SI (match_dup
0) (match_dup
2))))]
5019 HOST_WIDE_INT val = INTVAL (operands[
1]);
5022 operands[
2] = const0_rtx;
5023 else if (val >=
32 *
2)
5027 operands[
1] = GEN_INT (
0x7e + off);
5028 operands[
2] = GEN_INT (val - off -
0x7e);
5034 operands[
1] = GEN_INT (off);
5035 operands[
2] = GEN_INT (val - off);
5039 ;;
8-bit Integer moves
5041 ;; Unlike most other insns, the move insns can't be split with
5042 ;; different predicates, because register spilling and other parts of
5043 ;; the compiler, have memoized the insn number already.
5044 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
5046 (define_expand "movqi"
5047 [(set (match_operand:QI
0 "" "")
5048 (match_operand:QI
1 "" ""))]
5051 if (mips_legitimize_move (QImode, operands[
0], operands[
1]))
5055 (define_insn "*movqi_internal"
5056 [(set (match_operand:QI
0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x,*d")
5057 (match_operand:QI
1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d,*x"))]
5059 && (register_operand (operands[
0], QImode)
5060 || reg_or_0_operand (operands[
1], QImode))"
5071 [(set_attr "type" "move,arith,load,store,xfer,xfer,move,hilo,hilo")
5072 (set_attr "mode" "QI")
5073 (set_attr "length" "
4,
4,*,*,
4,
4,
4,
4,
4")])
5075 (define_insn "*movqi_mips16"
5076 [(set (match_operand:QI
0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
5077 (match_operand:QI
1 "move_operand" "d,d,y,K,N,m,d,*x"))]
5079 && (register_operand (operands[
0], QImode)
5080 || register_operand (operands[
1], QImode))"
5090 [(set_attr "type" "move,move,move,arith,arith,load,store,hilo")
5091 (set_attr "mode" "QI")
5092 (set_attr "length" "
4,
4,
4,
4,
8,*,*,
4")])
5094 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
5095 ;; when the original load is a
4 byte instruction but the add and the
5096 ;; load are
2 2 byte instructions.
5099 [(set (match_operand:QI
0 "register_operand" "")
5100 (mem:QI (plus:SI (match_dup
0)
5101 (match_operand:SI
1 "const_int_operand" ""))))]
5102 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5103 && GET_CODE (operands[
0]) == REG
5104 && M16_REG_P (REGNO (operands[
0]))
5105 && GET_CODE (operands[
1]) == CONST_INT
5106 && ((INTVAL (operands[
1]) <
0
5107 && INTVAL (operands[
1]) >= -
0x80)
5108 || (INTVAL (operands[
1]) >=
32
5109 && INTVAL (operands[
1]) <=
31 +
0x7f))"
5110 [(set (match_dup
0) (plus:SI (match_dup
0) (match_dup
1)))
5111 (set (match_dup
0) (mem:QI (plus:SI (match_dup
0) (match_dup
2))))]
5113 HOST_WIDE_INT val = INTVAL (operands[
1]);
5116 operands[
2] = const0_rtx;
5119 operands[
1] = GEN_INT (
0x7f);
5120 operands[
2] = GEN_INT (val -
0x7f);
5124 ;;
32-bit floating point moves
5126 (define_expand "movsf"
5127 [(set (match_operand:SF
0 "" "")
5128 (match_operand:SF
1 "" ""))]
5131 if (mips_legitimize_move (SFmode, operands[
0], operands[
1]))
5135 (define_insn "*movsf_hardfloat"
5136 [(set (match_operand:SF
0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
5137 (match_operand:SF
1 "move_operand" "f,G,m,fG,*d,*f,*G*d,*m,*d"))]
5139 && (register_operand (operands[
0], SFmode)
5140 || reg_or_0_operand (operands[
1], SFmode))"
5141 { return mips_output_move (operands[
0], operands[
1]); }
5142 [(set_attr "type" "move,xfer,fpload,fpstore,xfer,xfer,move,load,store")
5143 (set_attr "mode" "SF")
5144 (set_attr "length" "
4,
4,*,*,
4,
4,
4,*,*")])
5146 (define_insn "*movsf_softfloat"
5147 [(set (match_operand:SF
0 "nonimmediate_operand" "=d,d,m")
5148 (match_operand:SF
1 "move_operand" "Gd,m,d"))]
5149 "TARGET_SOFT_FLOAT && !TARGET_MIPS16
5150 && (register_operand (operands[
0], SFmode)
5151 || reg_or_0_operand (operands[
1], SFmode))"
5152 { return mips_output_move (operands[
0], operands[
1]); }
5153 [(set_attr "type" "move,load,store")
5154 (set_attr "mode" "SF")
5155 (set_attr "length" "
4,*,*")])
5157 (define_insn "*movsf_mips16"
5158 [(set (match_operand:SF
0 "nonimmediate_operand" "=d,y,d,d,m")
5159 (match_operand:SF
1 "move_operand" "d,d,y,m,d"))]
5161 && (register_operand (operands[
0], SFmode)
5162 || register_operand (operands[
1], SFmode))"
5163 { return mips_output_move (operands[
0], operands[
1]); }
5164 [(set_attr "type" "move,move,move,load,store")
5165 (set_attr "mode" "SF")
5166 (set_attr "length" "
4,
4,
4,*,*")])
5169 ;;
64-bit floating point moves
5171 (define_expand "movdf"
5172 [(set (match_operand:DF
0 "" "")
5173 (match_operand:DF
1 "" ""))]
5176 if (mips_legitimize_move (DFmode, operands[
0], operands[
1]))
5180 (define_insn "*movdf_hardfloat_64bit"
5181 [(set (match_operand:DF
0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
5182 (match_operand:DF
1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
5183 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT
5184 && (register_operand (operands[
0], DFmode)
5185 || reg_or_0_operand (operands[
1], DFmode))"
5186 { return mips_output_move (operands[
0], operands[
1]); }
5187 [(set_attr "type" "move,xfer,fpload,fpstore,xfer,xfer,move,load,store")
5188 (set_attr "mode" "DF")
5189 (set_attr "length" "
4,
4,*,*,
4,
4,
4,*,*")])
5191 (define_insn "*movdf_hardfloat_32bit"
5192 [(set (match_operand:DF
0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
5193 (match_operand:DF
1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
5194 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT
5195 && (register_operand (operands[
0], DFmode)
5196 || reg_or_0_operand (operands[
1], DFmode))"
5197 { return mips_output_move (operands[
0], operands[
1]); }
5198 [(set_attr "type" "move,xfer,fpload,fpstore,xfer,xfer,move,load,store")
5199 (set_attr "mode" "DF")
5200 (set_attr "length" "
4,
8,*,*,
8,
8,
8,*,*")])
5202 (define_insn "*movdf_softfloat"
5203 [(set (match_operand:DF
0 "nonimmediate_operand" "=d,d,m,d,f,f")
5204 (match_operand:DF
1 "move_operand" "dG,m,dG,f,d,f"))]
5205 "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
5206 && (register_operand (operands[
0], DFmode)
5207 || reg_or_0_operand (operands[
1], DFmode))"
5208 { return mips_output_move (operands[
0], operands[
1]); }
5209 [(set_attr "type" "move,load,store,xfer,xfer,move")
5210 (set_attr "mode" "DF")
5211 (set_attr "length" "
8,*,*,
4,
4,
4")])
5213 (define_insn "*movdf_mips16"
5214 [(set (match_operand:DF
0 "nonimmediate_operand" "=d,y,d,d,m")
5215 (match_operand:DF
1 "move_operand" "d,d,y,m,d"))]
5217 && (register_operand (operands[
0], DFmode)
5218 || register_operand (operands[
1], DFmode))"
5219 { return mips_output_move (operands[
0], operands[
1]); }
5220 [(set_attr "type" "move,move,move,load,store")
5221 (set_attr "mode" "DF")
5222 (set_attr "length" "
8,
8,
8,*,*")])
5225 [(set (match_operand:DI
0 "nonimmediate_operand" "")
5226 (match_operand:DI
1 "move_operand" ""))]
5227 "reload_completed && !TARGET_64BIT
5228 && mips_split_64bit_move_p (operands[
0], operands[
1])"
5231 mips_split_64bit_move (operands[
0], operands[
1]);
5236 [(set (match_operand:DF
0 "nonimmediate_operand" "")
5237 (match_operand:DF
1 "move_operand" ""))]
5238 "reload_completed && !TARGET_64BIT
5239 && mips_split_64bit_move_p (operands[
0], operands[
1])"
5242 mips_split_64bit_move (operands[
0], operands[
1]);
5246 ;; Patterns for loading or storing part of a paired floating point
5247 ;; register. We need them because odd-numbered floating-point registers
5248 ;; are not fully independent: see mips_split_64bit_move.
5250 ;; Load the low word of operand
0 with operand
1.
5251 (define_insn "load_df_low"
5252 [(set (match_operand:DF
0 "register_operand" "=f,f")
5253 (unspec:DF [(match_operand:SI
1 "general_operand" "dJ,m")]
5254 UNSPEC_LOAD_DF_LOW))]
5255 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
5257 operands[
0] = mips_subword (operands[
0],
0);
5258 return mips_output_move (operands[
0], operands[
1]);
5260 [(set_attr "type" "xfer,fpload")
5261 (set_attr "mode" "SF")
5262 (set_attr "length" "
4")])
5264 ;; Load the high word of operand
0 from operand
1, preserving the value
5266 (define_insn "load_df_high"
5267 [(set (match_operand:DF
0 "register_operand" "=f,f")
5268 (unspec:DF [(match_operand:SI
1 "general_operand" "dJ,m")
5269 (match_operand:DF
2 "register_operand" "
0,
0")]
5270 UNSPEC_LOAD_DF_HIGH))]
5271 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
5273 operands[
0] = mips_subword (operands[
0],
1);
5274 return mips_output_move (operands[
0], operands[
1]);
5276 [(set_attr "type" "xfer,fpload")
5277 (set_attr "mode" "SF")
5278 (set_attr "length" "
4")])
5280 ;; Store the high word of operand
1 in operand
0. The corresponding
5281 ;; low-word move is done in the normal way.
5282 (define_insn "store_df_high"
5283 [(set (match_operand:SI
0 "nonimmediate_operand" "=d,m")
5284 (unspec:SI [(match_operand:DF
1 "register_operand" "f,f")]
5285 UNSPEC_STORE_DF_HIGH))]
5286 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
5288 operands[
1] = mips_subword (operands[
1],
1);
5289 return mips_output_move (operands[
0], operands[
1]);
5291 [(set_attr "type" "xfer,fpstore")
5292 (set_attr "mode" "SF")
5293 (set_attr "length" "
4")])
5295 ;; Insn to initialize $gp for n32/n64 abicalls. Operand
0 is the offset
5296 ;; of _gp from the start of this function. Operand
1 is the incoming
5297 ;; function address.
5298 (define_insn_and_split "loadgp"
5299 [(unspec_volatile [(match_operand
0 "" "")
5300 (match_operand
1 "register_operand" "")] UNSPEC_LOADGP)]
5301 "TARGET_ABICALLS && TARGET_NEWABI"
5304 [(set (match_dup
2) (match_dup
3))
5305 (set (match_dup
2) (match_dup
4))
5306 (set (match_dup
2) (match_dup
5))]
5308 operands[
2] = pic_offset_table_rtx;
5309 operands[
3] = gen_rtx_HIGH (Pmode, operands[
0]);
5310 operands[
4] = gen_rtx_PLUS (Pmode, operands[
2], operands[
1]);
5311 operands[
5] = gen_rtx_LO_SUM (Pmode, operands[
2], operands[
0]);
5313 [(set_attr "length" "
12")])
5315 ;; The use of gp is hidden when not using explicit relocations.
5316 ;; This blockage instruction prevents the gp load from being
5317 ;; scheduled after an implicit use of gp. It also prevents
5318 ;; the load from being deleted as dead.
5319 (define_insn "loadgp_blockage"
5320 [(unspec_volatile [(reg:DI
28)] UNSPEC_BLOCKAGE)]
5323 [(set_attr "type" "unknown")
5324 (set_attr "mode" "none")
5325 (set_attr "length" "
0")])
5327 ;; Emit a .cprestore directive, which expands to a single store instruction.
5328 ;; Note that we continue to use .cprestore for explicit reloc code so that
5329 ;; jals inside inlines asms will work correctly.
5330 (define_insn "cprestore"
5331 [(unspec_volatile [(match_operand
0 "const_int_operand" "")]
5335 [(set_attr "type" "store")
5336 (set_attr "length" "
4")])
5338 ;; Block moves, see mips.c for more details.
5339 ;; Argument
0 is the destination
5340 ;; Argument
1 is the source
5341 ;; Argument
2 is the length
5342 ;; Argument
3 is the alignment
5344 (define_expand "movstrsi"
5345 [(parallel [(set (match_operand:BLK
0 "general_operand" "")
5346 (match_operand:BLK
1 "general_operand" ""))
5347 (use (match_operand:SI
2 "" ""))
5348 (use (match_operand:SI
3 "const_int_operand" ""))])]
5349 "!TARGET_MIPS16 && !TARGET_MEMCPY"
5351 if (mips_expand_block_move (operands[
0], operands[
1], operands[
2]))
5358 ;; ....................
5362 ;; ....................
5364 ;; Many of these instructions use trivial define_expands, because we
5365 ;; want to use a different set of constraints when TARGET_MIPS16.
5367 (define_expand "ashlsi3"
5368 [(set (match_operand:SI
0 "register_operand" "=d")
5369 (ashift:SI (match_operand:SI
1 "register_operand" "d")
5370 (match_operand:SI
2 "arith_operand" "dI")))]
5373 /* On the mips16, a shift of more than
8 is a four byte instruction,
5374 so, for a shift between
8 and
16, it is just as fast to do two
5375 shifts of
8 or less. If there is a lot of shifting going on, we
5376 may win in CSE. Otherwise combine will put the shifts back
5377 together again. This can be called by function_arg, so we must
5378 be careful not to allocate a new register if we've reached the
5382 && GET_CODE (operands[
2]) == CONST_INT
5383 && INTVAL (operands[
2]) >
8
5384 && INTVAL (operands[
2]) <=
16
5385 && ! reload_in_progress
5386 && ! reload_completed)
5388 rtx temp = gen_reg_rtx (SImode);
5390 emit_insn (gen_ashlsi3_internal2 (temp, operands[
1], GEN_INT (
8)));
5391 emit_insn (gen_ashlsi3_internal2 (operands[
0], temp,
5392 GEN_INT (INTVAL (operands[
2]) -
8)));
5397 (define_insn "ashlsi3_internal1"
5398 [(set (match_operand:SI
0 "register_operand" "=d")
5399 (ashift:SI (match_operand:SI
1 "register_operand" "d")
5400 (match_operand:SI
2 "arith_operand" "dI")))]
5403 if (GET_CODE (operands[
2]) == CONST_INT)
5404 operands[
2] = GEN_INT (INTVAL (operands[
2]) &
0x1f);
5406 return "sll
\t%
0,%
1,%
2";
5408 [(set_attr "type" "arith")
5409 (set_attr "mode" "SI")])
5411 (define_insn "ashlsi3_internal1_extend"
5412 [(set (match_operand:DI
0 "register_operand" "=d")
5413 (sign_extend:DI (ashift:SI (match_operand:SI
1 "register_operand" "d")
5414 (match_operand:SI
2 "arith_operand" "dI"))))]
5415 "TARGET_64BIT && !TARGET_MIPS16"
5417 if (GET_CODE (operands[
2]) == CONST_INT)
5418 operands[
2] = GEN_INT (INTVAL (operands[
2]) &
0x1f);
5420 return "sll
\t%
0,%
1,%
2";
5422 [(set_attr "type" "arith")
5423 (set_attr "mode" "DI")])
5426 (define_insn "ashlsi3_internal2"
5427 [(set (match_operand:SI
0 "register_operand" "=d,d")
5428 (ashift:SI (match_operand:SI
1 "register_operand" "
0,d")
5429 (match_operand:SI
2 "arith_operand" "d,I")))]
5432 if (which_alternative ==
0)
5433 return "sll
\t%
0,%
2";
5435 if (GET_CODE (operands[
2]) == CONST_INT)
5436 operands[
2] = GEN_INT (INTVAL (operands[
2]) &
0x1f);
5438 return "sll
\t%
0,%
1,%
2";
5440 [(set_attr "type" "arith")
5441 (set_attr "mode" "SI")
5442 (set_attr_alternative "length"
5444 (if_then_else (match_operand:VOID
2 "m16_uimm3_b" "")
5448 ;; On the mips16, we can split a
4 byte shift into
2 2 byte shifts.
5451 [(set (match_operand:SI
0 "register_operand" "")
5452 (ashift:SI (match_operand:SI
1 "register_operand" "")
5453 (match_operand:SI
2 "const_int_operand" "")))]
5454 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5455 && GET_CODE (operands[
2]) == CONST_INT
5456 && INTVAL (operands[
2]) >
8
5457 && INTVAL (operands[
2]) <=
16"
5458 [(set (match_dup
0) (ashift:SI (match_dup
1) (const_int
8)))
5459 (set (match_dup
0) (ashift:SI (match_dup
0) (match_dup
2)))]
5460 { operands[
2] = GEN_INT (INTVAL (operands[
2]) -
8); })
5462 (define_expand "ashldi3"
5463 [(parallel [(set (match_operand:DI
0 "register_operand" "")
5464 (ashift:DI (match_operand:DI
1 "register_operand" "")
5465 (match_operand:SI
2 "arith_operand" "")))
5466 (clobber (match_dup
3))])]
5467 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
5471 /* On the mips16, a shift of more than
8 is a four byte
5472 instruction, so, for a shift between
8 and
16, it is just as
5473 fast to do two shifts of
8 or less. If there is a lot of
5474 shifting going on, we may win in CSE. Otherwise combine will
5475 put the shifts back together again. This can be called by
5476 function_arg, so we must be careful not to allocate a new
5477 register if we've reached the reload pass. */
5480 && GET_CODE (operands[
2]) == CONST_INT
5481 && INTVAL (operands[
2]) >
8
5482 && INTVAL (operands[
2]) <=
16
5483 && ! reload_in_progress
5484 && ! reload_completed)
5486 rtx temp = gen_reg_rtx (DImode);
5488 emit_insn (gen_ashldi3_internal4 (temp, operands[
1], GEN_INT (
8)));
5489 emit_insn (gen_ashldi3_internal4 (operands[
0], temp,
5490 GEN_INT (INTVAL (operands[
2]) -
8)));
5494 emit_insn (gen_ashldi3_internal4 (operands[
0], operands[
1],
5499 operands[
3] = gen_reg_rtx (SImode);
5503 (define_insn "ashldi3_internal"
5504 [(set (match_operand:DI
0 "register_operand" "=&d")
5505 (ashift:DI (match_operand:DI
1 "register_operand" "d")
5506 (match_operand:SI
2 "register_operand" "d")))
5507 (clobber (match_operand:SI
3 "register_operand" "=d"))]
5508 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
5525 [(set_attr "type" "darith")
5526 (set_attr "mode" "SI")
5527 (set_attr "length" "
48")])
5530 (define_insn "ashldi3_internal2"
5531 [(set (match_operand:DI
0 "register_operand" "=d")
5532 (ashift:DI (match_operand:DI
1 "register_operand" "d")
5533 (match_operand:SI
2 "small_int" "IJK")))
5534 (clobber (match_operand:SI
3 "register_operand" "=d"))]
5535 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
5536 && (INTVAL (operands[
2]) &
32) !=
0"
5538 operands[
2] = GEN_INT (INTVAL (operands[
2]) &
0x1f);
5539 return "sll
\t%M0,%L1,%
2\;move
\t%L0,%.";
5541 [(set_attr "type" "darith")
5542 (set_attr "mode" "DI")
5543 (set_attr "length" "
8")])
5547 [(set (match_operand:DI
0 "register_operand" "")
5548 (ashift:DI (match_operand:DI
1 "register_operand" "")
5549 (match_operand:SI
2 "small_int" "")))
5550 (clobber (match_operand:SI
3 "register_operand" ""))]
5551 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
5552 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
5553 && GET_CODE (operands[
0]) == REG && REGNO (operands[
0]) < FIRST_PSEUDO_REGISTER
5554 && GET_CODE (operands[
1]) == REG && REGNO (operands[
1]) < FIRST_PSEUDO_REGISTER
5555 && (INTVAL (operands[
2]) &
32) !=
0"
5557 [(set (subreg:SI (match_dup
0)
4) (ashift:SI (subreg:SI (match_dup
1)
0) (match_dup
2)))
5558 (set (subreg:SI (match_dup
0)
0) (const_int
0))]
5560 "operands[
2] = GEN_INT (INTVAL (operands[
2]) &
0x1f);")
5564 [(set (match_operand:DI
0 "register_operand" "")
5565 (ashift:DI (match_operand:DI
1 "register_operand" "")
5566 (match_operand:SI
2 "small_int" "")))
5567 (clobber (match_operand:SI
3 "register_operand" ""))]
5568 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
5569 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
5570 && GET_CODE (operands[
0]) == REG && REGNO (operands[
0]) < FIRST_PSEUDO_REGISTER
5571 && GET_CODE (operands[
1]) == REG && REGNO (operands[
1]) < FIRST_PSEUDO_REGISTER
5572 && (INTVAL (operands[
2]) &
32) !=
0"
5574 [(set (subreg:SI (match_dup
0)
0) (ashift:SI (subreg:SI (match_dup
1)
4) (match_dup
2)))
5575 (set (subreg:SI (match_dup
0)
4) (const_int
0))]
5577 "operands[
2] = GEN_INT (INTVAL (operands[
2]) &
0x1f);")
5580 (define_insn "ashldi3_internal3"
5581 [(set (match_operand:DI
0 "register_operand" "=d")
5582 (ashift:DI (match_operand:DI
1 "register_operand" "d")
5583 (match_operand:SI
2 "small_int" "IJK")))
5584 (clobber (match_operand:SI
3 "register_operand" "=d"))]
5585 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
5586 && (INTVAL (operands[
2]) &
63) <
32
5587 && (INTVAL (operands[
2]) &
63) !=
0"
5589 int amount = INTVAL (operands[
2]);
5591 operands[
2] = GEN_INT (amount &
31);
5592 operands[
4] = GEN_INT ((-amount) &
31);
5594 return "sll
\t%M0,%M1,%
2\;srl
\t%
3,%L1,%
4\;or
\t%M0,%M0,%
3\;sll
\t%L0,%L1,%
2";
5596 [(set_attr "type" "darith")
5597 (set_attr "mode" "DI")
5598 (set_attr "length" "
16")])
5602 [(set (match_operand:DI
0 "register_operand" "")
5603 (ashift:DI (match_operand:DI
1 "register_operand" "")
5604 (match_operand:SI
2 "small_int" "")))
5605 (clobber (match_operand:SI
3 "register_operand" ""))]
5606 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
5607 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
5608 && GET_CODE (operands[
0]) == REG && REGNO (operands[
0]) < FIRST_PSEUDO_REGISTER
5609 && GET_CODE (operands[
1]) == REG && REGNO (operands[
1]) < FIRST_PSEUDO_REGISTER
5610 && (INTVAL (operands[
2]) &
63) <
32
5611 && (INTVAL (operands[
2]) &
63) !=
0"
5613 [(set (subreg:SI (match_dup
0)
4)
5614 (ashift:SI (subreg:SI (match_dup
1)
4)
5618 (lshiftrt:SI (subreg:SI (match_dup
1)
0)
5621 (set (subreg:SI (match_dup
0)
4)
5622 (ior:SI (subreg:SI (match_dup
0)
4)
5625 (set (subreg:SI (match_dup
0)
0)
5626 (ashift:SI (subreg:SI (match_dup
1)
0)
5629 int amount = INTVAL (operands[
2]);
5630 operands[
2] = GEN_INT (amount &
31);
5631 operands[
4] = GEN_INT ((-amount) &
31);
5636 [(set (match_operand:DI
0 "register_operand" "")
5637 (ashift:DI (match_operand:DI
1 "register_operand" "")
5638 (match_operand:SI
2 "small_int" "")))
5639 (clobber (match_operand:SI
3 "register_operand" ""))]
5640 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
5641 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
5642 && GET_CODE (operands[
0]) == REG && REGNO (operands[
0]) < FIRST_PSEUDO_REGISTER
5643 && GET_CODE (operands[
1]) == REG && REGNO (operands[
1]) < FIRST_PSEUDO_REGISTER
5644 && (INTVAL (operands[
2]) &
63) <
32
5645 && (INTVAL (operands[
2]) &
63) !=
0"
5647 [(set (subreg:SI (match_dup
0)
0)
5648 (ashift:SI (subreg:SI (match_dup
1)
0)
5652 (lshiftrt:SI (subreg:SI (match_dup
1)
4)
5655 (set (subreg:SI (match_dup
0)
0)
5656 (ior:SI (subreg:SI (match_dup
0)
0)
5659 (set (subreg:SI (match_dup
0)
4)
5660 (ashift:SI (subreg:SI (match_dup
1)
4)
5663 int amount = INTVAL (operands[
2]);
5664 operands[
2] = GEN_INT (amount &
31);
5665 operands[
4] = GEN_INT ((-amount) &
31);
5669 (define_insn "ashldi3_internal4"
5670 [(set (match_operand:DI
0 "register_operand" "=d")
5671 (ashift:DI (match_operand:DI
1 "register_operand" "d")
5672 (match_operand:SI
2 "arith_operand" "dI")))]
5673 "TARGET_64BIT && !TARGET_MIPS16"
5675 if (GET_CODE (operands[
2]) == CONST_INT)
5676 operands[
2] = GEN_INT (INTVAL (operands[
2]) &
0x3f);
5678 return "dsll
\t%
0,%
1,%
2";
5680 [(set_attr "type" "arith")
5681 (set_attr "mode" "DI")])
5684 [(set (match_operand:DI
0 "register_operand" "=d,d")
5685 (ashift:DI (match_operand:DI
1 "register_operand" "
0,d")
5686 (match_operand:SI
2 "arith_operand" "d,I")))]
5687 "TARGET_64BIT && TARGET_MIPS16"
5689 if (which_alternative ==
0)
5690 return "dsll
\t%
0,%
2";
5692 if (GET_CODE (operands[
2]) == CONST_INT)
5693 operands[
2] = GEN_INT (INTVAL (operands[
2]) &
0x3f);
5695 return "dsll
\t%
0,%
1,%
2";
5697 [(set_attr "type" "arith")
5698 (set_attr "mode" "DI")
5699 (set_attr_alternative "length"
5701 (if_then_else (match_operand:VOID
2 "m16_uimm3_b" "")
5706 ;; On the mips16, we can split a
4 byte shift into
2 2 byte shifts.
5709 [(set (match_operand:DI
0 "register_operand" "")
5710 (ashift:DI (match_operand:DI
1 "register_operand" "")
5711 (match_operand:SI
2 "const_int_operand" "")))]
5712 "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
5714 && GET_CODE (operands[
2]) == CONST_INT
5715 && INTVAL (operands[
2]) >
8
5716 && INTVAL (operands[
2]) <=
16"
5717 [(set (match_dup
0) (ashift:DI (match_dup
1) (const_int
8)))
5718 (set (match_dup
0) (ashift:DI (match_dup
0) (match_dup
2)))]
5719 { operands[
2] = GEN_INT (INTVAL (operands[
2]) -
8); })
5721 (define_expand "ashrsi3"
5722 [(set (match_operand:SI
0 "register_operand" "=d")
5723 (ashiftrt:SI (match_operand:SI
1 "register_operand" "d")
5724 (match_operand:SI
2 "arith_operand" "dI")))]
5727 /* On the mips16, a shift of more than
8 is a four byte instruction,
5728 so, for a shift between
8 and
16, it is just as fast to do two
5729 shifts of
8 or less. If there is a lot of shifting going on, we
5730 may win in CSE. Otherwise combine will put the shifts back
5734 && GET_CODE (operands[
2]) == CONST_INT
5735 && INTVAL (operands[
2]) >
8
5736 && INTVAL (operands[
2]) <=
16)
5738 rtx temp = gen_reg_rtx (SImode);
5740 emit_insn (gen_ashrsi3_internal2 (temp, operands[
1], GEN_INT (
8)));
5741 emit_insn (gen_ashrsi3_internal2 (operands[
0], temp,
5742 GEN_INT (INTVAL (operands[
2]) -
8)));
5747 (define_insn "ashrsi3_internal1"
5748 [(set (match_operand:SI
0 "register_operand" "=d")
5749 (ashiftrt:SI (match_operand:SI
1 "register_operand" "d")
5750 (match_operand:SI
2 "arith_operand" "dI")))]
5753 if (GET_CODE (operands[
2]) == CONST_INT)
5754 operands[
2] = GEN_INT (INTVAL (operands[
2]) &
0x1f);
5756 return "sra
\t%
0,%
1,%
2";
5758 [(set_attr "type" "arith")
5759 (set_attr "mode" "SI")])
5761 (define_insn "ashrsi3_internal2"
5762 [(set (match_operand:SI
0 "register_operand" "=d,d")
5763 (ashiftrt:SI (match_operand:SI
1 "register_operand" "
0,d")
5764 (match_operand:SI
2 "arith_operand" "d,I")))]
5767 if (which_alternative ==
0)
5768 return "sra
\t%
0,%
2";
5770 if (GET_CODE (operands[
2]) == CONST_INT)
5771 operands[
2] = GEN_INT (INTVAL (operands[
2]) &
0x1f);
5773 return "sra
\t%
0,%
1,%
2";
5775 [(set_attr "type" "arith")
5776 (set_attr "mode" "SI")
5777 (set_attr_alternative "length"
5779 (if_then_else (match_operand:VOID
2 "m16_uimm3_b" "")
5784 ;; On the mips16, we can split a
4 byte shift into
2 2 byte shifts.
5787 [(set (match_operand:SI
0 "register_operand" "")
5788 (ashiftrt:SI (match_operand:SI
1 "register_operand" "")
5789 (match_operand:SI
2 "const_int_operand" "")))]
5790 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5791 && GET_CODE (operands[
2]) == CONST_INT
5792 && INTVAL (operands[
2]) >
8
5793 && INTVAL (operands[
2]) <=
16"
5794 [(set (match_dup
0) (ashiftrt:SI (match_dup
1) (const_int
8)))
5795 (set (match_dup
0) (ashiftrt:SI (match_dup
0) (match_dup
2)))]
5796 { operands[
2] = GEN_INT (INTVAL (operands[
2]) -
8); })
5798 (define_expand "ashrdi3"
5799 [(parallel [(set (match_operand:DI
0 "register_operand" "")
5800 (ashiftrt:DI (match_operand:DI
1 "register_operand" "")
5801 (match_operand:SI
2 "arith_operand" "")))
5802 (clobber (match_dup
3))])]
5803 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
5807 /* On the mips16, a shift of more than
8 is a four byte
5808 instruction, so, for a shift between
8 and
16, it is just as
5809 fast to do two shifts of
8 or less. If there is a lot of
5810 shifting going on, we may win in CSE. Otherwise combine will
5811 put the shifts back together again. */
5814 && GET_CODE (operands[
2]) == CONST_INT
5815 && INTVAL (operands[
2]) >
8
5816 && INTVAL (operands[
2]) <=
16)
5818 rtx temp = gen_reg_rtx (DImode);
5820 emit_insn (gen_ashrdi3_internal4 (temp, operands[
1], GEN_INT (
8)));
5821 emit_insn (gen_ashrdi3_internal4 (operands[
0], temp,
5822 GEN_INT (INTVAL (operands[
2]) -
8)));
5826 emit_insn (gen_ashrdi3_internal4 (operands[
0], operands[
1],
5831 operands[
3] = gen_reg_rtx (SImode);
5835 (define_insn "ashrdi3_internal"
5836 [(set (match_operand:DI
0 "register_operand" "=&d")
5837 (ashiftrt:DI (match_operand:DI
1 "register_operand" "d")
5838 (match_operand:SI
2 "register_operand" "d")))
5839 (clobber (match_operand:SI
3 "register_operand" "=d"))]
5840 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
5857 [(set_attr "type" "darith")
5858 (set_attr "mode" "DI")
5859 (set_attr "length" "
48")])
5862 (define_insn "ashrdi3_internal2"
5863 [(set (match_operand:DI
0 "register_operand" "=d")
5864 (ashiftrt:DI (match_operand:DI
1 "register_operand" "d")
5865 (match_operand:SI
2 "small_int" "IJK")))
5866 (clobber (match_operand:SI
3 "register_operand" "=d"))]
5867 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[
2]) &
32) !=
0"
5869 operands[
2] = GEN_INT (INTVAL (operands[
2]) &
0x1f);
5870 return "sra
\t%L0,%M1,%
2\;sra
\t%M0,%M1,
31";
5872 [(set_attr "type" "darith")
5873 (set_attr "mode" "DI")
5874 (set_attr "length" "
8")])
5878 [(set (match_operand:DI
0 "register_operand" "")
5879 (ashiftrt:DI (match_operand:DI
1 "register_operand" "")
5880 (match_operand:SI
2 "small_int" "")))
5881 (clobber (match_operand:SI
3 "register_operand" ""))]
5882 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
5883 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
5884 && GET_CODE (operands[
0]) == REG && REGNO (operands[
0]) < FIRST_PSEUDO_REGISTER
5885 && GET_CODE (operands[
1]) == REG && REGNO (operands[
1]) < FIRST_PSEUDO_REGISTER
5886 && (INTVAL (operands[
2]) &
32) !=
0"
5888 [(set (subreg:SI (match_dup
0)
0) (ashiftrt:SI (subreg:SI (match_dup
1)
4) (match_dup
2)))
5889 (set (subreg:SI (match_dup
0)
4) (ashiftrt:SI (subreg:SI (match_dup
1)
4) (const_int
31)))]
5891 "operands[
2] = GEN_INT (INTVAL (operands[
2]) &
0x1f);")
5895 [(set (match_operand:DI
0 "register_operand" "")
5896 (ashiftrt:DI (match_operand:DI
1 "register_operand" "")
5897 (match_operand:SI
2 "small_int" "")))
5898 (clobber (match_operand:SI
3 "register_operand" ""))]
5899 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
5900 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
5901 && GET_CODE (operands[
0]) == REG && REGNO (operands[
0]) < FIRST_PSEUDO_REGISTER
5902 && GET_CODE (operands[
1]) == REG && REGNO (operands[
1]) < FIRST_PSEUDO_REGISTER
5903 && (INTVAL (operands[
2]) &
32) !=
0"
5905 [(set (subreg:SI (match_dup
0)
4) (ashiftrt:SI (subreg:SI (match_dup
1)
0) (match_dup
2)))
5906 (set (subreg:SI (match_dup
0)
0) (ashiftrt:SI (subreg:SI (match_dup
1)
0) (const_int
31)))]
5908 "operands[
2] = GEN_INT (INTVAL (operands[
2]) &
0x1f);")
5911 (define_insn "ashrdi3_internal3"
5912 [(set (match_operand:DI
0 "register_operand" "=d")
5913 (ashiftrt:DI (match_operand:DI
1 "register_operand" "d")
5914 (match_operand:SI
2 "small_int" "IJK")))
5915 (clobber (match_operand:SI
3 "register_operand" "=d"))]
5916 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
5917 && (INTVAL (operands[
2]) &
63) <
32
5918 && (INTVAL (operands[
2]) &
63) !=
0"
5920 int amount = INTVAL (operands[
2]);
5922 operands[
2] = GEN_INT (amount &
31);
5923 operands[
4] = GEN_INT ((-amount) &
31);
5925 return "srl
\t%L0,%L1,%
2\;sll
\t%
3,%M1,%
4\;or
\t%L0,%L0,%
3\;sra
\t%M0,%M1,%
2";
5927 [(set_attr "type" "darith")
5928 (set_attr "mode" "DI")
5929 (set_attr "length" "
16")])
5933 [(set (match_operand:DI
0 "register_operand" "")
5934 (ashiftrt:DI (match_operand:DI
1 "register_operand" "")
5935 (match_operand:SI
2 "small_int" "")))
5936 (clobber (match_operand:SI
3 "register_operand" ""))]
5937 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
5938 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
5939 && GET_CODE (operands[
0]) == REG && REGNO (operands[
0]) < FIRST_PSEUDO_REGISTER
5940 && GET_CODE (operands[
1]) == REG && REGNO (operands[
1]) < FIRST_PSEUDO_REGISTER
5941 && (INTVAL (operands[
2]) &
63) <
32
5942 && (INTVAL (operands[
2]) &
63) !=
0"
5944 [(set (subreg:SI (match_dup
0)
0)
5945 (lshiftrt:SI (subreg:SI (match_dup
1)
0)
5949 (ashift:SI (subreg:SI (match_dup
1)
4)
5952 (set (subreg:SI (match_dup
0)
0)
5953 (ior:SI (subreg:SI (match_dup
0)
0)
5956 (set (subreg:SI (match_dup
0)
4)
5957 (ashiftrt:SI (subreg:SI (match_dup
1)
4)
5960 int amount = INTVAL (operands[
2]);
5961 operands[
2] = GEN_INT (amount &
31);
5962 operands[
4] = GEN_INT ((-amount) &
31);
5967 [(set (match_operand:DI
0 "register_operand" "")
5968 (ashiftrt:DI (match_operand:DI
1 "register_operand" "")
5969 (match_operand:SI
2 "small_int" "")))
5970 (clobber (match_operand:SI
3 "register_operand" ""))]
5971 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
5972 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
5973 && GET_CODE (operands[
0]) == REG && REGNO (operands[
0]) < FIRST_PSEUDO_REGISTER
5974 && GET_CODE (operands[
1]) == REG && REGNO (operands[
1]) < FIRST_PSEUDO_REGISTER
5975 && (INTVAL (operands[
2]) &
63) <
32
5976 && (INTVAL (operands[
2]) &
63) !=
0"
5978 [(set (subreg:SI (match_dup
0)
4)
5979 (lshiftrt:SI (subreg:SI (match_dup
1)
4)
5983 (ashift:SI (subreg:SI (match_dup
1)
0)
5986 (set (subreg:SI (match_dup
0)
4)
5987 (ior:SI (subreg:SI (match_dup
0)
4)
5990 (set (subreg:SI (match_dup
0)
0)
5991 (ashiftrt:SI (subreg:SI (match_dup
1)
0)
5994 int amount = INTVAL (operands[
2]);
5995 operands[
2] = GEN_INT (amount &
31);
5996 operands[
4] = GEN_INT ((-amount) &
31);
6000 (define_insn "ashrdi3_internal4"
6001 [(set (match_operand:DI
0 "register_operand" "=d")
6002 (ashiftrt:DI (match_operand:DI
1 "register_operand" "d")
6003 (match_operand:SI
2 "arith_operand" "dI")))]
6004 "TARGET_64BIT && !TARGET_MIPS16"
6006 if (GET_CODE (operands[
2]) == CONST_INT)
6007 operands[
2] = GEN_INT (INTVAL (operands[
2]) &
0x3f);
6009 return "dsra
\t%
0,%
1,%
2";
6011 [(set_attr "type" "arith")
6012 (set_attr "mode" "DI")])
6015 [(set (match_operand:DI
0 "register_operand" "=d,d")
6016 (ashiftrt:DI (match_operand:DI
1 "register_operand" "
0,
0")
6017 (match_operand:SI
2 "arith_operand" "d,I")))]
6018 "TARGET_64BIT && TARGET_MIPS16"
6020 if (GET_CODE (operands[
2]) == CONST_INT)
6021 operands[
2] = GEN_INT (INTVAL (operands[
2]) &
0x3f);
6023 return "dsra
\t%
0,%
2";
6025 [(set_attr "type" "arith")
6026 (set_attr "mode" "DI")
6027 (set_attr_alternative "length"
6029 (if_then_else (match_operand:VOID
2 "m16_uimm3_b" "")
6033 ;; On the mips16, we can split a
4 byte shift into
2 2 byte shifts.
6036 [(set (match_operand:DI
0 "register_operand" "")
6037 (ashiftrt:DI (match_operand:DI
1 "register_operand" "")
6038 (match_operand:SI
2 "const_int_operand" "")))]
6039 "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
6041 && GET_CODE (operands[
2]) == CONST_INT
6042 && INTVAL (operands[
2]) >
8
6043 && INTVAL (operands[
2]) <=
16"
6044 [(set (match_dup
0) (ashiftrt:DI (match_dup
1) (const_int
8)))
6045 (set (match_dup
0) (ashiftrt:DI (match_dup
0) (match_dup
2)))]
6046 { operands[
2] = GEN_INT (INTVAL (operands[
2]) -
8); })
6048 (define_expand "lshrsi3"
6049 [(set (match_operand:SI
0 "register_operand" "=d")
6050 (lshiftrt:SI (match_operand:SI
1 "register_operand" "d")
6051 (match_operand:SI
2 "arith_operand" "dI")))]
6054 /* On the mips16, a shift of more than
8 is a four byte instruction,
6055 so, for a shift between
8 and
16, it is just as fast to do two
6056 shifts of
8 or less. If there is a lot of shifting going on, we
6057 may win in CSE. Otherwise combine will put the shifts back
6061 && GET_CODE (operands[
2]) == CONST_INT
6062 && INTVAL (operands[
2]) >
8
6063 && INTVAL (operands[
2]) <=
16)
6065 rtx temp = gen_reg_rtx (SImode);
6067 emit_insn (gen_lshrsi3_internal2 (temp, operands[
1], GEN_INT (
8)));
6068 emit_insn (gen_lshrsi3_internal2 (operands[
0], temp,
6069 GEN_INT (INTVAL (operands[
2]) -
8)));
6074 (define_insn "lshrsi3_internal1"
6075 [(set (match_operand:SI
0 "register_operand" "=d")
6076 (lshiftrt:SI (match_operand:SI
1 "register_operand" "d")
6077 (match_operand:SI
2 "arith_operand" "dI")))]
6080 if (GET_CODE (operands[
2]) == CONST_INT)
6081 operands[
2] = GEN_INT (INTVAL (operands[
2]) &
0x1f);
6083 return "srl
\t%
0,%
1,%
2";
6085 [(set_attr "type" "arith")
6086 (set_attr "mode" "SI")])
6088 (define_insn "lshrsi3_internal2"
6089 [(set (match_operand:SI
0 "register_operand" "=d,d")
6090 (lshiftrt:SI (match_operand:SI
1 "register_operand" "
0,d")
6091 (match_operand:SI
2 "arith_operand" "d,I")))]
6094 if (which_alternative ==
0)
6095 return "srl
\t%
0,%
2";
6097 if (GET_CODE (operands[
2]) == CONST_INT)
6098 operands[
2] = GEN_INT (INTVAL (operands[
2]) &
0x1f);
6100 return "srl
\t%
0,%
1,%
2";
6102 [(set_attr "type" "arith")
6103 (set_attr "mode" "SI")
6104 (set_attr_alternative "length"
6106 (if_then_else (match_operand:VOID
2 "m16_uimm3_b" "")
6111 ;; On the mips16, we can split a
4 byte shift into
2 2 byte shifts.
6114 [(set (match_operand:SI
0 "register_operand" "")
6115 (lshiftrt:SI (match_operand:SI
1 "register_operand" "")
6116 (match_operand:SI
2 "const_int_operand" "")))]
6117 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6118 && GET_CODE (operands[
2]) == CONST_INT
6119 && INTVAL (operands[
2]) >
8
6120 && INTVAL (operands[
2]) <=
16"
6121 [(set (match_dup
0) (lshiftrt:SI (match_dup
1) (const_int
8)))
6122 (set (match_dup
0) (lshiftrt:SI (match_dup
0) (match_dup
2)))]
6123 { operands[
2] = GEN_INT (INTVAL (operands[
2]) -
8); })
6125 ;; If we load a byte on the mips16 as a bitfield, the resulting
6126 ;; sequence of instructions is too complicated for combine, because it
6127 ;; involves four instructions: a load, a shift, a constant load into a
6128 ;; register, and an and (the key problem here is that the mips16 does
6129 ;; not have and immediate). We recognize a shift of a load in order
6130 ;; to make it simple enough for combine to understand.
6132 ;; The length here is the worst case: the length of the split version
6133 ;; will be more accurate.
6134 (define_insn_and_split ""
6135 [(set (match_operand:SI
0 "register_operand" "=d")
6136 (lshiftrt:SI (match_operand:SI
1 "memory_operand" "m")
6137 (match_operand:SI
2 "immediate_operand" "I")))]
6141 [(set (match_dup
0) (match_dup
1))
6142 (set (match_dup
0) (lshiftrt:SI (match_dup
0) (match_dup
2)))]
6144 [(set_attr "type" "load")
6145 (set_attr "mode" "SI")
6146 (set_attr "length" "
16")])
6148 (define_expand "lshrdi3"
6149 [(parallel [(set (match_operand:DI
0 "register_operand" "")
6150 (lshiftrt:DI (match_operand:DI
1 "register_operand" "")
6151 (match_operand:SI
2 "arith_operand" "")))
6152 (clobber (match_dup
3))])]
6153 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
6157 /* On the mips16, a shift of more than
8 is a four byte
6158 instruction, so, for a shift between
8 and
16, it is just as
6159 fast to do two shifts of
8 or less. If there is a lot of
6160 shifting going on, we may win in CSE. Otherwise combine will
6161 put the shifts back together again. */
6164 && GET_CODE (operands[
2]) == CONST_INT
6165 && INTVAL (operands[
2]) >
8
6166 && INTVAL (operands[
2]) <=
16)
6168 rtx temp = gen_reg_rtx (DImode);
6170 emit_insn (gen_lshrdi3_internal4 (temp, operands[
1], GEN_INT (
8)));
6171 emit_insn (gen_lshrdi3_internal4 (operands[
0], temp,
6172 GEN_INT (INTVAL (operands[
2]) -
8)));
6176 emit_insn (gen_lshrdi3_internal4 (operands[
0], operands[
1],
6181 operands[
3] = gen_reg_rtx (SImode);
6185 (define_insn "lshrdi3_internal"
6186 [(set (match_operand:DI
0 "register_operand" "=&d")
6187 (lshiftrt:DI (match_operand:DI
1 "register_operand" "d")
6188 (match_operand:SI
2 "register_operand" "d")))
6189 (clobber (match_operand:SI
3 "register_operand" "=d"))]
6190 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
6207 [(set_attr "type" "darith")
6208 (set_attr "mode" "DI")
6209 (set_attr "length" "
48")])
6212 (define_insn "lshrdi3_internal2"
6213 [(set (match_operand:DI
0 "register_operand" "=d")
6214 (lshiftrt:DI (match_operand:DI
1 "register_operand" "d")
6215 (match_operand:SI
2 "small_int" "IJK")))
6216 (clobber (match_operand:SI
3 "register_operand" "=d"))]
6217 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6218 && (INTVAL (operands[
2]) &
32) !=
0"
6220 operands[
2] = GEN_INT (INTVAL (operands[
2]) &
0x1f);
6221 return "srl
\t%L0,%M1,%
2\;move
\t%M0,%.";
6223 [(set_attr "type" "darith")
6224 (set_attr "mode" "DI")
6225 (set_attr "length" "
8")])
6229 [(set (match_operand:DI
0 "register_operand" "")
6230 (lshiftrt:DI (match_operand:DI
1 "register_operand" "")
6231 (match_operand:SI
2 "small_int" "")))
6232 (clobber (match_operand:SI
3 "register_operand" ""))]
6233 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6234 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6235 && GET_CODE (operands[
0]) == REG && REGNO (operands[
0]) < FIRST_PSEUDO_REGISTER
6236 && GET_CODE (operands[
1]) == REG && REGNO (operands[
1]) < FIRST_PSEUDO_REGISTER
6237 && (INTVAL (operands[
2]) &
32) !=
0"
6239 [(set (subreg:SI (match_dup
0)
0) (lshiftrt:SI (subreg:SI (match_dup
1)
4) (match_dup
2)))
6240 (set (subreg:SI (match_dup
0)
4) (const_int
0))]
6242 "operands[
2] = GEN_INT (INTVAL (operands[
2]) &
0x1f);")
6246 [(set (match_operand:DI
0 "register_operand" "")
6247 (lshiftrt:DI (match_operand:DI
1 "register_operand" "")
6248 (match_operand:SI
2 "small_int" "")))
6249 (clobber (match_operand:SI
3 "register_operand" ""))]
6250 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6251 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6252 && GET_CODE (operands[
0]) == REG && REGNO (operands[
0]) < FIRST_PSEUDO_REGISTER
6253 && GET_CODE (operands[
1]) == REG && REGNO (operands[
1]) < FIRST_PSEUDO_REGISTER
6254 && (INTVAL (operands[
2]) &
32) !=
0"
6256 [(set (subreg:SI (match_dup
0)
4) (lshiftrt:SI (subreg:SI (match_dup
1)
0) (match_dup
2)))
6257 (set (subreg:SI (match_dup
0)
0) (const_int
0))]
6259 "operands[
2] = GEN_INT (INTVAL (operands[
2]) &
0x1f);")
6262 (define_insn "lshrdi3_internal3"
6263 [(set (match_operand:DI
0 "register_operand" "=d")
6264 (lshiftrt:DI (match_operand:DI
1 "register_operand" "d")
6265 (match_operand:SI
2 "small_int" "IJK")))
6266 (clobber (match_operand:SI
3 "register_operand" "=d"))]
6267 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6268 && (INTVAL (operands[
2]) &
63) <
32
6269 && (INTVAL (operands[
2]) &
63) !=
0"
6271 int amount = INTVAL (operands[
2]);
6273 operands[
2] = GEN_INT (amount &
31);
6274 operands[
4] = GEN_INT ((-amount) &
31);
6276 return "srl
\t%L0,%L1,%
2\;sll
\t%
3,%M1,%
4\;or
\t%L0,%L0,%
3\;srl
\t%M0,%M1,%
2";
6278 [(set_attr "type" "darith")
6279 (set_attr "mode" "DI")
6280 (set_attr "length" "
16")])
6284 [(set (match_operand:DI
0 "register_operand" "")
6285 (lshiftrt:DI (match_operand:DI
1 "register_operand" "")
6286 (match_operand:SI
2 "small_int" "")))
6287 (clobber (match_operand:SI
3 "register_operand" ""))]
6288 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6289 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6290 && GET_CODE (operands[
0]) == REG && REGNO (operands[
0]) < FIRST_PSEUDO_REGISTER
6291 && GET_CODE (operands[
1]) == REG && REGNO (operands[
1]) < FIRST_PSEUDO_REGISTER
6292 && (INTVAL (operands[
2]) &
63) <
32
6293 && (INTVAL (operands[
2]) &
63) !=
0"
6295 [(set (subreg:SI (match_dup
0)
0)
6296 (lshiftrt:SI (subreg:SI (match_dup
1)
0)
6300 (ashift:SI (subreg:SI (match_dup
1)
4)
6303 (set (subreg:SI (match_dup
0)
0)
6304 (ior:SI (subreg:SI (match_dup
0)
0)
6307 (set (subreg:SI (match_dup
0)
4)
6308 (lshiftrt:SI (subreg:SI (match_dup
1)
4)
6311 int amount = INTVAL (operands[
2]);
6312 operands[
2] = GEN_INT (amount &
31);
6313 operands[
4] = GEN_INT ((-amount) &
31);
6318 [(set (match_operand:DI
0 "register_operand" "")
6319 (lshiftrt:DI (match_operand:DI
1 "register_operand" "")
6320 (match_operand:SI
2 "small_int" "")))
6321 (clobber (match_operand:SI
3 "register_operand" ""))]
6322 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6323 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6324 && GET_CODE (operands[
0]) == REG && REGNO (operands[
0]) < FIRST_PSEUDO_REGISTER
6325 && GET_CODE (operands[
1]) == REG && REGNO (operands[
1]) < FIRST_PSEUDO_REGISTER
6326 && (INTVAL (operands[
2]) &
63) <
32
6327 && (INTVAL (operands[
2]) &
63) !=
0"
6329 [(set (subreg:SI (match_dup
0)
4)
6330 (lshiftrt:SI (subreg:SI (match_dup
1)
4)
6334 (ashift:SI (subreg:SI (match_dup
1)
0)
6337 (set (subreg:SI (match_dup
0)
4)
6338 (ior:SI (subreg:SI (match_dup
0)
4)
6341 (set (subreg:SI (match_dup
0)
0)
6342 (lshiftrt:SI (subreg:SI (match_dup
1)
0)
6345 int amount = INTVAL (operands[
2]);
6346 operands[
2] = GEN_INT (amount &
31);
6347 operands[
4] = GEN_INT ((-amount) &
31);
6351 (define_insn "lshrdi3_internal4"
6352 [(set (match_operand:DI
0 "register_operand" "=d")
6353 (lshiftrt:DI (match_operand:DI
1 "register_operand" "d")
6354 (match_operand:SI
2 "arith_operand" "dI")))]
6355 "TARGET_64BIT && !TARGET_MIPS16"
6357 if (GET_CODE (operands[
2]) == CONST_INT)
6358 operands[
2] = GEN_INT (INTVAL (operands[
2]) &
0x3f);
6360 return "dsrl
\t%
0,%
1,%
2";
6362 [(set_attr "type" "arith")
6363 (set_attr "mode" "DI")])
6366 [(set (match_operand:DI
0 "register_operand" "=d,d")
6367 (lshiftrt:DI (match_operand:DI
1 "register_operand" "
0,
0")
6368 (match_operand:SI
2 "arith_operand" "d,I")))]
6369 "TARGET_64BIT && TARGET_MIPS16"
6371 if (GET_CODE (operands[
2]) == CONST_INT)
6372 operands[
2] = GEN_INT (INTVAL (operands[
2]) &
0x3f);
6374 return "dsrl
\t%
0,%
2";
6376 [(set_attr "type" "arith")
6377 (set_attr "mode" "DI")
6378 (set_attr_alternative "length"
6380 (if_then_else (match_operand:VOID
2 "m16_uimm3_b" "")
6384 (define_insn "rotrsi3"
6385 [(set (match_operand:SI
0 "register_operand" "=d")
6386 (rotatert:SI (match_operand:SI
1 "register_operand" "d")
6387 (match_operand:SI
2 "arith_operand" "dn")))]
6390 if (TARGET_SR71K && GET_CODE (operands[
2]) != CONST_INT)
6391 return "rorv
\t%
0,%
1,%
2";
6393 if ((GET_CODE (operands[
2]) == CONST_INT)
6394 && (INTVAL (operands[
2]) <
0 || INTVAL (operands[
2]) >=
32))
6397 return "ror
\t%
0,%
1,%
2";
6399 [(set_attr "type" "arith")
6400 (set_attr "mode" "SI")])
6402 (define_insn "rotrdi3"
6403 [(set (match_operand:DI
0 "register_operand" "=d")
6404 (rotatert:DI (match_operand:DI
1 "register_operand" "d")
6405 (match_operand:DI
2 "arith_operand" "dn")))]
6410 if (GET_CODE (operands[
2]) != CONST_INT)
6411 return "drorv
\t%
0,%
1,%
2";
6413 if (INTVAL (operands[
2]) >=
32 && INTVAL (operands[
2]) <=
63)
6414 return "dror32
\t%
0,%
1,%
2";
6417 if ((GET_CODE (operands[
2]) == CONST_INT)
6418 && (INTVAL (operands[
2]) <
0 || INTVAL (operands[
2]) >=
64))
6421 return "dror
\t%
0,%
1,%
2";
6423 [(set_attr "type" "arith")
6424 (set_attr "mode" "DI")])
6427 ;; On the mips16, we can split a
4 byte shift into
2 2 byte shifts.
6430 [(set (match_operand:DI
0 "register_operand" "")
6431 (lshiftrt:DI (match_operand:DI
1 "register_operand" "")
6432 (match_operand:SI
2 "const_int_operand" "")))]
6433 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6434 && GET_CODE (operands[
2]) == CONST_INT
6435 && INTVAL (operands[
2]) >
8
6436 && INTVAL (operands[
2]) <=
16"
6437 [(set (match_dup
0) (lshiftrt:DI (match_dup
1) (const_int
8)))
6438 (set (match_dup
0) (lshiftrt:DI (match_dup
0) (match_dup
2)))]
6439 { operands[
2] = GEN_INT (INTVAL (operands[
2]) -
8); })
6442 ;; ....................
6446 ;; ....................
6448 ;; Flow here is rather complex:
6450 ;;
1) The cmp{si,di,sf,df} routine is called. It deposits the
6451 ;; arguments into the branch_cmp array, and the type into
6452 ;; branch_type. No RTL is generated.
6454 ;;
2) The appropriate branch define_expand is called, which then
6455 ;; creates the appropriate RTL for the comparison and branch.
6456 ;; Different CC modes are used, based on what type of branch is
6457 ;; done, so that we can constrain things appropriately. There
6458 ;; are assumptions in the rest of GCC that break if we fold the
6459 ;; operands into the branches for integer operations, and use cc0
6460 ;; for floating point, so we use the fp status register instead.
6461 ;; If needed, an appropriate temporary is created to hold the
6462 ;; of the integer compare.
6464 (define_expand "cmpsi"
6466 (compare:CC (match_operand:SI
0 "register_operand" "")
6467 (match_operand:SI
1 "arith_operand" "")))]
6470 branch_cmp[
0] = operands[
0];
6471 branch_cmp[
1] = operands[
1];
6472 branch_type = CMP_SI;
6476 (define_expand "cmpdi"
6478 (compare:CC (match_operand:DI
0 "register_operand" "")
6479 (match_operand:DI
1 "arith_operand" "")))]
6482 branch_cmp[
0] = operands[
0];
6483 branch_cmp[
1] = operands[
1];
6484 branch_type = CMP_DI;
6488 (define_expand "cmpdf"
6490 (compare:CC (match_operand:DF
0 "register_operand" "")
6491 (match_operand:DF
1 "register_operand" "")))]
6492 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6494 branch_cmp[
0] = operands[
0];
6495 branch_cmp[
1] = operands[
1];
6496 branch_type = CMP_DF;
6500 (define_expand "cmpsf"
6502 (compare:CC (match_operand:SF
0 "register_operand" "")
6503 (match_operand:SF
1 "register_operand" "")))]
6506 branch_cmp[
0] = operands[
0];
6507 branch_cmp[
1] = operands[
1];
6508 branch_type = CMP_SF;
6513 ;; ....................
6515 ;; CONDITIONAL BRANCHES
6517 ;; ....................
6519 ;; Conditional branches on floating-point equality tests.
6521 (define_insn "branch_fp"
6524 (match_operator:CC
0 "cmp_op"
6525 [(match_operand:CC
2 "register_operand" "z")
6527 (label_ref (match_operand
1 "" ""))
6531 return mips_output_conditional_branch (insn,
6533 /*two_operands_p=*/
0,
6536 get_attr_length (insn));
6538 [(set_attr "type" "branch")
6539 (set_attr "mode" "none")])
6541 (define_insn "branch_fp_inverted"
6544 (match_operator:CC
0 "cmp_op"
6545 [(match_operand:CC
2 "register_operand" "z")
6548 (label_ref (match_operand
1 "" ""))))]
6551 return mips_output_conditional_branch (insn,
6553 /*two_operands_p=*/
0,
6556 get_attr_length (insn));
6558 [(set_attr "type" "branch")
6559 (set_attr "mode" "none")])
6561 ;; Conditional branches on comparisons with zero.
6563 (define_insn "branch_zero"
6566 (match_operator:SI
0 "cmp_op"
6567 [(match_operand:SI
2 "register_operand" "d")
6569 (label_ref (match_operand
1 "" ""))
6573 return mips_output_conditional_branch (insn,
6575 /*two_operands_p=*/
0,
6578 get_attr_length (insn));
6580 [(set_attr "type" "branch")
6581 (set_attr "mode" "none")])
6583 (define_insn "branch_zero_inverted"
6586 (match_operator:SI
0 "cmp_op"
6587 [(match_operand:SI
2 "register_operand" "d")
6590 (label_ref (match_operand
1 "" ""))))]
6593 return mips_output_conditional_branch (insn,
6595 /*two_operands_p=*/
0,
6598 get_attr_length (insn));
6600 [(set_attr "type" "branch")
6601 (set_attr "mode" "none")])
6603 (define_insn "branch_zero_di"
6606 (match_operator:DI
0 "cmp_op"
6607 [(match_operand:DI
2 "register_operand" "d")
6609 (label_ref (match_operand
1 "" ""))
6613 return mips_output_conditional_branch (insn,
6615 /*two_operands_p=*/
0,
6618 get_attr_length (insn));
6620 [(set_attr "type" "branch")
6621 (set_attr "mode" "none")])
6623 (define_insn "branch_zero_di_inverted"
6626 (match_operator:DI
0 "cmp_op"
6627 [(match_operand:DI
2 "register_operand" "d")
6630 (label_ref (match_operand
1 "" ""))))]
6633 return mips_output_conditional_branch (insn,
6635 /*two_operands_p=*/
0,
6638 get_attr_length (insn));
6640 [(set_attr "type" "branch")
6641 (set_attr "mode" "none")])
6643 ;; Conditional branch on equality comparison.
6645 (define_insn "branch_equality"
6648 (match_operator:SI
0 "equality_op"
6649 [(match_operand:SI
2 "register_operand" "d")
6650 (match_operand:SI
3 "register_operand" "d")])
6651 (label_ref (match_operand
1 "" ""))
6655 return mips_output_conditional_branch (insn,
6657 /*two_operands_p=*/
1,
6660 get_attr_length (insn));
6662 [(set_attr "type" "branch")
6663 (set_attr "mode" "none")])
6665 (define_insn "branch_equality_di"
6668 (match_operator:DI
0 "equality_op"
6669 [(match_operand:DI
2 "register_operand" "d")
6670 (match_operand:DI
3 "register_operand" "d")])
6671 (label_ref (match_operand
1 "" ""))
6675 return mips_output_conditional_branch (insn,
6677 /*two_operands_p=*/
1,
6680 get_attr_length (insn));
6682 [(set_attr "type" "branch")
6683 (set_attr "mode" "none")])
6685 (define_insn "branch_equality_inverted"
6688 (match_operator:SI
0 "equality_op"
6689 [(match_operand:SI
2 "register_operand" "d")
6690 (match_operand:SI
3 "register_operand" "d")])
6692 (label_ref (match_operand
1 "" ""))))]
6695 return mips_output_conditional_branch (insn,
6697 /*two_operands_p=*/
1,
6700 get_attr_length (insn));
6702 [(set_attr "type" "branch")
6703 (set_attr "mode" "none")])
6705 (define_insn "branch_equality_di_inverted"
6708 (match_operator:DI
0 "equality_op"
6709 [(match_operand:DI
2 "register_operand" "d")
6710 (match_operand:DI
3 "register_operand" "d")])
6712 (label_ref (match_operand
1 "" ""))))]
6715 return mips_output_conditional_branch (insn,
6717 /*two_operands_p=*/
1,
6720 get_attr_length (insn));
6722 [(set_attr "type" "branch")
6723 (set_attr "mode" "none")])
6729 (if_then_else (match_operator:SI
0 "equality_op"
6730 [(match_operand:SI
1 "register_operand" "d,t")
6732 (match_operand
2 "pc_or_label_operand" "")
6733 (match_operand
3 "pc_or_label_operand" "")))]
6736 if (operands[
2] != pc_rtx)
6738 if (which_alternative ==
0)
6739 return "b%C0z
\t%
1,%
2";
6741 return "bt%C0z
\t%
2";
6745 if (which_alternative ==
0)
6746 return "b%N0z
\t%
1,%
3";
6748 return "bt%N0z
\t%
3";
6751 [(set_attr "type" "branch")
6752 (set_attr "mode" "none")
6753 (set_attr "length" "
8")])
6757 (if_then_else (match_operator:DI
0 "equality_op"
6758 [(match_operand:DI
1 "register_operand" "d,t")
6760 (match_operand
2 "pc_or_label_operand" "")
6761 (match_operand
3 "pc_or_label_operand" "")))]
6764 if (operands[
2] != pc_rtx)
6766 if (which_alternative ==
0)
6767 return "b%C0z
\t%
1,%
2";
6769 return "bt%C0z
\t%
2";
6773 if (which_alternative ==
0)
6774 return "b%N0z
\t%
1,%
3";
6776 return "bt%N0z
\t%
3";
6779 [(set_attr "type" "branch")
6780 (set_attr "mode" "none")
6781 (set_attr "length" "
8")])
6783 (define_expand "bunordered"
6785 (if_then_else (unordered:CC (cc0)
6787 (label_ref (match_operand
0 "" ""))
6791 gen_conditional_branch (operands, UNORDERED);
6795 (define_expand "bordered"
6797 (if_then_else (ordered:CC (cc0)
6799 (label_ref (match_operand
0 "" ""))
6803 gen_conditional_branch (operands, ORDERED);
6807 (define_expand "bunlt"
6809 (if_then_else (unlt:CC (cc0)
6811 (label_ref (match_operand
0 "" ""))
6815 gen_conditional_branch (operands, UNLT);
6819 (define_expand "bunge"
6821 (if_then_else (unge:CC (cc0)
6823 (label_ref (match_operand
0 "" ""))
6827 gen_conditional_branch (operands, UNGE);
6831 (define_expand "buneq"
6833 (if_then_else (uneq:CC (cc0)
6835 (label_ref (match_operand
0 "" ""))
6839 gen_conditional_branch (operands, UNEQ);
6843 (define_expand "bltgt"
6845 (if_then_else (ltgt:CC (cc0)
6847 (label_ref (match_operand
0 "" ""))
6851 gen_conditional_branch (operands, LTGT);
6855 (define_expand "bunle"
6857 (if_then_else (unle:CC (cc0)
6859 (label_ref (match_operand
0 "" ""))
6863 gen_conditional_branch (operands, UNLE);
6867 (define_expand "bungt"
6869 (if_then_else (ungt:CC (cc0)
6871 (label_ref (match_operand
0 "" ""))
6875 gen_conditional_branch (operands, UNGT);
6879 (define_expand "beq"
6881 (if_then_else (eq:CC (cc0)
6883 (label_ref (match_operand
0 "" ""))
6887 gen_conditional_branch (operands, EQ);
6891 (define_expand "bne"
6893 (if_then_else (ne:CC (cc0)
6895 (label_ref (match_operand
0 "" ""))
6899 gen_conditional_branch (operands, NE);
6903 (define_expand "bgt"
6905 (if_then_else (gt:CC (cc0)
6907 (label_ref (match_operand
0 "" ""))
6911 gen_conditional_branch (operands, GT);
6915 (define_expand "bge"
6917 (if_then_else (ge:CC (cc0)
6919 (label_ref (match_operand
0 "" ""))
6923 gen_conditional_branch (operands, GE);
6927 (define_expand "blt"
6929 (if_then_else (lt:CC (cc0)
6931 (label_ref (match_operand
0 "" ""))
6935 gen_conditional_branch (operands, LT);
6939 (define_expand "ble"
6941 (if_then_else (le:CC (cc0)
6943 (label_ref (match_operand
0 "" ""))
6947 gen_conditional_branch (operands, LE);
6951 (define_expand "bgtu"
6953 (if_then_else (gtu:CC (cc0)
6955 (label_ref (match_operand
0 "" ""))
6959 gen_conditional_branch (operands, GTU);
6963 (define_expand "bgeu"
6965 (if_then_else (geu:CC (cc0)
6967 (label_ref (match_operand
0 "" ""))
6971 gen_conditional_branch (operands, GEU);
6975 (define_expand "bltu"
6977 (if_then_else (ltu:CC (cc0)
6979 (label_ref (match_operand
0 "" ""))
6983 gen_conditional_branch (operands, LTU);
6987 (define_expand "bleu"
6989 (if_then_else (leu:CC (cc0)
6991 (label_ref (match_operand
0 "" ""))
6995 gen_conditional_branch (operands, LEU);
7000 ;; ....................
7002 ;; SETTING A REGISTER FROM A COMPARISON
7004 ;; ....................
7006 (define_expand "seq"
7007 [(set (match_operand:SI
0 "register_operand" "=d")
7008 (eq:SI (match_dup
1)
7012 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7015 /* Set up operands from compare. */
7016 operands[
1] = branch_cmp[
0];
7017 operands[
2] = branch_cmp[
1];
7019 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7021 gen_int_relational (EQ, operands[
0], operands[
1], operands[
2], (int *)
0);
7025 if (GET_CODE (operands[
2]) == CONST_INT && INTVAL (operands[
2]) <
0)
7026 operands[
2] = force_reg (SImode, operands[
2]);
7028 /* Fall through and generate default code. */
7032 (define_insn "seq_si_zero"
7033 [(set (match_operand:SI
0 "register_operand" "=d")
7034 (eq:SI (match_operand:SI
1 "register_operand" "d")
7038 [(set_attr "type" "arith")
7039 (set_attr "mode" "SI")])
7042 [(set (match_operand:SI
0 "register_operand" "=t")
7043 (eq:SI (match_operand:SI
1 "register_operand" "d")
7047 [(set_attr "type" "arith")
7048 (set_attr "mode" "SI")])
7050 (define_insn "seq_di_zero"
7051 [(set (match_operand:DI
0 "register_operand" "=d")
7052 (eq:DI (match_operand:DI
1 "register_operand" "d")
7054 "TARGET_64BIT && !TARGET_MIPS16"
7056 [(set_attr "type" "arith")
7057 (set_attr "mode" "DI")])
7060 [(set (match_operand:DI
0 "register_operand" "=t")
7061 (eq:DI (match_operand:DI
1 "register_operand" "d")
7063 "TARGET_64BIT && TARGET_MIPS16"
7065 [(set_attr "type" "arith")
7066 (set_attr "mode" "DI")])
7068 (define_insn "seq_si"
7069 [(set (match_operand:SI
0 "register_operand" "=d,d")
7070 (eq:SI (match_operand:SI
1 "register_operand" "%d,d")
7071 (match_operand:SI
2 "uns_arith_operand" "d,K")))]
7072 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7074 xor
\t%
0,%
1,%
2\;sltu
\t%
0,%
0,
1
7075 xori
\t%
0,%
1,%
2\;sltu
\t%
0,%
0,
1"
7076 [(set_attr "type" "arith")
7077 (set_attr "mode" "SI")
7078 (set_attr "length" "
8")])
7081 [(set (match_operand:SI
0 "register_operand" "")
7082 (eq:SI (match_operand:SI
1 "register_operand" "")
7083 (match_operand:SI
2 "uns_arith_operand" "")))]
7084 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
7085 && (GET_CODE (operands[
2]) != CONST_INT || INTVAL (operands[
2]) !=
0)"
7087 (xor:SI (match_dup
1)
7090 (ltu:SI (match_dup
0)
7094 (define_insn "seq_di"
7095 [(set (match_operand:DI
0 "register_operand" "=d,d")
7096 (eq:DI (match_operand:DI
1 "register_operand" "%d,d")
7097 (match_operand:DI
2 "uns_arith_operand" "d,K")))]
7098 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7100 xor
\t%
0,%
1,%
2\;sltu
\t%
0,%
0,
1
7101 xori
\t%
0,%
1,%
2\;sltu
\t%
0,%
0,
1"
7102 [(set_attr "type" "arith")
7103 (set_attr "mode" "DI")
7104 (set_attr "length" "
8")])
7107 [(set (match_operand:DI
0 "register_operand" "")
7108 (eq:DI (match_operand:DI
1 "register_operand" "")
7109 (match_operand:DI
2 "uns_arith_operand" "")))]
7110 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
7112 && (GET_CODE (operands[
2]) != CONST_INT || INTVAL (operands[
2]) !=
0)"
7114 (xor:DI (match_dup
1)
7117 (ltu:DI (match_dup
0)
7121 ;; On the mips16 the default code is better than using sltu.
7123 (define_expand "sne"
7124 [(set (match_operand:SI
0 "register_operand" "=d")
7125 (ne:SI (match_dup
1)
7129 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7132 /* Set up operands from compare. */
7133 operands[
1] = branch_cmp[
0];
7134 operands[
2] = branch_cmp[
1];
7136 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
7138 gen_int_relational (NE, operands[
0], operands[
1], operands[
2], (int *)
0);
7142 if (GET_CODE (operands[
2]) == CONST_INT && INTVAL (operands[
2]) <
0)
7143 operands[
2] = force_reg (SImode, operands[
2]);
7145 /* Fall through and generate default code. */
7148 (define_insn "sne_si_zero"
7149 [(set (match_operand:SI
0 "register_operand" "=d")
7150 (ne:SI (match_operand:SI
1 "register_operand" "d")
7154 [(set_attr "type" "arith")
7155 (set_attr "mode" "SI")])
7157 (define_insn "sne_di_zero"
7158 [(set (match_operand:DI
0 "register_operand" "=d")
7159 (ne:DI (match_operand:DI
1 "register_operand" "d")
7161 "TARGET_64BIT && !TARGET_MIPS16"
7163 [(set_attr "type" "arith")
7164 (set_attr "mode" "DI")])
7166 (define_insn "sne_si"
7167 [(set (match_operand:SI
0 "register_operand" "=d,d")
7168 (ne:SI (match_operand:SI
1 "register_operand" "%d,d")
7169 (match_operand:SI
2 "uns_arith_operand" "d,K")))]
7170 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7172 xor
\t%
0,%
1,%
2\;sltu
\t%
0,%.,%
0
7173 xori
\t%
0,%
1,%x2\;sltu
\t%
0,%.,%
0"
7174 [(set_attr "type" "arith")
7175 (set_attr "mode" "SI")
7176 (set_attr "length" "
8")])
7179 [(set (match_operand:SI
0 "register_operand" "")
7180 (ne:SI (match_operand:SI
1 "register_operand" "")
7181 (match_operand:SI
2 "uns_arith_operand" "")))]
7182 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
7183 && (GET_CODE (operands[
2]) != CONST_INT || INTVAL (operands[
2]) !=
0)"
7185 (xor:SI (match_dup
1)
7188 (gtu:SI (match_dup
0)
7192 (define_insn "sne_di"
7193 [(set (match_operand:DI
0 "register_operand" "=d,d")
7194 (ne:DI (match_operand:DI
1 "register_operand" "%d,d")
7195 (match_operand:DI
2 "uns_arith_operand" "d,K")))]
7196 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7198 xor
\t%
0,%
1,%
2\;sltu
\t%
0,%.,%
0
7199 xori
\t%
0,%
1,%x2\;sltu
\t%
0,%.,%
0"
7200 [(set_attr "type" "arith")
7201 (set_attr "mode" "DI")
7202 (set_attr "length" "
8")])
7205 [(set (match_operand:DI
0 "register_operand" "")
7206 (ne:DI (match_operand:DI
1 "register_operand" "")
7207 (match_operand:DI
2 "uns_arith_operand" "")))]
7208 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
7210 && (GET_CODE (operands[
2]) != CONST_INT || INTVAL (operands[
2]) !=
0)"
7212 (xor:DI (match_dup
1)
7215 (gtu:DI (match_dup
0)
7219 (define_expand "sgt"
7220 [(set (match_operand:SI
0 "register_operand" "=d")
7221 (gt:SI (match_dup
1)
7225 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7228 /* Set up operands from compare. */
7229 operands[
1] = branch_cmp[
0];
7230 operands[
2] = branch_cmp[
1];
7232 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7234 gen_int_relational (GT, operands[
0], operands[
1], operands[
2], (int *)
0);
7238 if (GET_CODE (operands[
2]) == CONST_INT && INTVAL (operands[
2]) !=
0)
7239 operands[
2] = force_reg (SImode, operands[
2]);
7241 /* Fall through and generate default code. */
7244 (define_insn "sgt_si"
7245 [(set (match_operand:SI
0 "register_operand" "=d")
7246 (gt:SI (match_operand:SI
1 "register_operand" "d")
7247 (match_operand:SI
2 "reg_or_0_operand" "dJ")))]
7250 [(set_attr "type" "arith")
7251 (set_attr "mode" "SI")])
7254 [(set (match_operand:SI
0 "register_operand" "=t")
7255 (gt:SI (match_operand:SI
1 "register_operand" "d")
7256 (match_operand:SI
2 "register_operand" "d")))]
7259 [(set_attr "type" "arith")
7260 (set_attr "mode" "SI")])
7262 (define_insn "sgt_di"
7263 [(set (match_operand:DI
0 "register_operand" "=d")
7264 (gt:DI (match_operand:DI
1 "register_operand" "d")
7265 (match_operand:DI
2 "reg_or_0_operand" "dJ")))]
7266 "TARGET_64BIT && !TARGET_MIPS16"
7268 [(set_attr "type" "arith")
7269 (set_attr "mode" "DI")])
7272 [(set (match_operand:DI
0 "register_operand" "=d")
7273 (gt:DI (match_operand:DI
1 "register_operand" "d")
7274 (match_operand:DI
2 "register_operand" "d")))]
7275 "TARGET_64BIT && TARGET_MIPS16"
7277 [(set_attr "type" "arith")
7278 (set_attr "mode" "DI")])
7280 (define_expand "sge"
7281 [(set (match_operand:SI
0 "register_operand" "=d")
7282 (ge:SI (match_dup
1)
7286 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7289 /* Set up operands from compare. */
7290 operands[
1] = branch_cmp[
0];
7291 operands[
2] = branch_cmp[
1];
7293 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7295 gen_int_relational (GE, operands[
0], operands[
1], operands[
2], (int *)
0);
7299 /* Fall through and generate default code. */
7302 (define_insn "sge_si"
7303 [(set (match_operand:SI
0 "register_operand" "=d")
7304 (ge:SI (match_operand:SI
1 "register_operand" "d")
7305 (match_operand:SI
2 "arith_operand" "dI")))]
7306 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7307 "slt
\t%
0,%
1,%
2\;xori
\t%
0,%
0,
0x0001"
7308 [(set_attr "type" "arith")
7309 (set_attr "mode" "SI")
7310 (set_attr "length" "
8")])
7313 [(set (match_operand:SI
0 "register_operand" "")
7314 (ge:SI (match_operand:SI
1 "register_operand" "")
7315 (match_operand:SI
2 "arith_operand" "")))]
7316 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
7318 (lt:SI (match_dup
1)
7321 (xor:SI (match_dup
0)
7325 (define_insn "sge_di"
7326 [(set (match_operand:DI
0 "register_operand" "=d")
7327 (ge:DI (match_operand:DI
1 "register_operand" "d")
7328 (match_operand:DI
2 "arith_operand" "dI")))]
7329 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7330 "slt
\t%
0,%
1,%
2\;xori
\t%
0,%
0,
0x0001"
7331 [(set_attr "type" "arith")
7332 (set_attr "mode" "DI")
7333 (set_attr "length" "
8")])
7336 [(set (match_operand:DI
0 "register_operand" "")
7337 (ge:DI (match_operand:DI
1 "register_operand" "")
7338 (match_operand:DI
2 "arith_operand" "")))]
7339 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
7342 (lt:DI (match_dup
1)
7345 (xor:DI (match_dup
0)
7349 (define_expand "slt"
7350 [(set (match_operand:SI
0 "register_operand" "=d")
7351 (lt:SI (match_dup
1)
7355 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7358 /* Set up operands from compare. */
7359 operands[
1] = branch_cmp[
0];
7360 operands[
2] = branch_cmp[
1];
7362 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7364 gen_int_relational (LT, operands[
0], operands[
1], operands[
2], (int *)
0);
7368 /* Fall through and generate default code. */
7371 (define_insn "slt_si"
7372 [(set (match_operand:SI
0 "register_operand" "=d")
7373 (lt:SI (match_operand:SI
1 "register_operand" "d")
7374 (match_operand:SI
2 "arith_operand" "dI")))]
7377 [(set_attr "type" "arith")
7378 (set_attr "mode" "SI")])
7381 [(set (match_operand:SI
0 "register_operand" "=t,t")
7382 (lt:SI (match_operand:SI
1 "register_operand" "d,d")
7383 (match_operand:SI
2 "arith_operand" "d,I")))]
7386 [(set_attr "type" "arith")
7387 (set_attr "mode" "SI")
7388 (set_attr_alternative "length"
7390 (if_then_else (match_operand:VOID
2 "m16_uimm8_1" "")
7394 (define_insn "slt_di"
7395 [(set (match_operand:DI
0 "register_operand" "=d")
7396 (lt:DI (match_operand:DI
1 "register_operand" "d")
7397 (match_operand:DI
2 "arith_operand" "dI")))]
7398 "TARGET_64BIT && !TARGET_MIPS16"
7400 [(set_attr "type" "arith")
7401 (set_attr "mode" "DI")])
7404 [(set (match_operand:DI
0 "register_operand" "=t,t")
7405 (lt:DI (match_operand:DI
1 "register_operand" "d,d")
7406 (match_operand:DI
2 "arith_operand" "d,I")))]
7407 "TARGET_64BIT && TARGET_MIPS16"
7409 [(set_attr "type" "arith")
7410 (set_attr "mode" "DI")
7411 (set_attr_alternative "length"
7413 (if_then_else (match_operand:VOID
2 "m16_uimm8_1" "")
7417 (define_expand "sle"
7418 [(set (match_operand:SI
0 "register_operand" "=d")
7419 (le:SI (match_dup
1)
7423 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7426 /* Set up operands from compare. */
7427 operands[
1] = branch_cmp[
0];
7428 operands[
2] = branch_cmp[
1];
7430 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7432 gen_int_relational (LE, operands[
0], operands[
1], operands[
2], (int *)
0);
7436 if (GET_CODE (operands[
2]) == CONST_INT && INTVAL (operands[
2]) >=
32767)
7437 operands[
2] = force_reg (SImode, operands[
2]);
7439 /* Fall through and generate default code. */
7442 (define_insn "sle_si_const"
7443 [(set (match_operand:SI
0 "register_operand" "=d")
7444 (le:SI (match_operand:SI
1 "register_operand" "d")
7445 (match_operand:SI
2 "small_int" "I")))]
7446 "!TARGET_MIPS16 && INTVAL (operands[
2]) <
32767"
7448 operands[
2] = GEN_INT (INTVAL (operands[
2])+
1);
7449 return "slt
\t%
0,%
1,%
2";
7451 [(set_attr "type" "arith")
7452 (set_attr "mode" "SI")])
7455 [(set (match_operand:SI
0 "register_operand" "=t")
7456 (le:SI (match_operand:SI
1 "register_operand" "d")
7457 (match_operand:SI
2 "small_int" "I")))]
7458 "TARGET_MIPS16 && INTVAL (operands[
2]) <
32767"
7460 operands[
2] = GEN_INT (INTVAL (operands[
2])+
1);
7461 return "slt
\t%
1,%
2";
7463 [(set_attr "type" "arith")
7464 (set_attr "mode" "SI")
7465 (set (attr "length") (if_then_else (match_operand:VOID
2 "m16_uimm8_m1_1" "")
7469 (define_insn "sle_di_const"
7470 [(set (match_operand:DI
0 "register_operand" "=d")
7471 (le:DI (match_operand:DI
1 "register_operand" "d")
7472 (match_operand:DI
2 "small_int" "I")))]
7473 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[
2]) <
32767"
7475 operands[
2] = GEN_INT (INTVAL (operands[
2])+
1);
7476 return "slt
\t%
0,%
1,%
2";
7478 [(set_attr "type" "arith")
7479 (set_attr "mode" "DI")])
7482 [(set (match_operand:DI
0 "register_operand" "=t")
7483 (le:DI (match_operand:DI
1 "register_operand" "d")
7484 (match_operand:DI
2 "small_int" "I")))]
7485 "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[
2]) <
32767"
7487 operands[
2] = GEN_INT (INTVAL (operands[
2])+
1);
7488 return "slt
\t%
1,%
2";
7490 [(set_attr "type" "arith")
7491 (set_attr "mode" "DI")
7492 (set (attr "length") (if_then_else (match_operand:VOID
2 "m16_uimm8_m1_1" "")
7496 (define_insn "sle_si_reg"
7497 [(set (match_operand:SI
0 "register_operand" "=d")
7498 (le:SI (match_operand:SI
1 "register_operand" "d")
7499 (match_operand:SI
2 "register_operand" "d")))]
7500 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7501 "slt
\t%
0,%z2,%
1\;xori
\t%
0,%
0,
0x0001"
7502 [(set_attr "type" "arith")
7503 (set_attr "mode" "SI")
7504 (set_attr "length" "
8")])
7507 [(set (match_operand:SI
0 "register_operand" "")
7508 (le:SI (match_operand:SI
1 "register_operand" "")
7509 (match_operand:SI
2 "register_operand" "")))]
7510 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
7512 (lt:SI (match_dup
2)
7515 (xor:SI (match_dup
0)
7519 (define_insn "sle_di_reg"
7520 [(set (match_operand:DI
0 "register_operand" "=d")
7521 (le:DI (match_operand:DI
1 "register_operand" "d")
7522 (match_operand:DI
2 "register_operand" "d")))]
7523 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7524 "slt
\t%
0,%z2,%
1\;xori
\t%
0,%
0,
0x0001"
7525 [(set_attr "type" "arith")
7526 (set_attr "mode" "DI")
7527 (set_attr "length" "
8")])
7530 [(set (match_operand:DI
0 "register_operand" "")
7531 (le:DI (match_operand:DI
1 "register_operand" "")
7532 (match_operand:DI
2 "register_operand" "")))]
7533 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
7536 (lt:DI (match_dup
2)
7539 (xor:DI (match_dup
0)
7543 (define_expand "sgtu"
7544 [(set (match_operand:SI
0 "register_operand" "=d")
7545 (gtu:SI (match_dup
1)
7549 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7552 /* Set up operands from compare. */
7553 operands[
1] = branch_cmp[
0];
7554 operands[
2] = branch_cmp[
1];
7556 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7558 gen_int_relational (GTU, operands[
0], operands[
1], operands[
2], (int *)
0);
7562 if (GET_CODE (operands[
2]) == CONST_INT && INTVAL (operands[
2]) !=
0)
7563 operands[
2] = force_reg (SImode, operands[
2]);
7565 /* Fall through and generate default code. */
7568 (define_insn "sgtu_si"
7569 [(set (match_operand:SI
0 "register_operand" "=d")
7570 (gtu:SI (match_operand:SI
1 "register_operand" "d")
7571 (match_operand:SI
2 "reg_or_0_operand" "dJ")))]
7574 [(set_attr "type" "arith")
7575 (set_attr "mode" "SI")])
7578 [(set (match_operand:SI
0 "register_operand" "=t")
7579 (gtu:SI (match_operand:SI
1 "register_operand" "d")
7580 (match_operand:SI
2 "register_operand" "d")))]
7583 [(set_attr "type" "arith")
7584 (set_attr "mode" "SI")])
7586 (define_insn "sgtu_di"
7587 [(set (match_operand:DI
0 "register_operand" "=d")
7588 (gtu:DI (match_operand:DI
1 "register_operand" "d")
7589 (match_operand:DI
2 "reg_or_0_operand" "dJ")))]
7590 "TARGET_64BIT && !TARGET_MIPS16"
7592 [(set_attr "type" "arith")
7593 (set_attr "mode" "DI")])
7596 [(set (match_operand:DI
0 "register_operand" "=t")
7597 (gtu:DI (match_operand:DI
1 "register_operand" "d")
7598 (match_operand:DI
2 "register_operand" "d")))]
7599 "TARGET_64BIT && TARGET_MIPS16"
7601 [(set_attr "type" "arith")
7602 (set_attr "mode" "DI")])
7604 (define_expand "sgeu"
7605 [(set (match_operand:SI
0 "register_operand" "=d")
7606 (geu:SI (match_dup
1)
7610 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7613 /* Set up operands from compare. */
7614 operands[
1] = branch_cmp[
0];
7615 operands[
2] = branch_cmp[
1];
7617 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7619 gen_int_relational (GEU, operands[
0], operands[
1], operands[
2], (int *)
0);
7623 /* Fall through and generate default code. */
7626 (define_insn "sgeu_si"
7627 [(set (match_operand:SI
0 "register_operand" "=d")
7628 (geu:SI (match_operand:SI
1 "register_operand" "d")
7629 (match_operand:SI
2 "arith_operand" "dI")))]
7630 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7631 "sltu
\t%
0,%
1,%
2\;xori
\t%
0,%
0,
0x0001"
7632 [(set_attr "type" "arith")
7633 (set_attr "mode" "SI")
7634 (set_attr "length" "
8")])
7637 [(set (match_operand:SI
0 "register_operand" "")
7638 (geu:SI (match_operand:SI
1 "register_operand" "")
7639 (match_operand:SI
2 "arith_operand" "")))]
7640 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
7642 (ltu:SI (match_dup
1)
7645 (xor:SI (match_dup
0)
7649 (define_insn "sgeu_di"
7650 [(set (match_operand:DI
0 "register_operand" "=d")
7651 (geu:DI (match_operand:DI
1 "register_operand" "d")
7652 (match_operand:DI
2 "arith_operand" "dI")))]
7653 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7654 "sltu
\t%
0,%
1,%
2\;xori
\t%
0,%
0,
0x0001"
7655 [(set_attr "type" "arith")
7656 (set_attr "mode" "DI")
7657 (set_attr "length" "
8")])
7660 [(set (match_operand:DI
0 "register_operand" "")
7661 (geu:DI (match_operand:DI
1 "register_operand" "")
7662 (match_operand:DI
2 "arith_operand" "")))]
7663 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
7666 (ltu:DI (match_dup
1)
7669 (xor:DI (match_dup
0)
7673 (define_expand "sltu"
7674 [(set (match_operand:SI
0 "register_operand" "=d")
7675 (ltu:SI (match_dup
1)
7679 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7682 /* Set up operands from compare. */
7683 operands[
1] = branch_cmp[
0];
7684 operands[
2] = branch_cmp[
1];
7686 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7688 gen_int_relational (LTU, operands[
0], operands[
1], operands[
2], (int *)
0);
7692 /* Fall through and generate default code. */
7695 (define_insn "sltu_si"
7696 [(set (match_operand:SI
0 "register_operand" "=d")
7697 (ltu:SI (match_operand:SI
1 "register_operand" "d")
7698 (match_operand:SI
2 "arith_operand" "dI")))]
7701 [(set_attr "type" "arith")
7702 (set_attr "mode" "SI")])
7705 [(set (match_operand:SI
0 "register_operand" "=t,t")
7706 (ltu:SI (match_operand:SI
1 "register_operand" "d,d")
7707 (match_operand:SI
2 "arith_operand" "d,I")))]
7710 [(set_attr "type" "arith")
7711 (set_attr "mode" "SI")
7712 (set_attr_alternative "length"
7714 (if_then_else (match_operand:VOID
2 "m16_uimm8_1" "")
7718 (define_insn "sltu_di"
7719 [(set (match_operand:DI
0 "register_operand" "=d")
7720 (ltu:DI (match_operand:DI
1 "register_operand" "d")
7721 (match_operand:DI
2 "arith_operand" "dI")))]
7722 "TARGET_64BIT && !TARGET_MIPS16"
7724 [(set_attr "type" "arith")
7725 (set_attr "mode" "DI")])
7728 [(set (match_operand:DI
0 "register_operand" "=t,t")
7729 (ltu:DI (match_operand:DI
1 "register_operand" "d,d")
7730 (match_operand:DI
2 "arith_operand" "d,I")))]
7731 "TARGET_64BIT && TARGET_MIPS16"
7733 [(set_attr "type" "arith")
7734 (set_attr "mode" "DI")
7735 (set_attr_alternative "length"
7737 (if_then_else (match_operand:VOID
2 "m16_uimm8_1" "")
7741 (define_expand "sleu"
7742 [(set (match_operand:SI
0 "register_operand" "=d")
7743 (leu:SI (match_dup
1)
7747 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7750 /* Set up operands from compare. */
7751 operands[
1] = branch_cmp[
0];
7752 operands[
2] = branch_cmp[
1];
7754 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7756 gen_int_relational (LEU, operands[
0], operands[
1], operands[
2], (int *)
0);
7760 if (GET_CODE (operands[
2]) == CONST_INT && INTVAL (operands[
2]) >=
32767)
7761 operands[
2] = force_reg (SImode, operands[
2]);
7763 /* Fall through and generate default code. */
7766 (define_insn "sleu_si_const"
7767 [(set (match_operand:SI
0 "register_operand" "=d")
7768 (leu:SI (match_operand:SI
1 "register_operand" "d")
7769 (match_operand:SI
2 "small_int" "I")))]
7770 "!TARGET_MIPS16 && INTVAL (operands[
2]) <
32767"
7772 operands[
2] = GEN_INT (INTVAL (operands[
2]) +
1);
7773 return "sltu
\t%
0,%
1,%
2";
7775 [(set_attr "type" "arith")
7776 (set_attr "mode" "SI")])
7779 [(set (match_operand:SI
0 "register_operand" "=t")
7780 (leu:SI (match_operand:SI
1 "register_operand" "d")
7781 (match_operand:SI
2 "small_int" "I")))]
7782 "TARGET_MIPS16 && INTVAL (operands[
2]) <
32767"
7784 operands[
2] = GEN_INT (INTVAL (operands[
2])+
1);
7785 return "sltu
\t%
1,%
2";
7787 [(set_attr "type" "arith")
7788 (set_attr "mode" "SI")
7789 (set (attr "length") (if_then_else (match_operand:VOID
2 "m16_uimm8_m1_1" "")
7793 (define_insn "sleu_di_const"
7794 [(set (match_operand:DI
0 "register_operand" "=d")
7795 (leu:DI (match_operand:DI
1 "register_operand" "d")
7796 (match_operand:DI
2 "small_int" "I")))]
7797 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[
2]) <
32767"
7799 operands[
2] = GEN_INT (INTVAL (operands[
2]) +
1);
7800 return "sltu
\t%
0,%
1,%
2";
7802 [(set_attr "type" "arith")
7803 (set_attr "mode" "DI")])
7806 [(set (match_operand:DI
0 "register_operand" "=t")
7807 (leu:DI (match_operand:DI
1 "register_operand" "d")
7808 (match_operand:DI
2 "small_int" "I")))]
7809 "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[
2]) <
32767"
7811 operands[
2] = GEN_INT (INTVAL (operands[
2])+
1);
7812 return "sltu
\t%
1,%
2";
7814 [(set_attr "type" "arith")
7815 (set_attr "mode" "DI")
7816 (set (attr "length") (if_then_else (match_operand:VOID
2 "m16_uimm8_m1_1" "")
7820 (define_insn "sleu_si_reg"
7821 [(set (match_operand:SI
0 "register_operand" "=d")
7822 (leu:SI (match_operand:SI
1 "register_operand" "d")
7823 (match_operand:SI
2 "register_operand" "d")))]
7824 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7825 "sltu
\t%
0,%z2,%
1\;xori
\t%
0,%
0,
0x0001"
7826 [(set_attr "type" "arith")
7827 (set_attr "mode" "SI")
7828 (set_attr "length" "
8")])
7831 [(set (match_operand:SI
0 "register_operand" "")
7832 (leu:SI (match_operand:SI
1 "register_operand" "")
7833 (match_operand:SI
2 "register_operand" "")))]
7834 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
7836 (ltu:SI (match_dup
2)
7839 (xor:SI (match_dup
0)
7843 (define_insn "sleu_di_reg"
7844 [(set (match_operand:DI
0 "register_operand" "=d")
7845 (leu:DI (match_operand:DI
1 "register_operand" "d")
7846 (match_operand:DI
2 "register_operand" "d")))]
7847 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7848 "sltu
\t%
0,%z2,%
1\;xori
\t%
0,%
0,
0x0001"
7849 [(set_attr "type" "arith")
7850 (set_attr "mode" "DI")
7851 (set_attr "length" "
8")])
7854 [(set (match_operand:DI
0 "register_operand" "")
7855 (leu:DI (match_operand:DI
1 "register_operand" "")
7856 (match_operand:DI
2 "register_operand" "")))]
7857 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
7860 (ltu:DI (match_dup
2)
7863 (xor:DI (match_dup
0)
7868 ;; ....................
7870 ;; FLOATING POINT COMPARISONS
7872 ;; ....................
7874 (define_insn "sunordered_df"
7875 [(set (match_operand:CC
0 "register_operand" "=z")
7876 (unordered:CC (match_operand:DF
1 "register_operand" "f")
7877 (match_operand:DF
2 "register_operand" "f")))]
7878 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7880 [(set_attr "type" "fcmp")
7881 (set_attr "mode" "FPSW")])
7883 (define_insn "sunlt_df"
7884 [(set (match_operand:CC
0 "register_operand" "=z")
7885 (unlt:CC (match_operand:DF
1 "register_operand" "f")
7886 (match_operand:DF
2 "register_operand" "f")))]
7887 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7889 [(set_attr "type" "fcmp")
7890 (set_attr "mode" "FPSW")])
7892 (define_insn "suneq_df"
7893 [(set (match_operand:CC
0 "register_operand" "=z")
7894 (uneq:CC (match_operand:DF
1 "register_operand" "f")
7895 (match_operand:DF
2 "register_operand" "f")))]
7896 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7898 [(set_attr "type" "fcmp")
7899 (set_attr "mode" "FPSW")])
7901 (define_insn "sunle_df"
7902 [(set (match_operand:CC
0 "register_operand" "=z")
7903 (unle:CC (match_operand:DF
1 "register_operand" "f")
7904 (match_operand:DF
2 "register_operand" "f")))]
7905 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7907 [(set_attr "type" "fcmp")
7908 (set_attr "mode" "FPSW")])
7910 (define_insn "seq_df"
7911 [(set (match_operand:CC
0 "register_operand" "=z")
7912 (eq:CC (match_operand:DF
1 "register_operand" "f")
7913 (match_operand:DF
2 "register_operand" "f")))]
7914 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7916 [(set_attr "type" "fcmp")
7917 (set_attr "mode" "FPSW")])
7919 (define_insn "slt_df"
7920 [(set (match_operand:CC
0 "register_operand" "=z")
7921 (lt:CC (match_operand:DF
1 "register_operand" "f")
7922 (match_operand:DF
2 "register_operand" "f")))]
7923 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7925 [(set_attr "type" "fcmp")
7926 (set_attr "mode" "FPSW")])
7928 (define_insn "sle_df"
7929 [(set (match_operand:CC
0 "register_operand" "=z")
7930 (le:CC (match_operand:DF
1 "register_operand" "f")
7931 (match_operand:DF
2 "register_operand" "f")))]
7932 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7934 [(set_attr "type" "fcmp")
7935 (set_attr "mode" "FPSW")])
7937 (define_insn "sgt_df"
7938 [(set (match_operand:CC
0 "register_operand" "=z")
7939 (gt:CC (match_operand:DF
1 "register_operand" "f")
7940 (match_operand:DF
2 "register_operand" "f")))]
7941 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7943 [(set_attr "type" "fcmp")
7944 (set_attr "mode" "FPSW")])
7946 (define_insn "sge_df"
7947 [(set (match_operand:CC
0 "register_operand" "=z")
7948 (ge:CC (match_operand:DF
1 "register_operand" "f")
7949 (match_operand:DF
2 "register_operand" "f")))]
7950 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7952 [(set_attr "type" "fcmp")
7953 (set_attr "mode" "FPSW")])
7955 (define_insn "sunordered_sf"
7956 [(set (match_operand:CC
0 "register_operand" "=z")
7957 (unordered:CC (match_operand:SF
1 "register_operand" "f")
7958 (match_operand:SF
2 "register_operand" "f")))]
7961 [(set_attr "type" "fcmp")
7962 (set_attr "mode" "FPSW")])
7964 (define_insn "sunlt_sf"
7965 [(set (match_operand:CC
0 "register_operand" "=z")
7966 (unlt:CC (match_operand:SF
1 "register_operand" "f")
7967 (match_operand:SF
2 "register_operand" "f")))]
7970 [(set_attr "type" "fcmp")
7971 (set_attr "mode" "FPSW")])
7973 (define_insn "suneq_sf"
7974 [(set (match_operand:CC
0 "register_operand" "=z")
7975 (uneq:CC (match_operand:SF
1 "register_operand" "f")
7976 (match_operand:SF
2 "register_operand" "f")))]
7979 [(set_attr "type" "fcmp")
7980 (set_attr "mode" "FPSW")])
7982 (define_insn "sunle_sf"
7983 [(set (match_operand:CC
0 "register_operand" "=z")
7984 (unle:CC (match_operand:SF
1 "register_operand" "f")
7985 (match_operand:SF
2 "register_operand" "f")))]
7988 [(set_attr "type" "fcmp")
7989 (set_attr "mode" "FPSW")])
7991 (define_insn "seq_sf"
7992 [(set (match_operand:CC
0 "register_operand" "=z")
7993 (eq:CC (match_operand:SF
1 "register_operand" "f")
7994 (match_operand:SF
2 "register_operand" "f")))]
7997 [(set_attr "type" "fcmp")
7998 (set_attr "mode" "FPSW")])
8000 (define_insn "slt_sf"
8001 [(set (match_operand:CC
0 "register_operand" "=z")
8002 (lt:CC (match_operand:SF
1 "register_operand" "f")
8003 (match_operand:SF
2 "register_operand" "f")))]
8006 [(set_attr "type" "fcmp")
8007 (set_attr "mode" "FPSW")])
8009 (define_insn "sle_sf"
8010 [(set (match_operand:CC
0 "register_operand" "=z")
8011 (le:CC (match_operand:SF
1 "register_operand" "f")
8012 (match_operand:SF
2 "register_operand" "f")))]
8015 [(set_attr "type" "fcmp")
8016 (set_attr "mode" "FPSW")])
8018 (define_insn "sgt_sf"
8019 [(set (match_operand:CC
0 "register_operand" "=z")
8020 (gt:CC (match_operand:SF
1 "register_operand" "f")
8021 (match_operand:SF
2 "register_operand" "f")))]
8024 [(set_attr "type" "fcmp")
8025 (set_attr "mode" "FPSW")])
8027 (define_insn "sge_sf"
8028 [(set (match_operand:CC
0 "register_operand" "=z")
8029 (ge:CC (match_operand:SF
1 "register_operand" "f")
8030 (match_operand:SF
2 "register_operand" "f")))]
8033 [(set_attr "type" "fcmp")
8034 (set_attr "mode" "FPSW")])
8037 ;; ....................
8039 ;; UNCONDITIONAL BRANCHES
8041 ;; ....................
8043 ;; Unconditional branches.
8047 (label_ref (match_operand
0 "" "")))]
8050 if (flag_pic && ! TARGET_EMBEDDED_PIC)
8052 if (get_attr_length (insn) <=
8)
8053 return "%*b
\t%l0%/";
8056 output_asm_insn (mips_output_load_label (), operands);
8057 return "%*jr
\t%@%/%]";
8061 return "%*j
\t%l0%/";
8063 [(set_attr "type" "jump")
8064 (set_attr "mode" "none")
8065 (set (attr "length")
8066 ;; we can't use
`j' when emitting non-embedded PIC, so we emit
8067 ;; branch, if it's in range, or load the address of the branch
8068 ;; target into $at in a PIC-compatible way and then jump to it.
8070 (ior (eq (symbol_ref "flag_pic && ! TARGET_EMBEDDED_PIC")
8072 (lt (abs (minus (match_dup 0)
8073 (plus (pc) (const_int 4))))
8074 (const_int 131072)))
8075 (const_int 4) (const_int 16)))])
8077 ;; We need a different insn for the mips16, because a mips16 branch
8078 ;; does not have a delay slot.
8082 (label_ref (match_operand 0 "" "")))]
8085 [(set_attr "type" "branch")
8086 (set_attr "mode" "none")
8087 (set_attr "length" "8")])
8089 (define_expand "indirect_jump"
8090 [(set (pc) (match_operand 0 "register_operand" "d"))]
8096 if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
8097 operands[0] = copy_to_mode_reg (Pmode, dest);
8099 if (!(Pmode == DImode))
8100 emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
8102 emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
8107 (define_insn "indirect_jump_internal1"
8108 [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
8109 "!(Pmode == DImode)"
8111 [(set_attr "type" "jump")
8112 (set_attr "mode" "none")])
8114 (define_insn "indirect_jump_internal2"
8115 [(set (pc) (match_operand:DI 0 "register_operand" "d"))]
8118 [(set_attr "type" "jump")
8119 (set_attr "mode" "none")])
8121 (define_expand "tablejump"
8123 (match_operand 0 "register_operand" "d"))
8124 (use (label_ref (match_operand 1 "" "")))]
8129 if (GET_MODE (operands[0]) != HImode)
8131 if (!(Pmode == DImode))
8132 emit_insn (gen_tablejump_mips161 (operands[0], operands[1]));
8134 emit_insn (gen_tablejump_mips162 (operands[0], operands[1]));
8138 if (GET_MODE (operands[0]) != ptr_mode)
8142 operands[0] = expand_binop (ptr_mode, add_optab, operands[0],
8143 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
8145 if (Pmode == SImode)
8146 emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
8148 emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
8152 (define_insn "tablejump_internal1"
8154 (match_operand:SI 0 "register_operand" "d"))
8155 (use (label_ref (match_operand 1 "" "")))]
8158 [(set_attr "type" "jump")
8159 (set_attr "mode" "none")])
8161 (define_insn "tablejump_internal2"
8163 (match_operand:DI 0 "register_operand" "d"))
8164 (use (label_ref (match_operand 1 "" "")))]
8167 [(set_attr "type" "jump")
8168 (set_attr "mode" "none")])
8170 (define_expand "tablejump_mips161"
8171 [(set (pc) (plus:SI (sign_extend:SI
8172 (match_operand:HI 0 "register_operand" "d"))
8173 (label_ref:SI (match_operand 1 "" ""))))]
8174 "TARGET_MIPS16 && !(Pmode == DImode)"
8178 t1 = gen_reg_rtx (SImode);
8179 t2 = gen_reg_rtx (SImode);
8180 t3 = gen_reg_rtx (SImode);
8181 emit_insn (gen_extendhisi2 (t1, operands[0]));
8182 emit_move_insn (t2, gen_rtx_LABEL_REF (SImode, operands[1]));
8183 emit_insn (gen_addsi3 (t3, t1, t2));
8184 emit_jump_insn (gen_tablejump_internal1 (t3, operands[1]));
8188 (define_expand "tablejump_mips162"
8189 [(set (pc) (plus:DI (sign_extend:DI
8190 (match_operand:HI 0 "register_operand" "d"))
8191 (label_ref:DI (match_operand 1 "" ""))))]
8192 "TARGET_MIPS16 && Pmode == DImode"
8196 t1 = gen_reg_rtx (DImode);
8197 t2 = gen_reg_rtx (DImode);
8198 t3 = gen_reg_rtx (DImode);
8199 emit_insn (gen_extendhidi2 (t1, operands[0]));
8200 emit_move_insn (t2, gen_rtx_LABEL_REF (DImode, operands[1]));
8201 emit_insn (gen_adddi3 (t3, t1, t2));
8202 emit_jump_insn (gen_tablejump_internal2 (t3, operands[1]));
8206 ;; Implement a switch statement when generating embedded PIC code.
8207 ;; Switches are implemented by `tablejump' when not using -membedded-pic.
8209 (define_expand "casesi"
8211 (minus:SI (match_operand:SI
0 "register_operand" "")
8212 (match_operand:SI
1 "const_int_operand" "")))
8214 (compare:CC (match_dup
5)
8215 (match_operand:SI
2 "arith_operand" "")))
8217 (if_then_else (gtu (cc0)
8219 (label_ref (match_operand
4 "" ""))
8223 (mem:SI (plus:SI (mult:SI (match_dup
5)
8225 (label_ref (match_operand
3 "" "")))))
8226 (clobber (match_scratch:SI
6 ""))
8227 (clobber (reg:SI
31))])]
8228 "TARGET_EMBEDDED_PIC"
8232 /* If the index is too large, go to the default label. */
8233 index = expand_binop (SImode, sub_optab, operands[
0],
8234 operands[
1],
0,
0, OPTAB_WIDEN);
8235 emit_insn (gen_cmpsi (index, operands[
2]));
8236 emit_insn (gen_bgtu (operands[
4]));
8238 /* Do the PIC jump. */
8239 if (Pmode != DImode)
8240 emit_jump_insn (gen_casesi_internal (index, operands[
3],
8241 gen_reg_rtx (SImode)));
8243 emit_jump_insn (gen_casesi_internal_di (index, operands[
3],
8244 gen_reg_rtx (DImode)));
8249 ;; An embedded PIC switch statement looks like this:
8251 ;; sll $reg,$index,
2
8253 ;; addu $reg,$reg,$
31
8254 ;; lw $reg,$L1-$LS1($reg)
8255 ;; addu $reg,$reg,$
31
8262 (define_insn "casesi_internal"
8264 (mem:SI (plus:SI (mult:SI (match_operand:SI
0 "register_operand" "d")
8266 (label_ref (match_operand
1 "" "")))))
8267 (clobber (match_operand:SI
2 "register_operand" "=d"))
8268 (clobber (reg:SI
31))]
8269 "TARGET_EMBEDDED_PIC"
8272 return "%(bal
\\t%S1\;sll
\\t%
2,%
0,
2\\n%~%S1:\;addu
\\t%
2,%
2,$
31%)\;
\\
8273 .set macro\;lw
\\t%
2,%
1-%S1(%
2)\;.set nomacro\;addu
\\t%
2,%
2,$
31\\n
\\t%*j
\\t%
2%/";
8275 "%(bal
\\t%S1\;sll
\\t%
2,%
0,
2\\n%~%S1:\;addu
\\t%
2,%
2,$
31%)\;
\\
8276 lw
\\t%
2,%
1-%S1(%
2)\;addu
\\t%
2,%
2,$
31\\n
\\t%*j
\\t%
2%/"
8279 [(set_attr "type" "jump")
8280 (set_attr "mode" "none")
8281 (set_attr "length" "
24")])
8283 ;; This code assumes that the table index will never be >=
29 bits wide,
8284 ;; which allows the 'sign extend' from SI to DI be a no-op.
8285 (define_insn "casesi_internal_di"
8287 (mem:DI (plus:DI (sign_extend:DI
8288 (mult:SI (match_operand:SI
0 "register_operand" "d")
8290 (label_ref (match_operand
1 "" "")))))
8291 (clobber (match_operand:DI
2 "register_operand" "=d"))
8292 (clobber (reg:DI
31))]
8293 "TARGET_EMBEDDED_PIC"
8296 return "%(bal
\\t%S1\;sll
\\t%
2,%
0,
3\\n%~%S1:\;daddu
\\t%
2,%
2,$
31%)\;
\\
8297 .set macro\;ld
\\t%
2,%
1-%S1(%
2)\;.set nomacro\;daddu
\\t%
2,%
2,$
31\\n
\\t%*j
\\t%
2%/";
8299 "%(bal
\\t%S1\;sll
\\t%
2,%
0,
3\\n%~%S1:\;daddu
\\t%
2,%
2,$
31%)\;
\\
8300 ld
\\t%
2,%
1-%S1(%
2)\;daddu
\\t%
2,%
2,$
31\\n
\\t%*j
\\t%
2%/"
8303 [(set_attr "type" "jump")
8304 (set_attr "mode" "none")
8305 (set_attr "length" "
24")])
8307 ;; For TARGET_ABICALLS, we save the gp in the jmp_buf as well.
8308 ;; While it is possible to either pull it off the stack (in the
8309 ;; o32 case) or recalculate it given t9 and our target label,
8310 ;; it takes
3 or
4 insns to do so.
8312 (define_expand "builtin_setjmp_setup"
8313 [(use (match_operand
0 "register_operand" ""))]
8318 addr = plus_constant (operands[
0], GET_MODE_SIZE (Pmode) *
3);
8319 emit_move_insn (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
8323 ;; Restore the gp that we saved above. Despite the earlier comment, it seems
8324 ;; that older code did recalculate the gp from $
25. Continue to jump through
8325 ;; $
25 for compatibility (we lose nothing by doing so).
8327 (define_expand "builtin_longjmp"
8328 [(use (match_operand
0 "register_operand" "r"))]
8331 /* The elements of the buffer are, in order: */
8332 int W = GET_MODE_SIZE (Pmode);
8333 rtx fp = gen_rtx_MEM (Pmode, operands[
0]);
8334 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[
0],
1*W));
8335 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[
0],
2*W));
8336 rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[
0],
3*W));
8337 rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
8338 /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
8339 The target is bound to be using $
28 as the global pointer
8340 but the current function might not be. */
8341 rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
8343 /* This bit is similar to expand_builtin_longjmp except that it
8344 restores $gp as well. */
8345 emit_move_insn (hard_frame_pointer_rtx, fp);
8346 emit_move_insn (pv, lab);
8347 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
8348 emit_move_insn (gp, gpv);
8349 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
8350 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8351 emit_insn (gen_rtx_USE (VOIDmode, gp));
8352 emit_indirect_jump (pv);
8357 ;; ....................
8359 ;; Function prologue/epilogue
8361 ;; ....................
8364 (define_expand "prologue"
8368 mips_expand_prologue ();
8372 ;; Block any insns from being moved before this point, since the
8373 ;; profiling call to mcount can use various registers that aren't
8374 ;; saved or used to pass arguments.
8376 (define_insn "blockage"
8377 [(unspec_volatile [(const_int
0)] UNSPEC_BLOCKAGE)]
8380 [(set_attr "type" "unknown")
8381 (set_attr "mode" "none")
8382 (set_attr "length" "
0")])
8384 (define_expand "epilogue"
8388 mips_expand_epilogue (false);
8392 (define_expand "sibcall_epilogue"
8396 mips_expand_epilogue (true);
8400 ;; Trivial return. Make it look like a normal return insn as that
8401 ;; allows jump optimizations to work better.
8403 (define_insn "return"
8405 "mips_can_use_return_insn ()"
8407 [(set_attr "type" "jump")
8408 (set_attr "mode" "none")])
8412 (define_insn "return_internal"
8414 (use (match_operand
0 "pmode_register_operand" ""))]
8417 [(set_attr "type" "jump")
8418 (set_attr "mode" "none")])
8420 ;; When generating embedded PIC code we need to get the address of the
8421 ;; current function. This specialized instruction does just that.
8423 (define_insn "get_fnaddr"
8424 [(set (match_operand
0 "register_operand" "=d")
8425 (unspec [(match_operand
1 "" "")] UNSPEC_GET_FNADDR))
8426 (clobber (reg:SI
31))]
8427 "TARGET_EMBEDDED_PIC
8428 && GET_CODE (operands[
1]) == SYMBOL_REF"
8429 "%($LF%= = . +
8\;bal
\t$LF%=\;nop;la
\t%
0,%
1-$LF%=%)\;addu
\t%
0,%
0,$
31"
8430 [(set_attr "type" "call")
8431 (set_attr "mode" "none")
8432 (set_attr "length" "
20")])
8434 ;; This is used in compiling the unwind routines.
8435 (define_expand "eh_return"
8436 [(use (match_operand
0 "general_operand" ""))]
8439 enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
8441 if (GET_MODE (operands[
0]) != gpr_mode)
8442 operands[
0] = convert_to_mode (gpr_mode, operands[
0],
0);
8444 emit_insn (gen_eh_set_lr_di (operands[
0]));
8446 emit_insn (gen_eh_set_lr_si (operands[
0]));
8451 ;; Clobber the return address on the stack. We can't expand this
8452 ;; until we know where it will be put in the stack frame.
8454 (define_insn "eh_set_lr_si"
8455 [(unspec [(match_operand:SI
0 "register_operand" "d")] UNSPEC_EH_RETURN)
8456 (clobber (match_scratch:SI
1 "=&d"))]
8460 (define_insn "eh_set_lr_di"
8461 [(unspec [(match_operand:DI
0 "register_operand" "d")] UNSPEC_EH_RETURN)
8462 (clobber (match_scratch:DI
1 "=&d"))]
8467 [(unspec [(match_operand
0 "register_operand" "")] UNSPEC_EH_RETURN)
8468 (clobber (match_scratch
1 ""))]
8469 "reload_completed && !TARGET_DEBUG_D_MODE"
8472 mips_set_return_address (operands[
0], operands[
1]);
8476 (define_insn "exception_receiver"
8478 (unspec_volatile:SI [(const_int
0)] UNSPEC_EH_RECEIVER))]
8479 "TARGET_ABICALLS && TARGET_OLDABI"
8481 operands[
0] = pic_offset_table_rtx;
8482 operands[
1] = mips_gp_save_slot ();
8483 return mips_output_move (operands[
0], operands[
1]);
8485 [(set_attr "type" "load")
8486 (set_attr "length" "
8")])
8489 ;; ....................
8493 ;; ....................
8495 ;; Instructions to load a call address from the GOT. The address might
8496 ;; point to a function or to a lazy binding stub. In the latter case,
8497 ;; the stub will use the dynamic linker to resolve the function, which
8498 ;; in turn will change the GOT entry to point to the function's real
8501 ;; This means that every call, even pure and constant ones, can
8502 ;; potentially modify the GOT entry. And once a stub has been called,
8503 ;; we must not call it again.
8505 ;; We represent this restriction using an imaginary fixed register that
8506 ;; acts like a GOT version number. By making the register call-clobbered,
8507 ;; we tell the target-independent code that the address could be changed
8508 ;; by any call insn.
8509 (define_insn "load_callsi"
8510 [(set (match_operand:SI
0 "register_operand" "=c")
8511 (unspec:SI [(match_operand:SI
1 "register_operand" "r")
8512 (match_operand:SI
2 "immediate_operand" "")
8513 (reg:SI FAKE_CALL_REGNO)]
8517 [(set_attr "type" "load")
8518 (set_attr "length" "
4")])
8520 (define_insn "load_calldi"
8521 [(set (match_operand:DI
0 "register_operand" "=c")
8522 (unspec:DI [(match_operand:DI
1 "register_operand" "r")
8523 (match_operand:DI
2 "immediate_operand" "")
8524 (reg:DI FAKE_CALL_REGNO)]
8528 [(set_attr "type" "load")
8529 (set_attr "length" "
4")])
8531 ;; Sibling calls. All these patterns use jump instructions.
8533 ;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
8534 ;; addresses if a direct jump is acceptable. Since the 'S' constraint
8535 ;; is defined in terms of call_insn_operand, the same is true of the
8538 ;; When we use an indirect jump, we need a register that will be
8539 ;; preserved by the epilogue. Since TARGET_ABICALLS forces us to
8540 ;; use $
25 for this purpose -- and $
25 is never clobbered by the
8541 ;; epilogue -- we might as well use it for !TARGET_ABICALLS as well.
8543 (define_expand "sibcall"
8544 [(parallel [(call (match_operand
0 "" "")
8545 (match_operand
1 "" ""))
8546 (use (match_operand
2 "" "")) ;; next_arg_reg
8547 (use (match_operand
3 "" ""))])] ;; struct_value_size_rtx
8550 mips_expand_call (
0, XEXP (operands[
0],
0), operands[
1], operands[
2], true);
8554 (define_insn "sibcall_internal"
8555 [(call (mem:SI (match_operand
0 "call_insn_operand" "j,S"))
8556 (match_operand
1 "" ""))]
8557 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
8561 [(set_attr "type" "call")])
8563 (define_expand "sibcall_value"
8564 [(parallel [(set (match_operand
0 "" "")
8565 (call (match_operand
1 "" "")
8566 (match_operand
2 "" "")))
8567 (use (match_operand
3 "" ""))])] ;; next_arg_reg
8570 mips_expand_call (operands[
0], XEXP (operands[
1],
0),
8571 operands[
2], operands[
3], true);
8575 (define_insn "sibcall_value_internal"
8576 [(set (match_operand
0 "register_operand" "=df,df")
8577 (call (mem:SI (match_operand
1 "call_insn_operand" "j,S"))
8578 (match_operand
2 "" "")))]
8579 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
8583 [(set_attr "type" "call")])
8585 (define_insn "sibcall_value_multiple_internal"
8586 [(set (match_operand
0 "register_operand" "=df,df")
8587 (call (mem:SI (match_operand
1 "call_insn_operand" "j,S"))
8588 (match_operand
2 "" "")))
8589 (set (match_operand
3 "register_operand" "=df,df")
8590 (call (mem:SI (match_dup
1))
8592 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
8596 [(set_attr "type" "call")])
8598 (define_expand "call"
8599 [(parallel [(call (match_operand
0 "" "")
8600 (match_operand
1 "" ""))
8601 (use (match_operand
2 "" "")) ;; next_arg_reg
8602 (use (match_operand
3 "" ""))])] ;; struct_value_size_rtx
8605 mips_expand_call (
0, XEXP (operands[
0],
0), operands[
1], operands[
2], false);
8609 ;; This instruction directly corresponds to an assembly-language "jal".
8610 ;; There are four cases:
8613 ;; Both symbolic and register destinations are OK. The pattern
8614 ;; always expands to a single mips instruction.
8616 ;; - -mabicalls/-mno-explicit-relocs:
8617 ;; Again, both symbolic and register destinations are OK.
8618 ;; The call is treated as a multi-instruction black box.
8620 ;; - -mabicalls/-mexplicit-relocs with n32 or n64:
8621 ;; Only "jal $
25" is allowed. This expands to a single "jalr $
25"
8624 ;; - -mabicalls/-mexplicit-relocs with o32 or o64:
8625 ;; Only "jal $
25" is allowed. The call is actually two instructions:
8626 ;; "jalr $
25" followed by an insn to reload $gp.
8628 ;; In the last case, we can generate the individual instructions with
8629 ;; a define_split. There are several things to be wary of:
8631 ;; - We can't expose the load of $gp before reload. If we did,
8632 ;; it might get removed as dead, but reload can introduce new
8633 ;; uses of $gp by rematerializing constants.
8635 ;; - We shouldn't restore $gp after calls that never return.
8636 ;; It isn't valid to insert instructions between a noreturn
8637 ;; call and the following barrier.
8639 ;; - The splitter deliberately changes the liveness of $gp. The unsplit
8640 ;; instruction preserves $gp and so have no effect on its liveness.
8641 ;; But once we generate the separate insns, it becomes obvious that
8642 ;; $gp is not live on entry to the call.
8644 ;; ??? The operands[
2] = insn check is a hack to make the original insn
8645 ;; available to the splitter.
8646 (define_insn_and_split "call_internal"
8647 [(call (mem:SI (match_operand
0 "call_insn_operand" "c,S"))
8648 (match_operand
1 "" ""))
8649 (clobber (reg:SI
31))]
8651 { return TARGET_SPLIT_CALLS ? "#" : "%*jal
\t%
0%/"; }
8652 "reload_completed && TARGET_SPLIT_CALLS && (operands[
2] = insn)"
8655 emit_call_insn (gen_call_split (operands[
0], operands[
1]));
8656 if (!find_reg_note (operands[
2], REG_NORETURN,
0))
8657 emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ());
8660 [(set_attr "jal" "indirect,direct")
8661 (set_attr "extended_mips16" "no,yes")])
8663 (define_insn "call_split"
8664 [(call (mem:SI (match_operand
0 "call_insn_operand" "c"))
8665 (match_operand
1 "" ""))
8666 (clobber (reg:SI
31))
8667 (clobber (reg:SI
28))]
8668 "TARGET_SPLIT_CALLS"
8670 [(set_attr "type" "call")])
8672 (define_expand "call_value"
8673 [(parallel [(set (match_operand
0 "" "")
8674 (call (match_operand
1 "" "")
8675 (match_operand
2 "" "")))
8676 (use (match_operand
3 "" ""))])] ;; next_arg_reg
8679 mips_expand_call (operands[
0], XEXP (operands[
1],
0),
8680 operands[
2], operands[
3], false);
8684 ;; See comment for call_internal.
8685 (define_insn_and_split "call_value_internal"
8686 [(set (match_operand
0 "register_operand" "=df,df")
8687 (call (mem:SI (match_operand
1 "call_insn_operand" "c,S"))
8688 (match_operand
2 "" "")))
8689 (clobber (reg:SI
31))]
8691 { return TARGET_SPLIT_CALLS ? "#" : "%*jal
\t%
1%/"; }
8692 "reload_completed && TARGET_SPLIT_CALLS && (operands[
3] = insn)"
8695 emit_call_insn (gen_call_value_split (operands[
0], operands[
1],
8697 if (!find_reg_note (operands[
3], REG_NORETURN,
0))
8698 emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ());
8701 [(set_attr "jal" "indirect,direct")
8702 (set_attr "extended_mips16" "no,yes")])
8704 (define_insn "call_value_split"
8705 [(set (match_operand
0 "register_operand" "=df")
8706 (call (mem:SI (match_operand
1 "call_insn_operand" "c"))
8707 (match_operand
2 "" "")))
8708 (clobber (reg:SI
31))
8709 (clobber (reg:SI
28))]
8710 "TARGET_SPLIT_CALLS"
8712 [(set_attr "type" "call")])
8714 ;; See comment for call_internal.
8715 (define_insn_and_split "call_value_multiple_internal"
8716 [(set (match_operand
0 "register_operand" "=df,df")
8717 (call (mem:SI (match_operand
1 "call_insn_operand" "c,S"))
8718 (match_operand
2 "" "")))
8719 (set (match_operand
3 "register_operand" "=df,df")
8720 (call (mem:SI (match_dup
1))
8722 (clobber (reg:SI
31))]
8724 { return TARGET_SPLIT_CALLS ? "#" : "%*jal
\t%
1%/"; }
8725 "reload_completed && TARGET_SPLIT_CALLS && (operands[
4] = insn)"
8728 emit_call_insn (gen_call_value_multiple_split (operands[
0], operands[
1],
8729 operands[
2], operands[
3]));
8730 if (!find_reg_note (operands[
4], REG_NORETURN,
0))
8731 emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ());
8734 [(set_attr "jal" "indirect,direct")
8735 (set_attr "extended_mips16" "no,yes")])
8737 (define_insn "call_value_multiple_split"
8738 [(set (match_operand
0 "register_operand" "=df")
8739 (call (mem:SI (match_operand
1 "call_insn_operand" "c"))
8740 (match_operand
2 "" "")))
8741 (set (match_operand
3 "register_operand" "=df")
8742 (call (mem:SI (match_dup
1))
8744 (clobber (reg:SI
31))
8745 (clobber (reg:SI
28))]
8746 "TARGET_SPLIT_CALLS"
8748 [(set_attr "type" "call")])
8750 ;; Call subroutine returning any type.
8752 (define_expand "untyped_call"
8753 [(parallel [(call (match_operand
0 "" "")
8755 (match_operand
1 "" "")
8756 (match_operand
2 "" "")])]
8761 emit_call_insn (GEN_CALL (operands[
0], const0_rtx, NULL, const0_rtx));
8763 for (i =
0; i < XVECLEN (operands[
2],
0); i++)
8765 rtx set = XVECEXP (operands[
2],
0, i);
8766 emit_move_insn (SET_DEST (set), SET_SRC (set));
8769 emit_insn (gen_blockage ());
8774 ;; ....................
8778 ;; ....................
8782 (define_expand "prefetch"
8783 [(prefetch (match_operand
0 "address_operand" "")
8784 (match_operand
1 "const_int_operand" "")
8785 (match_operand
2 "const_int_operand" ""))]
8788 if (symbolic_operand (operands[
0], GET_MODE (operands[
0])))
8789 operands[
0] = force_reg (GET_MODE (operands[
0]), operands[
0]);
8792 (define_insn "prefetch_si_address"
8793 [(prefetch (plus:SI (match_operand:SI
0 "register_operand" "r")
8794 (match_operand:SI
3 "const_int_operand" "I"))
8795 (match_operand:SI
1 "const_int_operand" "n")
8796 (match_operand:SI
2 "const_int_operand" "n"))]
8797 "ISA_HAS_PREFETCH && Pmode == SImode"
8798 { return mips_emit_prefetch (operands); }
8799 [(set_attr "type" "prefetch")])
8801 (define_insn "prefetch_indexed_si"
8802 [(prefetch (plus:SI (match_operand:SI
0 "register_operand" "r")
8803 (match_operand:SI
3 "register_operand" "r"))
8804 (match_operand:SI
1 "const_int_operand" "n")
8805 (match_operand:SI
2 "const_int_operand" "n"))]
8806 "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == SImode"
8807 { return mips_emit_prefetch (operands); }
8808 [(set_attr "type" "prefetchx")])
8810 (define_insn "prefetch_si"
8811 [(prefetch (match_operand:SI
0 "register_operand" "r")
8812 (match_operand:SI
1 "const_int_operand" "n")
8813 (match_operand:SI
2 "const_int_operand" "n"))]
8814 "ISA_HAS_PREFETCH && Pmode == SImode"
8816 operands[
3] = const0_rtx;
8817 return mips_emit_prefetch (operands);
8819 [(set_attr "type" "prefetch")])
8821 (define_insn "prefetch_di_address"
8822 [(prefetch (plus:DI (match_operand:DI
0 "register_operand" "r")
8823 (match_operand:DI
3 "const_int_operand" "I"))
8824 (match_operand:DI
1 "const_int_operand" "n")
8825 (match_operand:DI
2 "const_int_operand" "n"))]
8826 "ISA_HAS_PREFETCH && Pmode == DImode"
8827 { return mips_emit_prefetch (operands); }
8828 [(set_attr "type" "prefetch")])
8830 (define_insn "prefetch_indexed_di"
8831 [(prefetch (plus:DI (match_operand:DI
0 "register_operand" "r")
8832 (match_operand:DI
3 "register_operand" "r"))
8833 (match_operand:DI
1 "const_int_operand" "n")
8834 (match_operand:DI
2 "const_int_operand" "n"))]
8835 "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == DImode"
8836 { return mips_emit_prefetch (operands); }
8837 [(set_attr "type" "prefetchx")])
8839 (define_insn "prefetch_di"
8840 [(prefetch (match_operand:DI
0 "register_operand" "r")
8841 (match_operand:DI
1 "const_int_operand" "n")
8842 (match_operand:DI
2 "const_int_operand" "n"))]
8843 "ISA_HAS_PREFETCH && Pmode == DImode"
8845 operands[
3] = const0_rtx;
8846 return mips_emit_prefetch (operands);
8848 [(set_attr "type" "prefetch")])
8854 [(set_attr "type" "nop")
8855 (set_attr "mode" "none")])
8857 ;; Like nop, but commented out when outside a .set noreorder block.
8858 (define_insn "hazard_nop"
8867 [(set_attr "type" "arith")])
8869 ;; MIPS4 Conditional move instructions.
8872 [(set (match_operand:SI
0 "register_operand" "=d,d")
8874 (match_operator
4 "equality_op"
8875 [(match_operand:SI
1 "register_operand" "d,d")
8877 (match_operand:SI
2 "reg_or_0_operand" "dJ,
0")
8878 (match_operand:SI
3 "reg_or_0_operand" "
0,dJ")))]
8879 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
8883 [(set_attr "type" "condmove")
8884 (set_attr "mode" "SI")])
8887 [(set (match_operand:SI
0 "register_operand" "=d,d")
8889 (match_operator
4 "equality_op"
8890 [(match_operand:DI
1 "register_operand" "d,d")
8892 (match_operand:SI
2 "reg_or_0_operand" "dJ,
0")
8893 (match_operand:SI
3 "reg_or_0_operand" "
0,dJ")))]
8894 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
8898 [(set_attr "type" "condmove")
8899 (set_attr "mode" "SI")])
8902 [(set (match_operand:SI
0 "register_operand" "=d,d")
8904 (match_operator
3 "equality_op" [(match_operand:CC
4
8908 (match_operand:SI
1 "reg_or_0_operand" "dJ,
0")
8909 (match_operand:SI
2 "reg_or_0_operand" "
0,dJ")))]
8910 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
8914 [(set_attr "type" "condmove")
8915 (set_attr "mode" "SI")])
8918 [(set (match_operand:DI
0 "register_operand" "=d,d")
8920 (match_operator
4 "equality_op"
8921 [(match_operand:SI
1 "register_operand" "d,d")
8923 (match_operand:DI
2 "reg_or_0_operand" "dJ,
0")
8924 (match_operand:DI
3 "reg_or_0_operand" "
0,dJ")))]
8925 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
8929 [(set_attr "type" "condmove")
8930 (set_attr "mode" "DI")])
8933 [(set (match_operand:DI
0 "register_operand" "=d,d")
8935 (match_operator
4 "equality_op"
8936 [(match_operand:DI
1 "register_operand" "d,d")
8938 (match_operand:DI
2 "reg_or_0_operand" "dJ,
0")
8939 (match_operand:DI
3 "reg_or_0_operand" "
0,dJ")))]
8940 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
8944 [(set_attr "type" "condmove")
8945 (set_attr "mode" "DI")])
8948 [(set (match_operand:DI
0 "register_operand" "=d,d")
8950 (match_operator
3 "equality_op" [(match_operand:CC
4
8954 (match_operand:DI
1 "reg_or_0_operand" "dJ,
0")
8955 (match_operand:DI
2 "reg_or_0_operand" "
0,dJ")))]
8956 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_64BIT"
8960 [(set_attr "type" "condmove")
8961 (set_attr "mode" "DI")])
8964 [(set (match_operand:SF
0 "register_operand" "=f,f")
8966 (match_operator
4 "equality_op"
8967 [(match_operand:SI
1 "register_operand" "d,d")
8969 (match_operand:SF
2 "register_operand" "f,
0")
8970 (match_operand:SF
3 "register_operand" "
0,f")))]
8971 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
8975 [(set_attr "type" "condmove")
8976 (set_attr "mode" "SF")])
8979 [(set (match_operand:SF
0 "register_operand" "=f,f")
8981 (match_operator
4 "equality_op"
8982 [(match_operand:DI
1 "register_operand" "d,d")
8984 (match_operand:SF
2 "register_operand" "f,
0")
8985 (match_operand:SF
3 "register_operand" "
0,f")))]
8986 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
8990 [(set_attr "type" "condmove")
8991 (set_attr "mode" "SF")])
8994 [(set (match_operand:SF
0 "register_operand" "=f,f")
8996 (match_operator
3 "equality_op" [(match_operand:CC
4
9000 (match_operand:SF
1 "register_operand" "f,
0")
9001 (match_operand:SF
2 "register_operand" "
0,f")))]
9002 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
9006 [(set_attr "type" "condmove")
9007 (set_attr "mode" "SF")])
9010 [(set (match_operand:DF
0 "register_operand" "=f,f")
9012 (match_operator
4 "equality_op"
9013 [(match_operand:SI
1 "register_operand" "d,d")
9015 (match_operand:DF
2 "register_operand" "f,
0")
9016 (match_operand:DF
3 "register_operand" "
0,f")))]
9017 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9021 [(set_attr "type" "condmove")
9022 (set_attr "mode" "DF")])
9025 [(set (match_operand:DF
0 "register_operand" "=f,f")
9027 (match_operator
4 "equality_op"
9028 [(match_operand:DI
1 "register_operand" "d,d")
9030 (match_operand:DF
2 "register_operand" "f,
0")
9031 (match_operand:DF
3 "register_operand" "
0,f")))]
9032 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9036 [(set_attr "type" "condmove")
9037 (set_attr "mode" "DF")])
9040 [(set (match_operand:DF
0 "register_operand" "=f,f")
9042 (match_operator
3 "equality_op" [(match_operand:CC
4
9046 (match_operand:DF
1 "register_operand" "f,
0")
9047 (match_operand:DF
2 "register_operand" "
0,f")))]
9048 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9052 [(set_attr "type" "condmove")
9053 (set_attr "mode" "DF")])
9055 ;; These are the main define_expand's used to make conditional moves.
9057 (define_expand "movsicc"
9058 [(set (match_dup
4) (match_operand
1 "comparison_operator" ""))
9059 (set (match_operand:SI
0 "register_operand" "")
9060 (if_then_else:SI (match_dup
5)
9061 (match_operand:SI
2 "reg_or_0_operand" "")
9062 (match_operand:SI
3 "reg_or_0_operand" "")))]
9063 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
9065 gen_conditional_move (operands);
9069 (define_expand "movdicc"
9070 [(set (match_dup
4) (match_operand
1 "comparison_operator" ""))
9071 (set (match_operand:DI
0 "register_operand" "")
9072 (if_then_else:DI (match_dup
5)
9073 (match_operand:DI
2 "reg_or_0_operand" "")
9074 (match_operand:DI
3 "reg_or_0_operand" "")))]
9075 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
9077 gen_conditional_move (operands);
9081 (define_expand "movsfcc"
9082 [(set (match_dup
4) (match_operand
1 "comparison_operator" ""))
9083 (set (match_operand:SF
0 "register_operand" "")
9084 (if_then_else:SF (match_dup
5)
9085 (match_operand:SF
2 "register_operand" "")
9086 (match_operand:SF
3 "register_operand" "")))]
9087 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
9089 gen_conditional_move (operands);
9093 (define_expand "movdfcc"
9094 [(set (match_dup
4) (match_operand
1 "comparison_operator" ""))
9095 (set (match_operand:DF
0 "register_operand" "")
9096 (if_then_else:DF (match_dup
5)
9097 (match_operand:DF
2 "register_operand" "")
9098 (match_operand:DF
3 "register_operand" "")))]
9099 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9101 gen_conditional_move (operands);
9106 ;; ....................
9108 ;; mips16 inline constant tables
9110 ;; ....................
9113 (define_insn "consttable_qi"
9114 [(unspec_volatile [(match_operand:QI
0 "consttable_operand" "=g")]
9115 UNSPEC_CONSTTABLE_QI)]
9118 assemble_integer (operands[
0],
1, BITS_PER_UNIT,
1);
9121 [(set_attr "type" "unknown")
9122 (set_attr "mode" "QI")
9123 (set_attr "length" "
8")])
9125 (define_insn "consttable_hi"
9126 [(unspec_volatile [(match_operand:HI
0 "consttable_operand" "=g")]
9127 UNSPEC_CONSTTABLE_HI)]
9130 assemble_integer (operands[
0],
2, BITS_PER_UNIT *
2,
1);
9133 [(set_attr "type" "unknown")
9134 (set_attr "mode" "HI")
9135 (set_attr "length" "
8")])
9137 (define_insn "consttable_si"
9138 [(unspec_volatile [(match_operand:SI
0 "consttable_operand" "=g")]
9139 UNSPEC_CONSTTABLE_SI)]
9142 assemble_integer (operands[
0],
4, BITS_PER_UNIT *
4,
1);
9145 [(set_attr "type" "unknown")
9146 (set_attr "mode" "SI")
9147 (set_attr "length" "
8")])
9149 (define_insn "consttable_di"
9150 [(unspec_volatile [(match_operand:DI
0 "consttable_operand" "=g")]
9151 UNSPEC_CONSTTABLE_DI)]
9154 assemble_integer (operands[
0],
8, BITS_PER_UNIT *
8,
1);
9157 [(set_attr "type" "unknown")
9158 (set_attr "mode" "DI")
9159 (set_attr "length" "
16")])
9161 (define_insn "consttable_sf"
9162 [(unspec_volatile [(match_operand:SF
0 "consttable_operand" "=g")]
9163 UNSPEC_CONSTTABLE_SF)]
9168 if (GET_CODE (operands[
0]) != CONST_DOUBLE)
9170 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[
0]);
9171 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9174 [(set_attr "type" "unknown")
9175 (set_attr "mode" "SF")
9176 (set_attr "length" "
8")])
9178 (define_insn "consttable_df"
9179 [(unspec_volatile [(match_operand:DF
0 "consttable_operand" "=g")]
9180 UNSPEC_CONSTTABLE_DF)]
9185 if (GET_CODE (operands[
0]) != CONST_DOUBLE)
9187 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[
0]);
9188 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9191 [(set_attr "type" "unknown")
9192 (set_attr "mode" "DF")
9193 (set_attr "length" "
16")])
9195 (define_insn "align_2"
9196 [(unspec_volatile [(const_int
0)] UNSPEC_ALIGN_2)]
9199 [(set_attr "type" "unknown")
9200 (set_attr "mode" "HI")
9201 (set_attr "length" "
8")])
9203 (define_insn "align_4"
9204 [(unspec_volatile [(const_int
0)] UNSPEC_ALIGN_4)]
9207 [(set_attr "type" "unknown")
9208 (set_attr "mode" "SI")
9209 (set_attr "length" "
8")])
9211 (define_insn "align_8"
9212 [(unspec_volatile [(const_int
0)] UNSPEC_ALIGN_8)]
9215 [(set_attr "type" "unknown")
9216 (set_attr "mode" "DI")
9217 (set_attr "length" "
12")])
9220 ;; ....................
9224 ;; ....................
9227 ;; On the mips16, reload will sometimes decide that a pseudo register
9228 ;; should go into $
24, and then later on have to reload that register.
9229 ;; When that happens, we get a load of a general register followed by
9230 ;; a move from the general register to $
24 followed by a branch.
9231 ;; These peepholes catch the common case, and fix it to just use the
9232 ;; general register for the branch.
9235 [(set (match_operand:SI
0 "register_operand" "=t")
9236 (match_operand:SI
1 "register_operand" "d"))
9238 (if_then_else (match_operator:SI
2 "equality_op" [(match_dup
0)
9240 (match_operand
3 "pc_or_label_operand" "")
9241 (match_operand
4 "pc_or_label_operand" "")))]
9243 && GET_CODE (operands[
0]) == REG
9244 && REGNO (operands[
0]) ==
24
9245 && dead_or_set_p (insn, operands[
0])
9246 && GET_CODE (operands[
1]) == REG
9247 && M16_REG_P (REGNO (operands[
1]))"
9249 if (operands[
3] != pc_rtx)
9250 return "b%C2z
\t%
1,%
3";
9252 return "b%N2z
\t%
1,%
4";
9254 [(set_attr "type" "branch")
9255 (set_attr "mode" "none")
9256 (set_attr "length" "
8")])
9259 [(set (match_operand:DI
0 "register_operand" "=t")
9260 (match_operand:DI
1 "register_operand" "d"))
9262 (if_then_else (match_operator:DI
2 "equality_op" [(match_dup
0)
9264 (match_operand
3 "pc_or_label_operand" "")
9265 (match_operand
4 "pc_or_label_operand" "")))]
9266 "TARGET_MIPS16 && TARGET_64BIT
9267 && GET_CODE (operands[
0]) == REG
9268 && REGNO (operands[
0]) ==
24
9269 && dead_or_set_p (insn, operands[
0])
9270 && GET_CODE (operands[
1]) == REG
9271 && M16_REG_P (REGNO (operands[
1]))"
9273 if (operands[
3] != pc_rtx)
9274 return "b%C2z
\t%
1,%
3";
9276 return "b%N2z
\t%
1,%
4";
9278 [(set_attr "type" "branch")
9279 (set_attr "mode" "none")
9280 (set_attr "length" "
8")])
9282 ;; We can also have the reverse reload: reload will spill $
24 into
9283 ;; another register, and then do a branch on that register when it
9284 ;; could have just stuck with $
24.
9287 [(set (match_operand:SI
0 "register_operand" "=d")
9288 (match_operand:SI
1 "register_operand" "t"))
9290 (if_then_else (match_operator:SI
2 "equality_op" [(match_dup
0)
9292 (match_operand
3 "pc_or_label_operand" "")
9293 (match_operand
4 "pc_or_label_operand" "")))]
9295 && GET_CODE (operands[
1]) == REG
9296 && REGNO (operands[
1]) ==
24
9297 && GET_CODE (operands[
0]) == REG
9298 && M16_REG_P (REGNO (operands[
0]))
9299 && dead_or_set_p (insn, operands[
0])"
9301 if (operands[
3] != pc_rtx)
9302 return "bt%C2z
\t%
3";
9304 return "bt%N2z
\t%
4";
9306 [(set_attr "type" "branch")
9307 (set_attr "mode" "none")
9308 (set_attr "length" "
8")])
9311 [(set (match_operand:DI
0 "register_operand" "=d")
9312 (match_operand:DI
1 "register_operand" "t"))
9314 (if_then_else (match_operator:DI
2 "equality_op" [(match_dup
0)
9316 (match_operand
3 "pc_or_label_operand" "")
9317 (match_operand
4 "pc_or_label_operand" "")))]
9318 "TARGET_MIPS16 && TARGET_64BIT
9319 && GET_CODE (operands[
1]) == REG
9320 && REGNO (operands[
1]) ==
24
9321 && GET_CODE (operands[
0]) == REG
9322 && M16_REG_P (REGNO (operands[
0]))
9323 && dead_or_set_p (insn, operands[
0])"
9325 if (operands[
3] != pc_rtx)
9326 return "bt%C2z
\t%
3";
9328 return "bt%N2z
\t%
4";
9330 [(set_attr "type" "branch")
9331 (set_attr "mode" "none")
9332 (set_attr "length" "
8")])
9335 [(match_operand
0 "small_data_pattern" "")]
9338 { operands[
0] = mips_rewrite_small_data (operands[
0]); })