1 ;; Mips.md Machine Description for MIPS based processors
2 ;; Copyright (C) 1989-2014 Free Software Foundation, Inc.
3 ;; Contributed by A. Lichnewsky, lich@inria.inria.fr
4 ;; Changes by Michael Meissner, meissner@osf.org
5 ;; 64-bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
6 ;; Brendan Eich, brendan@microunity.com.
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>.
24 (define_enum "processor" [
72 (define_c_enum "unspec" [
73 ;; Unaligned accesses.
79 ;; Integer operations that are too cumbersome to describe directly.
84 ;; Floating-point moves.
91 ;; Floating-point environment.
104 UNSPEC_POTENTIAL_CPRESTORE
109 UNSPEC_SET_GOT_VERSION
110 UNSPEC_UPDATE_GOT_VERSION
112 ;; Symbolic accesses.
117 UNSPEC_UNSHIFTED_HIGH
119 ;; MIPS16 constant pools.
121 UNSPEC_CONSTTABLE_INT
122 UNSPEC_CONSTTABLE_FLOAT
124 ;; Blockage and synchronisation.
131 ;; Cache manipulation.
133 UNSPEC_R10K_CACHE_BARRIER
135 ;; Interrupt handling.
143 ;; Used in a call expression in place of args_size. It's present for PIC
144 ;; indirect calls where it contains args_size and the function symbol.
147 ;; MIPS16 casesi jump table dispatch.
148 UNSPEC_CASESI_DISPATCH
151 UNSPEC_PROBE_STACK_RANGE
155 [(TLS_GET_TP_REGNUM 3)
159 (PIC_FUNCTION_ADDR_REGNUM 25)
160 (RETURN_ADDR_REGNUM 31)
161 (CPRESTORE_SLOT_REGNUM 76)
162 (GOT_VERSION_REGNUM 79)
164 ;; PIC long branch sequences are never longer than 100 bytes.
165 (MAX_PIC_BRANCH_LENGTH 100)
169 (include "predicates.md")
170 (include "constraints.md")
172 ;; ....................
176 ;; ....................
178 (define_attr "got" "unset,xgot_high,load"
179 (const_string "unset"))
181 ;; For jal instructions, this attribute is DIRECT when the target address
182 ;; is symbolic and INDIRECT when it is a register.
183 (define_attr "jal" "unset,direct,indirect"
184 (const_string "unset"))
186 ;; This attribute is YES if the instruction is a jal macro (not a
187 ;; real jal instruction).
189 ;; jal is always a macro for TARGET_CALL_CLOBBERED_GP because it includes
190 ;; an instruction to restore $gp. Direct jals are also macros for
191 ;; !TARGET_ABSOLUTE_JUMPS because they first load the target address
193 (define_attr "jal_macro" "no,yes"
194 (cond [(eq_attr "jal" "direct")
195 (symbol_ref "(TARGET_CALL_CLOBBERED_GP || !TARGET_ABSOLUTE_JUMPS
196 ? JAL_MACRO_YES : JAL_MACRO_NO)")
197 (eq_attr "jal" "indirect")
198 (symbol_ref "(TARGET_CALL_CLOBBERED_GP
199 ? JAL_MACRO_YES : JAL_MACRO_NO)")]
200 (const_string "no")))
202 ;; Classification of moves, extensions and truncations. Most values
203 ;; are as for "type" (see below) but there are also the following
204 ;; move-specific values:
206 ;; constN move an N-constraint integer into a MIPS16 register
207 ;; sll0 "sll DEST,SRC,0", which on 64-bit targets is guaranteed
208 ;; to produce a sign-extended DEST, even if SRC is not
209 ;; properly sign-extended
210 ;; ext_ins EXT, DEXT, INS or DINS instruction
211 ;; andi a single ANDI instruction
212 ;; loadpool move a constant into a MIPS16 register by loading it
214 ;; shift_shift a shift left followed by a shift right
216 ;; This attribute is used to determine the instruction's length and
217 ;; scheduling type. For doubleword moves, the attribute always describes
218 ;; the split instructions; in some cases, it is more appropriate for the
219 ;; scheduling type to be "multi" instead.
220 (define_attr "move_type"
221 "unknown,load,fpload,store,fpstore,mtc,mfc,mtlo,mflo,imul,move,fmove,
222 const,constN,signext,ext_ins,logical,arith,sll0,andi,loadpool,
224 (const_string "unknown"))
226 (define_attr "alu_type" "unknown,add,sub,not,nor,and,or,xor"
227 (const_string "unknown"))
229 ;; Main data type used by the insn
230 (define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF,FPSW"
231 (const_string "unknown"))
233 ;; True if the main data type is twice the size of a word.
234 (define_attr "dword_mode" "no,yes"
235 (cond [(and (eq_attr "mode" "DI,DF")
236 (not (match_test "TARGET_64BIT")))
239 (and (eq_attr "mode" "TI,TF")
240 (match_test "TARGET_64BIT"))
241 (const_string "yes")]
242 (const_string "no")))
244 ;; Attributes describing a sync loop. These loops have the form:
246 ;; if (RELEASE_BARRIER == YES) sync
248 ;; if ((OLDVAL & INCLUSIVE_MASK) != REQUIRED_OLDVAL) goto 2
249 ;; CMP = 0 [delay slot]
250 ;; $TMP1 = OLDVAL & EXCLUSIVE_MASK
251 ;; $TMP2 = INSN1 (OLDVAL, INSN1_OP2)
252 ;; $TMP3 = INSN2 ($TMP2, INCLUSIVE_MASK)
253 ;; $AT |= $TMP1 | $TMP3
254 ;; if (!commit (*MEM = $AT)) goto 1.
255 ;; if (INSN1 != MOVE && INSN1 != LI) NEWVAL = $TMP3 [delay slot]
257 ;; if (ACQUIRE_BARRIER == YES) sync
260 ;; where "$" values are temporaries and where the other values are
261 ;; specified by the attributes below. Values are specified as operand
262 ;; numbers and insns are specified as enums. If no operand number is
263 ;; specified, the following values are used instead:
268 ;; - INCLUSIVE_MASK: -1
269 ;; - REQUIRED_OLDVAL: OLDVAL & INCLUSIVE_MASK
270 ;; - EXCLUSIVE_MASK: 0
272 ;; MEM and INSN1_OP2 are required.
274 ;; Ideally, the operand attributes would be integers, with -1 meaning "none",
275 ;; but the gen* programs don't yet support that.
276 (define_attr "sync_mem" "none,0,1,2,3,4,5" (const_string "none"))
277 (define_attr "sync_oldval" "none,0,1,2,3,4,5" (const_string "none"))
278 (define_attr "sync_cmp" "none,0,1,2,3,4,5" (const_string "none"))
279 (define_attr "sync_newval" "none,0,1,2,3,4,5" (const_string "none"))
280 (define_attr "sync_inclusive_mask" "none,0,1,2,3,4,5" (const_string "none"))
281 (define_attr "sync_exclusive_mask" "none,0,1,2,3,4,5" (const_string "none"))
282 (define_attr "sync_required_oldval" "none,0,1,2,3,4,5" (const_string "none"))
283 (define_attr "sync_insn1_op2" "none,0,1,2,3,4,5" (const_string "none"))
284 (define_attr "sync_insn1" "move,li,addu,addiu,subu,and,andi,or,ori,xor,xori"
285 (const_string "move"))
286 (define_attr "sync_insn2" "nop,and,xor,not"
287 (const_string "nop"))
288 ;; Memory model specifier.
289 ;; "0"-"9" values specify the operand that stores the memory model value.
290 ;; "10" specifies MEMMODEL_ACQ_REL,
291 ;; "11" specifies MEMMODEL_ACQUIRE.
292 (define_attr "sync_memmodel" "" (const_int 10))
294 ;; Accumulator operand for madd patterns.
295 (define_attr "accum_in" "none,0,1,2,3,4,5" (const_string "none"))
297 ;; Classification of each insn.
298 ;; branch conditional branch
299 ;; jump unconditional jump
300 ;; call unconditional call
301 ;; load load instruction(s)
302 ;; fpload floating point load
303 ;; fpidxload floating point indexed load
304 ;; store store instruction(s)
305 ;; fpstore floating point store
306 ;; fpidxstore floating point indexed store
307 ;; prefetch memory prefetch (register + offset)
308 ;; prefetchx memory indexed prefetch (register + register)
309 ;; condmove conditional moves
310 ;; mtc transfer to coprocessor
311 ;; mfc transfer from coprocessor
312 ;; mthi transfer to a hi register
313 ;; mtlo transfer to a lo register
314 ;; mfhi transfer from a hi register
315 ;; mflo transfer from a lo register
316 ;; const load constant
317 ;; arith integer arithmetic instructions
318 ;; logical integer logical instructions
319 ;; shift integer shift instructions
320 ;; slt set less than instructions
321 ;; signext sign extend instructions
322 ;; clz the clz and clo instructions
323 ;; pop the pop instruction
324 ;; trap trap if instructions
325 ;; imul integer multiply 2 operands
326 ;; imul3 integer multiply 3 operands
327 ;; imul3nc integer multiply 3 operands without clobbering HI/LO
328 ;; imadd integer multiply-add
329 ;; idiv integer divide 2 operands
330 ;; idiv3 integer divide 3 operands
331 ;; move integer register move ({,D}ADD{,U} with rt = 0)
332 ;; fmove floating point register move
333 ;; fadd floating point add/subtract
334 ;; fmul floating point multiply
335 ;; fmadd floating point multiply-add
336 ;; fdiv floating point divide
337 ;; frdiv floating point reciprocal divide
338 ;; frdiv1 floating point reciprocal divide step 1
339 ;; frdiv2 floating point reciprocal divide step 2
340 ;; fabs floating point absolute value
341 ;; fneg floating point negation
342 ;; fcmp floating point compare
343 ;; fcvt floating point convert
344 ;; fsqrt floating point square root
345 ;; frsqrt floating point reciprocal square root
346 ;; frsqrt1 floating point reciprocal square root step1
347 ;; frsqrt2 floating point reciprocal square root step2
348 ;; dspmac DSP MAC instructions not saturating the accumulator
349 ;; dspmacsat DSP MAC instructions that saturate the accumulator
350 ;; accext DSP accumulator extract instructions
351 ;; accmod DSP accumulator modify instructions
352 ;; dspalu DSP ALU instructions not saturating the result
353 ;; dspalusat DSP ALU instructions that saturate the result
354 ;; multi multiword sequence (or user asm statements)
355 ;; atomic atomic memory update instruction
356 ;; syncloop memory atomic operation implemented as a sync loop
358 ;; ghost an instruction that produces no real code
359 ;; multimem microMIPS multiword load and store
361 "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,
362 prefetch,prefetchx,condmove,mtc,mfc,mthi,mtlo,mfhi,mflo,const,arith,logical,
363 shift,slt,signext,clz,pop,trap,imul,imul3,imul3nc,imadd,idiv,idiv3,move,
364 fmove,fadd,fmul,fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt,
365 frsqrt,frsqrt1,frsqrt2,dspmac,dspmacsat,accext,accmod,dspalu,dspalusat,
366 multi,atomic,syncloop,nop,ghost,multimem"
367 (cond [(eq_attr "jal" "!unset") (const_string "call")
368 (eq_attr "got" "load") (const_string "load")
370 (eq_attr "alu_type" "add,sub") (const_string "arith")
372 (eq_attr "alu_type" "not,nor,and,or,xor") (const_string "logical")
374 ;; If a doubleword move uses these expensive instructions,
375 ;; it is usually better to schedule them in the same way
376 ;; as the singleword form, rather than as "multi".
377 (eq_attr "move_type" "load") (const_string "load")
378 (eq_attr "move_type" "fpload") (const_string "fpload")
379 (eq_attr "move_type" "store") (const_string "store")
380 (eq_attr "move_type" "fpstore") (const_string "fpstore")
381 (eq_attr "move_type" "mtc") (const_string "mtc")
382 (eq_attr "move_type" "mfc") (const_string "mfc")
383 (eq_attr "move_type" "mtlo") (const_string "mtlo")
384 (eq_attr "move_type" "mflo") (const_string "mflo")
386 ;; These types of move are always single insns.
387 (eq_attr "move_type" "imul") (const_string "imul")
388 (eq_attr "move_type" "fmove") (const_string "fmove")
389 (eq_attr "move_type" "loadpool") (const_string "load")
390 (eq_attr "move_type" "signext") (const_string "signext")
391 (eq_attr "move_type" "ext_ins") (const_string "arith")
392 (eq_attr "move_type" "arith") (const_string "arith")
393 (eq_attr "move_type" "logical") (const_string "logical")
394 (eq_attr "move_type" "sll0") (const_string "shift")
395 (eq_attr "move_type" "andi") (const_string "logical")
397 ;; These types of move are always split.
398 (eq_attr "move_type" "constN,shift_shift")
399 (const_string "multi")
401 ;; These types of move are split for doubleword modes only.
402 (and (eq_attr "move_type" "move,const")
403 (eq_attr "dword_mode" "yes"))
404 (const_string "multi")
405 (eq_attr "move_type" "move") (const_string "move")
406 (eq_attr "move_type" "const") (const_string "const")
407 (eq_attr "sync_mem" "!none") (const_string "syncloop")]
408 (const_string "unknown")))
410 ;; Mode for conversion types (fcvt)
411 ;; I2S integer to float single (SI/DI to SF)
412 ;; I2D integer to float double (SI/DI to DF)
413 ;; S2I float to integer (SF to SI/DI)
414 ;; D2I float to integer (DF to SI/DI)
415 ;; D2S double to float single
416 ;; S2D float single to double
418 (define_attr "cnv_mode" "unknown,I2S,I2D,S2I,D2I,D2S,S2D"
419 (const_string "unknown"))
421 ;; Is this an extended instruction in mips16 mode?
422 (define_attr "extended_mips16" "no,yes"
423 (if_then_else (ior ;; In general, constant-pool loads are extended
424 ;; instructions. We don't yet optimize for 16-bit
425 ;; PC-relative references.
426 (eq_attr "move_type" "sll0,loadpool")
427 (eq_attr "jal" "direct")
428 (eq_attr "got" "load"))
430 (const_string "no")))
432 (define_attr "compression" "none,all,micromips32,micromips"
433 (const_string "none"))
435 (define_attr "enabled" "no,yes"
436 (cond [;; The o32 FPXX and FP64A ABI extensions prohibit direct moves between
437 ;; GR_REG and FR_REG for 64-bit values.
438 (and (eq_attr "move_type" "mtc,mfc")
439 (match_test "(TARGET_FLOATXX && !ISA_HAS_MXHC1)
440 || TARGET_O32_FP64A_ABI")
441 (eq_attr "dword_mode" "yes"))
443 (and (eq_attr "compression" "micromips32,micromips")
444 (match_test "!TARGET_MICROMIPS"))
446 (const_string "yes")))
448 ;; The number of individual instructions that a non-branch pattern generates,
449 ;; using units of BASE_INSN_LENGTH.
450 (define_attr "insn_count" ""
451 (cond [;; "Ghost" instructions occupy no space.
452 (eq_attr "type" "ghost")
455 ;; Extended instructions count as 2.
456 (and (eq_attr "extended_mips16" "yes")
457 (match_test "TARGET_MIPS16"))
460 ;; A GOT load followed by an add of $gp. This is not used for MIPS16.
461 (eq_attr "got" "xgot_high")
464 ;; SHIFT_SHIFTs are decomposed into two separate instructions.
465 ;; They are extended instructions on MIPS16 targets.
466 (eq_attr "move_type" "shift_shift")
467 (if_then_else (match_test "TARGET_MIPS16")
471 ;; Check for doubleword moves that are decomposed into two
472 ;; instructions. The individual instructions are unextended
474 (and (eq_attr "move_type" "mtc,mfc,mtlo,mflo,move")
475 (eq_attr "dword_mode" "yes"))
478 ;; Constants, loads and stores are handled by external routines.
479 (and (eq_attr "move_type" "const,constN")
480 (eq_attr "dword_mode" "yes"))
481 (symbol_ref "mips_split_const_insns (operands[1])")
482 (eq_attr "move_type" "const,constN")
483 (symbol_ref "mips_const_insns (operands[1])")
484 (eq_attr "move_type" "load,fpload")
485 (symbol_ref "mips_load_store_insns (operands[1], insn)")
486 (eq_attr "move_type" "store,fpstore")
487 (symbol_ref "mips_load_store_insns (operands[0], insn)
488 + (TARGET_FIX_24K ? 1 : 0)")
490 ;; In the worst case, a call macro will take 8 instructions:
492 ;; lui $25,%call_hi(FOO)
494 ;; lw $25,%call_lo(FOO)($25)
500 (eq_attr "jal_macro" "yes")
503 ;; Various VR4120 errata require a nop to be inserted after a macc
504 ;; instruction. The assembler does this for us, so account for
505 ;; the worst-case length here.
506 (and (eq_attr "type" "imadd")
507 (match_test "TARGET_FIX_VR4120"))
510 ;; VR4120 errata MD(4): if there are consecutive dmult instructions,
511 ;; the result of the second one is missed. The assembler should work
512 ;; around this by inserting a nop after the first dmult.
513 (and (eq_attr "type" "imul,imul3")
514 (eq_attr "mode" "DI")
515 (match_test "TARGET_FIX_VR4120"))
518 (eq_attr "type" "idiv,idiv3")
519 (symbol_ref "mips_idiv_insns ()")
521 (not (eq_attr "sync_mem" "none"))
522 (symbol_ref "mips_sync_loop_insns (insn, operands)")]
525 ;; Length of instruction in bytes. The default is derived from "insn_count",
526 ;; but there are special cases for branches (which must be handled here)
527 ;; and for compressed single instructions.
528 (define_attr "length" ""
529 (cond [(and (ior (eq_attr "compression" "micromips,all")
530 (and (eq_attr "compression" "micromips32")
531 (eq_attr "mode" "SI,SF")))
532 (eq_attr "dword_mode" "no")
533 (match_test "TARGET_MICROMIPS"))
536 ;; Direct microMIPS branch instructions have a range of
537 ;; [-0x10000,0xfffe], otherwise the range is [-0x20000,0x1fffc].
538 ;; If a branch is outside this range, we have a choice of two
541 ;; For PIC, an out-of-range branch like:
546 ;; becomes the equivalent of:
555 ;; The non-PIC case is similar except that we use a direct
556 ;; jump instead of an la/jr pair. Since the target of this
557 ;; jump is an absolute 28-bit bit address (the other bits
558 ;; coming from the address of the delay slot) this form cannot
559 ;; cross a 256MB boundary. We could provide the option of
560 ;; using la/jr in this case too, but we do not do so at
563 ;; The value we specify here does not account for the delay slot
564 ;; instruction, whose length is added separately. If the RTL
565 ;; pattern has no explicit delay slot, mips_adjust_insn_length
566 ;; will add the length of the implicit nop. The range of
567 ;; [-0x20000, 0x1fffc] from the address of the delay slot
568 ;; therefore translates to a range of:
570 ;; [-(0x20000 - sizeof (branch)), 0x1fffc - sizeof (slot)]
571 ;; == [-0x1fffc, 0x1fff8]
573 ;; from the shorten_branches reference address.
574 (and (eq_attr "type" "branch")
575 (not (match_test "TARGET_MIPS16")))
576 (cond [;; Any variant can handle the 17-bit range.
577 (and (le (minus (match_dup 0) (pc)) (const_int 65532))
578 (le (minus (pc) (match_dup 0)) (const_int 65534)))
581 ;; The 18-bit range is OK other than for microMIPS.
582 (and (not (match_test "TARGET_MICROMIPS"))
583 (and (le (minus (match_dup 0) (pc)) (const_int 131064))
584 (le (minus (pc) (match_dup 0)) (const_int 131068))))
587 ;; The non-PIC case: branch, first delay slot, and J.
588 (match_test "TARGET_ABSOLUTE_JUMPS")
591 ;; Use MAX_PIC_BRANCH_LENGTH as a (gross) overestimate.
592 ;; mips_adjust_insn_length substitutes the correct length.
594 ;; Note that we can't simply use (symbol_ref ...) here
595 ;; because genattrtab needs to know the maximum length
597 (const_int MAX_PIC_BRANCH_LENGTH))
599 ;; An unextended MIPS16 branch has a range of [-0x100, 0xfe]
600 ;; from the address of the following instruction, which leads
603 ;; [-(0x100 - sizeof (branch)), 0xfe]
606 ;; from the shorten_branches reference address. Extended branches
607 ;; likewise have a range of [-0x10000, 0xfffe] from the address
608 ;; of the following instruction, which leads to a range of:
610 ;; [-(0x10000 - sizeof (branch)), 0xfffe]
611 ;; == [-0xfffc, 0xfffe]
613 ;; from the reference address.
615 ;; When a branch is out of range, mips_reorg splits it into a form
616 ;; that uses in-range branches. There are four basic sequences:
618 ;; (1) Absolute addressing with a readable text segment
619 ;; (32-bit addresses):
622 ;; move $1,$2 2 bytes
623 ;; lw $2,label 2 bytes
625 ;; move $2,$1 2 bytes
626 ;; .align 2 0 or 2 bytes
628 ;; .word target 4 bytes
630 ;; (16 bytes in the worst case)
632 ;; (2) Absolute addressing with a readable text segment
633 ;; (64-bit addresses):
636 ;; move $1,$2 2 bytes
637 ;; ld $2,label 2 bytes
639 ;; move $2,$1 2 bytes
640 ;; .align 3 0 to 6 bytes
642 ;; .dword target 8 bytes
644 ;; (24 bytes in the worst case)
646 ;; (3) Absolute addressing without a readable text segment
647 ;; (which requires 32-bit addresses at present):
650 ;; move $1,$2 2 bytes
651 ;; lui $2,%hi(target) 4 bytes
654 ;; addiu $2,%lo(target) 4 bytes
656 ;; move $2,$1 2 bytes
660 ;; (4) PIC addressing (which requires 32-bit addresses at present):
663 ;; move $1,$2 2 bytes
664 ;; lw $2,cprestore 0, 2 or 4 bytes
665 ;; lw $2,%got(target)($2) 4 bytes
666 ;; addiu $2,%lo(target) 4 bytes
668 ;; move $2,$1 2 bytes
670 ;; (20 bytes in the worst case)
671 (and (eq_attr "type" "branch")
672 (match_test "TARGET_MIPS16"))
673 (cond [(and (le (minus (match_dup 0) (pc)) (const_int 254))
674 (le (minus (pc) (match_dup 0)) (const_int 254)))
676 (and (le (minus (match_dup 0) (pc)) (const_int 65534))
677 (le (minus (pc) (match_dup 0)) (const_int 65532)))
679 (and (match_test "TARGET_ABICALLS")
680 (not (match_test "TARGET_ABSOLUTE_ABICALLS")))
682 (match_test "Pmode == SImode")
685 (symbol_ref "get_attr_insn_count (insn) * BASE_INSN_LENGTH")))
687 ;; Attribute describing the processor.
688 (define_enum_attr "cpu" "processor"
689 (const (symbol_ref "mips_tune")))
691 ;; The type of hardware hazard associated with this instruction.
692 ;; DELAY means that the next instruction cannot read the result
693 ;; of this one. HILO means that the next two instructions cannot
694 ;; write to HI or LO.
695 (define_attr "hazard" "none,delay,hilo"
696 (cond [(and (eq_attr "type" "load,fpload,fpidxload")
697 (match_test "ISA_HAS_LOAD_DELAY"))
698 (const_string "delay")
700 (and (eq_attr "type" "mfc,mtc")
701 (match_test "ISA_HAS_XFER_DELAY"))
702 (const_string "delay")
704 (and (eq_attr "type" "fcmp")
705 (match_test "ISA_HAS_FCMP_DELAY"))
706 (const_string "delay")
708 ;; The r4000 multiplication patterns include an mflo instruction.
709 (and (eq_attr "type" "imul")
710 (match_test "TARGET_FIX_R4000"))
711 (const_string "hilo")
713 (and (eq_attr "type" "mfhi,mflo")
714 (not (match_test "ISA_HAS_HILO_INTERLOCKS")))
715 (const_string "hilo")]
716 (const_string "none")))
718 ;; Can the instruction be put into a delay slot?
719 (define_attr "can_delay" "no,yes"
720 (if_then_else (and (eq_attr "type" "!branch,call,jump")
721 (eq_attr "hazard" "none")
722 (match_test "get_attr_insn_count (insn) == 1"))
724 (const_string "no")))
726 ;; Attribute defining whether or not we can use the branch-likely
728 (define_attr "branch_likely" "no,yes"
729 (if_then_else (match_test "GENERATE_BRANCHLIKELY")
731 (const_string "no")))
733 ;; True if an instruction might assign to hi or lo when reloaded.
734 ;; This is used by the TUNE_MACC_CHAINS code.
735 (define_attr "may_clobber_hilo" "no,yes"
736 (if_then_else (eq_attr "type" "imul,imul3,imadd,idiv,mthi,mtlo")
738 (const_string "no")))
740 ;; Describe a user's asm statement.
741 (define_asm_attributes
742 [(set_attr "type" "multi")
743 (set_attr "can_delay" "no")])
745 ;; This mode iterator allows 32-bit and 64-bit GPR patterns to be generated
746 ;; from the same template.
747 (define_mode_iterator GPR [SI (DI "TARGET_64BIT")])
749 ;; A copy of GPR that can be used when a pattern has two independent
751 (define_mode_iterator GPR2 [SI (DI "TARGET_64BIT")])
753 (define_mode_iterator MOVEP1 [SI SF])
754 (define_mode_iterator MOVEP2 [SI SF])
756 ;; This mode iterator allows :HILO to be used as the mode of the
757 ;; concatenated HI and LO registers.
758 (define_mode_iterator HILO [(DI "!TARGET_64BIT") (TI "TARGET_64BIT")])
760 ;; This mode iterator allows :P to be used for patterns that operate on
761 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
762 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
764 ;; This mode iterator allows :MOVECC to be used anywhere that a
765 ;; conditional-move-type condition is needed.
766 (define_mode_iterator MOVECC [SI (DI "TARGET_64BIT")
767 (CC "TARGET_HARD_FLOAT
768 && !TARGET_LOONGSON_2EF
769 && !TARGET_MIPS5900")])
771 ;; 32-bit integer moves for which we provide move patterns.
772 (define_mode_iterator IMOVE32
781 (V4UQQ "TARGET_DSP")])
783 ;; 64-bit modes for which we provide move patterns.
784 (define_mode_iterator MOVE64
786 (V2SF "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT")
787 (V2SI "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS")
788 (V4HI "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS")
789 (V8QI "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS")])
791 ;; 128-bit modes for which we provide move patterns on 64-bit targets.
792 (define_mode_iterator MOVE128 [TI TF])
794 ;; This mode iterator allows the QI and HI extension patterns to be
795 ;; defined from the same template.
796 (define_mode_iterator SHORT [QI HI])
798 ;; Likewise the 64-bit truncate-and-shift patterns.
799 (define_mode_iterator SUBDI [QI HI SI])
801 ;; This mode iterator allows :ANYF to be used wherever a scalar or vector
802 ;; floating-point mode is allowed.
803 (define_mode_iterator ANYF [(SF "TARGET_HARD_FLOAT")
804 (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
805 (V2SF "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT")])
807 ;; Like ANYF, but only applies to scalar modes.
808 (define_mode_iterator SCALARF [(SF "TARGET_HARD_FLOAT")
809 (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")])
811 ;; A floating-point mode for which moves involving FPRs may need to be split.
812 (define_mode_iterator SPLITF
813 [(DF "!TARGET_64BIT && TARGET_DOUBLE_FLOAT")
814 (DI "!TARGET_64BIT && TARGET_DOUBLE_FLOAT")
815 (V2SF "!TARGET_64BIT && TARGET_PAIRED_SINGLE_FLOAT")
816 (V2SI "!TARGET_64BIT && TARGET_LOONGSON_VECTORS")
817 (V4HI "!TARGET_64BIT && TARGET_LOONGSON_VECTORS")
818 (V8QI "!TARGET_64BIT && TARGET_LOONGSON_VECTORS")
819 (TF "TARGET_64BIT && TARGET_FLOAT64")])
821 ;; In GPR templates, a string like "<d>subu" will expand to "subu" in the
822 ;; 32-bit version and "dsubu" in the 64-bit version.
823 (define_mode_attr d [(SI "") (DI "d")
824 (QQ "") (HQ "") (SQ "") (DQ "d")
825 (UQQ "") (UHQ "") (USQ "") (UDQ "d")
826 (HA "") (SA "") (DA "d")
827 (UHA "") (USA "") (UDA "d")])
829 ;; Same as d but upper-case.
830 (define_mode_attr D [(SI "") (DI "D")
831 (QQ "") (HQ "") (SQ "") (DQ "D")
832 (UQQ "") (UHQ "") (USQ "") (UDQ "D")
833 (HA "") (SA "") (DA "D")
834 (UHA "") (USA "") (UDA "D")])
836 ;; This attribute gives the length suffix for a load or store instruction.
837 ;; The same suffixes work for zero and sign extensions.
838 (define_mode_attr size [(QI "b") (HI "h") (SI "w") (DI "d")])
839 (define_mode_attr SIZE [(QI "B") (HI "H") (SI "W") (DI "D")])
841 ;; This attributes gives the mode mask of a SHORT.
842 (define_mode_attr mask [(QI "0x00ff") (HI "0xffff")])
844 ;; Mode attributes for GPR loads.
845 (define_mode_attr load [(SI "lw") (DI "ld")])
846 ;; Instruction names for stores.
847 (define_mode_attr store [(QI "sb") (HI "sh") (SI "sw") (DI "sd")])
849 ;; Similarly for MIPS IV indexed FPR loads and stores.
850 (define_mode_attr loadx [(SF "lwxc1") (DF "ldxc1") (V2SF "ldxc1")])
851 (define_mode_attr storex [(SF "swxc1") (DF "sdxc1") (V2SF "sdxc1")])
853 ;; The unextended ranges of the MIPS16 addiu and daddiu instructions
854 ;; are different. Some forms of unextended addiu have an 8-bit immediate
855 ;; field but the equivalent daddiu has only a 5-bit field.
856 (define_mode_attr si8_di5 [(SI "8") (DI "5")])
858 ;; This attribute gives the best constraint to use for registers of
860 (define_mode_attr reg [(SI "d") (DI "d") (CC "z")])
862 ;; This attribute gives the format suffix for floating-point operations.
863 (define_mode_attr fmt [(SF "s") (DF "d") (V2SF "ps")])
865 ;; This attribute gives the upper-case mode name for one unit of a
866 ;; floating-point mode.
867 (define_mode_attr UNITMODE [(SF "SF") (DF "DF") (V2SF "SF")])
869 ;; This attribute gives the integer mode that has the same size as a
871 (define_mode_attr IMODE [(QQ "QI") (HQ "HI") (SQ "SI") (DQ "DI")
872 (UQQ "QI") (UHQ "HI") (USQ "SI") (UDQ "DI")
873 (HA "HI") (SA "SI") (DA "DI")
874 (UHA "HI") (USA "SI") (UDA "DI")
875 (V4UQQ "SI") (V2UHQ "SI") (V2UHA "SI")
876 (V2HQ "SI") (V2HA "SI")])
878 ;; This attribute gives the integer mode that has half the size of
879 ;; the controlling mode.
880 (define_mode_attr HALFMODE [(DF "SI") (DI "SI") (V2SF "SI")
881 (V2SI "SI") (V4HI "SI") (V8QI "SI")
884 ;; This attribute works around the early SB-1 rev2 core "F2" erratum:
886 ;; In certain cases, div.s and div.ps may have a rounding error
887 ;; and/or wrong inexact flag.
889 ;; Therefore, we only allow div.s if not working around SB-1 rev2
890 ;; errata or if a slight loss of precision is OK.
891 (define_mode_attr divide_condition
892 [DF (SF "!TARGET_FIX_SB1 || flag_unsafe_math_optimizations")
893 (V2SF "TARGET_SB1 && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)")])
895 ;; This attribute gives the conditions under which SQRT.fmt instructions
897 (define_mode_attr sqrt_condition
898 [(SF "!ISA_MIPS1") (DF "!ISA_MIPS1") (V2SF "TARGET_SB1")])
900 ;; This code iterator allows signed and unsigned widening multiplications
901 ;; to use the same template.
902 (define_code_iterator any_extend [sign_extend zero_extend])
904 ;; This code iterator allows the two right shift instructions to be
905 ;; generated from the same template.
906 (define_code_iterator any_shiftrt [ashiftrt lshiftrt])
908 ;; This code iterator allows the three shift instructions to be generated
909 ;; from the same template.
910 (define_code_iterator any_shift [ashift ashiftrt lshiftrt])
912 ;; This code iterator allows unsigned and signed division to be generated
913 ;; from the same template.
914 (define_code_iterator any_div [div udiv])
916 ;; This code iterator allows unsigned and signed modulus to be generated
917 ;; from the same template.
918 (define_code_iterator any_mod [mod umod])
920 ;; This code iterator allows all native floating-point comparisons to be
921 ;; generated from the same template.
922 (define_code_iterator fcond [unordered uneq unlt unle eq lt le])
924 ;; This code iterator is used for comparisons that can be implemented
925 ;; by swapping the operands.
926 (define_code_iterator swapped_fcond [ge gt unge ungt])
928 ;; Equality operators.
929 (define_code_iterator equality_op [eq ne])
931 ;; These code iterators allow the signed and unsigned scc operations to use
932 ;; the same template.
933 (define_code_iterator any_gt [gt gtu])
934 (define_code_iterator any_ge [ge geu])
935 (define_code_iterator any_lt [lt ltu])
936 (define_code_iterator any_le [le leu])
938 (define_code_iterator any_return [return simple_return])
940 ;; <u> expands to an empty string when doing a signed operation and
941 ;; "u" when doing an unsigned operation.
942 (define_code_attr u [(sign_extend "") (zero_extend "u")
950 ;; <U> is like <u> except uppercase.
951 (define_code_attr U [(sign_extend "") (zero_extend "U")])
953 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
954 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
956 ;; <optab> expands to the name of the optab for a particular code.
957 (define_code_attr optab [(ashift "ashl")
966 (simple_return "simple_return")])
968 ;; <insn> expands to the name of the insn that implements a particular code.
969 (define_code_attr insn [(ashift "sll")
978 ;; <immediate_insn> expands to the name of the insn that implements
979 ;; a particular code to operate on immediate values.
980 (define_code_attr immediate_insn [(ior "ori")
984 (define_code_attr shift_compression [(ashift "micromips32")
985 (lshiftrt "micromips32")
988 ;; <fcond> is the c.cond.fmt condition associated with a particular code.
989 (define_code_attr fcond [(unordered "un")
997 ;; Similar, but for swapped conditions.
998 (define_code_attr swapped_fcond [(ge "le")
1003 ;; The value of the bit when the branch is taken for branch_bit patterns.
1004 ;; Comparison is always against zero so this depends on the operator.
1005 (define_code_attr bbv [(eq "0") (ne "1")])
1007 ;; This is the inverse value of bbv.
1008 (define_code_attr bbinv [(eq "1") (ne "0")])
1010 ;; .........................
1012 ;; Branch, call and jump delay slots
1014 ;; .........................
1016 (define_delay (and (eq_attr "type" "branch")
1017 (not (match_test "TARGET_MIPS16"))
1018 (eq_attr "branch_likely" "yes"))
1019 [(eq_attr "can_delay" "yes")
1021 (eq_attr "can_delay" "yes")])
1023 ;; Branches that don't have likely variants do not annul on false.
1024 (define_delay (and (eq_attr "type" "branch")
1025 (not (match_test "TARGET_MIPS16"))
1026 (eq_attr "branch_likely" "no"))
1027 [(eq_attr "can_delay" "yes")
1031 (define_delay (eq_attr "type" "jump")
1032 [(eq_attr "can_delay" "yes")
1036 (define_delay (and (eq_attr "type" "call")
1037 (eq_attr "jal_macro" "no"))
1038 [(eq_attr "can_delay" "yes")
1042 ;; Pipeline descriptions.
1044 ;; generic.md provides a fallback for processors without a specific
1045 ;; pipeline description. It is derived from the old define_function_unit
1046 ;; version and uses the "alu" and "imuldiv" units declared below.
1048 ;; Some of the processor-specific files are also derived from old
1049 ;; define_function_unit descriptions and simply override the parts of
1050 ;; generic.md that don't apply. The other processor-specific files
1051 ;; are self-contained.
1052 (define_automaton "alu,imuldiv")
1054 (define_cpu_unit "alu" "alu")
1055 (define_cpu_unit "imuldiv" "imuldiv")
1057 ;; Ghost instructions produce no real code and introduce no hazards.
1058 ;; They exist purely to express an effect on dataflow.
1059 (define_insn_reservation "ghost" 0
1060 (eq_attr "type" "ghost")
1063 (include "p5600.md")
1081 (include "10000.md")
1082 (include "loongson2ef.md")
1083 (include "loongson3a.md")
1084 (include "octeon.md")
1086 (include "sr71k.md")
1089 (include "generic.md")
1092 ;; ....................
1094 ;; CONDITIONAL TRAPS
1096 ;; ....................
1100 [(trap_if (const_int 1) (const_int 0))]
1103 if (ISA_HAS_COND_TRAP)
1104 return "teq\t$0,$0";
1105 else if (TARGET_MIPS16)
1110 [(set_attr "type" "trap")])
1112 (define_expand "ctrap<mode>4"
1113 [(trap_if (match_operator 0 "comparison_operator"
1114 [(match_operand:GPR 1 "reg_or_0_operand")
1115 (match_operand:GPR 2 "arith_operand")])
1116 (match_operand 3 "const_0_operand"))]
1119 mips_expand_conditional_trap (operands[0]);
1123 (define_insn "*conditional_trap<mode>"
1124 [(trap_if (match_operator:GPR 0 "trap_comparison_operator"
1125 [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
1126 (match_operand:GPR 2 "arith_operand" "dI")])
1130 [(set_attr "type" "trap")])
1133 ;; ....................
1137 ;; ....................
1140 (define_insn "add<mode>3"
1141 [(set (match_operand:ANYF 0 "register_operand" "=f")
1142 (plus:ANYF (match_operand:ANYF 1 "register_operand" "f")
1143 (match_operand:ANYF 2 "register_operand" "f")))]
1145 "add.<fmt>\t%0,%1,%2"
1146 [(set_attr "type" "fadd")
1147 (set_attr "mode" "<UNITMODE>")])
1149 (define_expand "add<mode>3"
1150 [(set (match_operand:GPR 0 "register_operand")
1151 (plus:GPR (match_operand:GPR 1 "register_operand")
1152 (match_operand:GPR 2 "arith_operand")))]
1155 (define_insn "*add<mode>3"
1156 [(set (match_operand:GPR 0 "register_operand" "=!u,d,!u,!u,!ks,!d,d")
1157 (plus:GPR (match_operand:GPR 1 "register_operand" "!u,d,!u,!ks,!ks,0,d")
1158 (match_operand:GPR 2 "arith_operand" "!u,d,Uead,Uuw6,Uesp,Usb4,Q")))]
1161 if (which_alternative == 0
1162 || which_alternative == 1)
1163 return "<d>addu\t%0,%1,%2";
1165 return "<d>addiu\t%0,%1,%2";
1167 [(set_attr "alu_type" "add")
1168 (set_attr "compression" "micromips32,*,micromips32,micromips32,micromips32,micromips32,*")
1169 (set_attr "mode" "<MODE>")])
1171 (define_insn "*add<mode>3_mips16"
1172 [(set (match_operand:GPR 0 "register_operand" "=ks,ks,d,d,d,d,d,d,d")
1173 (plus:GPR (match_operand:GPR 1 "register_operand" "ks,ks,ks,ks,0,0,d,d,d")
1174 (match_operand:GPR 2 "arith_operand" "Usd8,Q,Uuw<si8_di5>,Q,Usb<si8_di5>,Q,Usb4,O,d")))]
1186 [(set_attr "alu_type" "add")
1187 (set_attr "mode" "<MODE>")
1188 (set_attr "extended_mips16" "no,yes,no,yes,no,yes,no,yes,no")])
1190 ;; On the mips16, we can sometimes split an add of a constant which is
1191 ;; a 4 byte instruction into two adds which are both 2 byte
1192 ;; instructions. There are two cases: one where we are adding a
1193 ;; constant plus a register to another register, and one where we are
1194 ;; simply adding a constant to a register.
1197 [(set (match_operand:SI 0 "d_operand")
1198 (plus:SI (match_dup 0)
1199 (match_operand:SI 1 "const_int_operand")))]
1200 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
1201 && ((INTVAL (operands[1]) > 0x7f
1202 && INTVAL (operands[1]) <= 0x7f + 0x7f)
1203 || (INTVAL (operands[1]) < - 0x80
1204 && INTVAL (operands[1]) >= - 0x80 - 0x80))"
1205 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
1206 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
1208 HOST_WIDE_INT val = INTVAL (operands[1]);
1212 operands[1] = GEN_INT (0x7f);
1213 operands[2] = GEN_INT (val - 0x7f);
1217 operands[1] = GEN_INT (- 0x80);
1218 operands[2] = GEN_INT (val + 0x80);
1223 [(set (match_operand:SI 0 "d_operand")
1224 (plus:SI (match_operand:SI 1 "d_operand")
1225 (match_operand:SI 2 "const_int_operand")))]
1226 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
1227 && REGNO (operands[0]) != REGNO (operands[1])
1228 && ((INTVAL (operands[2]) > 0x7
1229 && INTVAL (operands[2]) <= 0x7 + 0x7f)
1230 || (INTVAL (operands[2]) < - 0x8
1231 && INTVAL (operands[2]) >= - 0x8 - 0x80))"
1232 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
1233 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
1235 HOST_WIDE_INT val = INTVAL (operands[2]);
1239 operands[2] = GEN_INT (0x7);
1240 operands[3] = GEN_INT (val - 0x7);
1244 operands[2] = GEN_INT (- 0x8);
1245 operands[3] = GEN_INT (val + 0x8);
1250 [(set (match_operand:DI 0 "d_operand")
1251 (plus:DI (match_dup 0)
1252 (match_operand:DI 1 "const_int_operand")))]
1253 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1254 && ((INTVAL (operands[1]) > 0xf
1255 && INTVAL (operands[1]) <= 0xf + 0xf)
1256 || (INTVAL (operands[1]) < - 0x10
1257 && INTVAL (operands[1]) >= - 0x10 - 0x10))"
1258 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
1259 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
1261 HOST_WIDE_INT val = INTVAL (operands[1]);
1265 operands[1] = GEN_INT (0xf);
1266 operands[2] = GEN_INT (val - 0xf);
1270 operands[1] = GEN_INT (- 0x10);
1271 operands[2] = GEN_INT (val + 0x10);
1276 [(set (match_operand:DI 0 "d_operand")
1277 (plus:DI (match_operand:DI 1 "d_operand")
1278 (match_operand:DI 2 "const_int_operand")))]
1279 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1280 && REGNO (operands[0]) != REGNO (operands[1])
1281 && ((INTVAL (operands[2]) > 0x7
1282 && INTVAL (operands[2]) <= 0x7 + 0xf)
1283 || (INTVAL (operands[2]) < - 0x8
1284 && INTVAL (operands[2]) >= - 0x8 - 0x10))"
1285 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
1286 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
1288 HOST_WIDE_INT val = INTVAL (operands[2]);
1292 operands[2] = GEN_INT (0x7);
1293 operands[3] = GEN_INT (val - 0x7);
1297 operands[2] = GEN_INT (- 0x8);
1298 operands[3] = GEN_INT (val + 0x8);
1302 (define_insn "*addsi3_extended"
1303 [(set (match_operand:DI 0 "register_operand" "=d,d")
1305 (plus:SI (match_operand:SI 1 "register_operand" "d,d")
1306 (match_operand:SI 2 "arith_operand" "d,Q"))))]
1307 "TARGET_64BIT && !TARGET_MIPS16"
1311 [(set_attr "alu_type" "add")
1312 (set_attr "mode" "SI")])
1314 ;; Split this insn so that the addiu splitters can have a crack at it.
1315 ;; Use a conservative length estimate until the split.
1316 (define_insn_and_split "*addsi3_extended_mips16"
1317 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1319 (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1320 (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
1321 "TARGET_64BIT && TARGET_MIPS16"
1323 "&& reload_completed"
1324 [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))]
1325 { operands[3] = gen_lowpart (SImode, operands[0]); }
1326 [(set_attr "alu_type" "add")
1327 (set_attr "mode" "SI")
1328 (set_attr "extended_mips16" "yes")])
1330 ;; Combiner patterns for unsigned byte-add.
1332 (define_insn "*baddu_si_eb"
1333 [(set (match_operand:SI 0 "register_operand" "=d")
1336 (plus:SI (match_operand:SI 1 "register_operand" "d")
1337 (match_operand:SI 2 "register_operand" "d")) 3)))]
1338 "ISA_HAS_BADDU && BYTES_BIG_ENDIAN"
1340 [(set_attr "alu_type" "add")])
1342 (define_insn "*baddu_si_el"
1343 [(set (match_operand:SI 0 "register_operand" "=d")
1346 (plus:SI (match_operand:SI 1 "register_operand" "d")
1347 (match_operand:SI 2 "register_operand" "d")) 0)))]
1348 "ISA_HAS_BADDU && !BYTES_BIG_ENDIAN"
1350 [(set_attr "alu_type" "add")])
1352 (define_insn "*baddu_di<mode>"
1353 [(set (match_operand:GPR 0 "register_operand" "=d")
1356 (plus:DI (match_operand:DI 1 "register_operand" "d")
1357 (match_operand:DI 2 "register_operand" "d")))))]
1358 "ISA_HAS_BADDU && TARGET_64BIT"
1360 [(set_attr "alu_type" "add")])
1363 ;; ....................
1367 ;; ....................
1370 (define_insn "sub<mode>3"
1371 [(set (match_operand:ANYF 0 "register_operand" "=f")
1372 (minus:ANYF (match_operand:ANYF 1 "register_operand" "f")
1373 (match_operand:ANYF 2 "register_operand" "f")))]
1375 "sub.<fmt>\t%0,%1,%2"
1376 [(set_attr "type" "fadd")
1377 (set_attr "mode" "<UNITMODE>")])
1379 (define_insn "sub<mode>3"
1380 [(set (match_operand:GPR 0 "register_operand" "=!u,d")
1381 (minus:GPR (match_operand:GPR 1 "register_operand" "!u,d")
1382 (match_operand:GPR 2 "register_operand" "!u,d")))]
1385 [(set_attr "alu_type" "sub")
1386 (set_attr "compression" "micromips32,*")
1387 (set_attr "mode" "<MODE>")])
1389 (define_insn "*subsi3_extended"
1390 [(set (match_operand:DI 0 "register_operand" "=d")
1392 (minus:SI (match_operand:SI 1 "register_operand" "d")
1393 (match_operand:SI 2 "register_operand" "d"))))]
1396 [(set_attr "alu_type" "sub")
1397 (set_attr "mode" "DI")])
1400 ;; ....................
1404 ;; ....................
1407 (define_expand "mul<mode>3"
1408 [(set (match_operand:SCALARF 0 "register_operand")
1409 (mult:SCALARF (match_operand:SCALARF 1 "register_operand")
1410 (match_operand:SCALARF 2 "register_operand")))]
1414 (define_insn "*mul<mode>3"
1415 [(set (match_operand:SCALARF 0 "register_operand" "=f")
1416 (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
1417 (match_operand:SCALARF 2 "register_operand" "f")))]
1418 "!TARGET_4300_MUL_FIX"
1419 "mul.<fmt>\t%0,%1,%2"
1420 [(set_attr "type" "fmul")
1421 (set_attr "mode" "<MODE>")])
1423 ;; Early VR4300 silicon has a CPU bug where multiplies with certain
1424 ;; operands may corrupt immediately following multiplies. This is a
1425 ;; simple fix to insert NOPs.
1427 (define_insn "*mul<mode>3_r4300"
1428 [(set (match_operand:SCALARF 0 "register_operand" "=f")
1429 (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
1430 (match_operand:SCALARF 2 "register_operand" "f")))]
1431 "TARGET_4300_MUL_FIX"
1432 "mul.<fmt>\t%0,%1,%2\;nop"
1433 [(set_attr "type" "fmul")
1434 (set_attr "mode" "<MODE>")
1435 (set_attr "insn_count" "2")])
1437 (define_insn "mulv2sf3"
1438 [(set (match_operand:V2SF 0 "register_operand" "=f")
1439 (mult:V2SF (match_operand:V2SF 1 "register_operand" "f")
1440 (match_operand:V2SF 2 "register_operand" "f")))]
1441 "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
1443 [(set_attr "type" "fmul")
1444 (set_attr "mode" "SF")])
1446 ;; The original R4000 has a cpu bug. If a double-word or a variable
1447 ;; shift executes while an integer multiplication is in progress, the
1448 ;; shift may give an incorrect result. Avoid this by keeping the mflo
1449 ;; with the mult on the R4000.
1451 ;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
1452 ;; (also valid for MIPS R4000MC processors):
1454 ;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
1455 ;; this errata description.
1456 ;; The following code sequence causes the R4000 to incorrectly
1457 ;; execute the Double Shift Right Arithmetic 32 (dsra32)
1458 ;; instruction. If the dsra32 instruction is executed during an
1459 ;; integer multiply, the dsra32 will only shift by the amount in
1460 ;; specified in the instruction rather than the amount plus 32
1462 ;; instruction 1: mult rs,rt integer multiply
1463 ;; instruction 2-12: dsra32 rd,rt,rs doubleword shift
1464 ;; right arithmetic + 32
1465 ;; Workaround: A dsra32 instruction placed after an integer
1466 ;; multiply should not be one of the 11 instructions after the
1467 ;; multiply instruction."
1471 ;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
1472 ;; the following description.
1473 ;; All extended shifts (shift by n+32) and variable shifts (32 and
1474 ;; 64-bit versions) may produce incorrect results under the
1475 ;; following conditions:
1476 ;; 1) An integer multiply is currently executing
1477 ;; 2) These types of shift instructions are executed immediately
1478 ;; following an integer divide instruction.
1480 ;; 1) Make sure no integer multiply is running wihen these
1481 ;; instruction are executed. If this cannot be predicted at
1482 ;; compile time, then insert a "mfhi" to R0 instruction
1483 ;; immediately after the integer multiply instruction. This
1484 ;; will cause the integer multiply to complete before the shift
1486 ;; 2) Separate integer divide and these two classes of shift
1487 ;; instructions by another instruction or a noop."
1489 ;; These processors have PRId values of 0x00004220 and 0x00004300,
1492 (define_expand "mul<mode>3"
1493 [(set (match_operand:GPR 0 "register_operand")
1494 (mult:GPR (match_operand:GPR 1 "register_operand")
1495 (match_operand:GPR 2 "register_operand")))]
1500 if (TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A)
1501 emit_insn (gen_mul<mode>3_mul3_loongson (operands[0], operands[1],
1503 else if (ISA_HAS_<D>MUL3)
1504 emit_insn (gen_mul<mode>3_mul3 (operands[0], operands[1], operands[2]));
1505 else if (TARGET_MIPS16)
1507 lo = gen_rtx_REG (<MODE>mode, LO_REGNUM);
1508 emit_insn (gen_mul<mode>3_internal (lo, operands[1], operands[2]));
1509 emit_move_insn (operands[0], lo);
1511 else if (TARGET_FIX_R4000)
1512 emit_insn (gen_mul<mode>3_r4000 (operands[0], operands[1], operands[2]));
1515 (gen_mul<mode>3_internal (operands[0], operands[1], operands[2]));
1519 (define_insn "mul<mode>3_mul3_loongson"
1520 [(set (match_operand:GPR 0 "register_operand" "=d")
1521 (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1522 (match_operand:GPR 2 "register_operand" "d")))]
1523 "TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A"
1525 if (TARGET_LOONGSON_2EF)
1526 return "<d>multu.g\t%0,%1,%2";
1528 return "gs<d>multu\t%0,%1,%2";
1530 [(set_attr "type" "imul3nc")
1531 (set_attr "mode" "<MODE>")])
1533 (define_insn "mul<mode>3_mul3"
1534 [(set (match_operand:GPR 0 "register_operand" "=d,l")
1535 (mult:GPR (match_operand:GPR 1 "register_operand" "d,d")
1536 (match_operand:GPR 2 "register_operand" "d,d")))
1537 (clobber (match_scratch:GPR 3 "=l,X"))]
1540 if (which_alternative == 1)
1541 return "<d>mult\t%1,%2";
1542 if (<MODE>mode == SImode && (TARGET_MIPS3900 || TARGET_MIPS5900))
1543 return "mult\t%0,%1,%2";
1544 return "<d>mul\t%0,%1,%2";
1546 [(set_attr "type" "imul3,imul")
1547 (set_attr "mode" "<MODE>")])
1549 ;; If a register gets allocated to LO, and we spill to memory, the reload
1550 ;; will include a move from LO to a GPR. Merge it into the multiplication
1551 ;; if it can set the GPR directly.
1554 ;; Operand 1: GPR (1st multiplication operand)
1555 ;; Operand 2: GPR (2nd multiplication operand)
1556 ;; Operand 3: GPR (destination)
1559 [(set (match_operand:SI 0 "lo_operand")
1560 (mult:SI (match_operand:SI 1 "d_operand")
1561 (match_operand:SI 2 "d_operand")))
1562 (clobber (scratch:SI))])
1563 (set (match_operand:SI 3 "d_operand")
1565 "ISA_HAS_MUL3 && peep2_reg_dead_p (2, operands[0])"
1568 (mult:SI (match_dup 1)
1570 (clobber (match_dup 0))])])
1572 (define_insn "mul<mode>3_internal"
1573 [(set (match_operand:GPR 0 "muldiv_target_operand" "=l")
1574 (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1575 (match_operand:GPR 2 "register_operand" "d")))]
1576 "ISA_HAS_<D>MULT && !TARGET_FIX_R4000"
1578 [(set_attr "type" "imul")
1579 (set_attr "mode" "<MODE>")])
1581 (define_insn "mul<mode>3_r4000"
1582 [(set (match_operand:GPR 0 "register_operand" "=d")
1583 (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1584 (match_operand:GPR 2 "register_operand" "d")))
1585 (clobber (match_scratch:GPR 3 "=l"))]
1586 "ISA_HAS_<D>MULT && TARGET_FIX_R4000"
1587 "<d>mult\t%1,%2\;mflo\t%0"
1588 [(set_attr "type" "imul")
1589 (set_attr "mode" "<MODE>")
1590 (set_attr "insn_count" "2")])
1592 ;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
1593 ;; of "mult; mflo". They have the same latency, but the first form gives
1594 ;; us an extra cycle to compute the operands.
1597 ;; Operand 1: GPR (1st multiplication operand)
1598 ;; Operand 2: GPR (2nd multiplication operand)
1599 ;; Operand 3: GPR (destination)
1601 [(set (match_operand:SI 0 "lo_operand")
1602 (mult:SI (match_operand:SI 1 "d_operand")
1603 (match_operand:SI 2 "d_operand")))
1604 (set (match_operand:SI 3 "d_operand")
1606 "ISA_HAS_MACC && !ISA_HAS_MUL3"
1611 (plus:SI (mult:SI (match_dup 1)
1615 (plus:SI (mult:SI (match_dup 1)
1619 ;; Multiply-accumulate patterns
1621 ;; This pattern is first matched by combine, which tries to use the
1622 ;; pattern wherever it can. We don't know until later whether it
1623 ;; is actually profitable to use MADD over a "MUL; ADDIU" sequence,
1624 ;; so we need to keep both options open.
1626 ;; The second alternative has a "?" marker because it is generally
1627 ;; one instruction more costly than the first alternative. This "?"
1628 ;; marker is enough to convey the relative costs to the register
1631 ;; However, reload counts reloads of operands 4 and 5 in the same way as
1632 ;; reloads of the other operands, even though operands 4 and 5 need no
1633 ;; copy instructions. Reload therefore thinks that the second alternative
1634 ;; is two reloads more costly than the first. We add "*?*?" to the first
1635 ;; alternative as a counterweight.
1637 ;; LRA simulates reload but the cost of reloading scratches is lower
1638 ;; than of the classic reload. For the time being, removing the counterweight
1639 ;; for LRA is more profitable.
1640 (define_insn "*mul_acc_si"
1641 [(set (match_operand:SI 0 "register_operand" "=l*?*?,l,d?")
1642 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1643 (match_operand:SI 2 "register_operand" "d,d,d"))
1644 (match_operand:SI 3 "register_operand" "0,0,d")))
1645 (clobber (match_scratch:SI 4 "=X,X,l"))
1646 (clobber (match_scratch:SI 5 "=X,X,&d"))]
1647 "GENERATE_MADD_MSUB && !TARGET_MIPS16"
1652 [(set_attr "type" "imadd")
1653 (set_attr "accum_in" "3")
1654 (set_attr "mode" "SI")
1655 (set_attr "insn_count" "1,1,2")
1656 (set (attr "enabled")
1657 (cond [(and (eq_attr "alternative" "0")
1658 (match_test "!mips_lra_flag"))
1659 (const_string "yes")
1660 (and (eq_attr "alternative" "1")
1661 (match_test "mips_lra_flag"))
1662 (const_string "yes")
1663 (eq_attr "alternative" "2")
1664 (const_string "yes")]
1665 (const_string "no")))])
1667 ;; The same idea applies here. The middle alternative needs one less
1668 ;; clobber than the final alternative, so we add "*?" as a counterweight.
1669 (define_insn "*mul_acc_si_r3900"
1670 [(set (match_operand:SI 0 "register_operand" "=l*?*?,l,d*?,d?")
1671 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d,d")
1672 (match_operand:SI 2 "register_operand" "d,d,d,d"))
1673 (match_operand:SI 3 "register_operand" "0,0,l,d")))
1674 (clobber (match_scratch:SI 4 "=X,X,3,l"))
1675 (clobber (match_scratch:SI 5 "=X,X,X,&d"))]
1676 "TARGET_MIPS3900 && !TARGET_MIPS16"
1682 [(set_attr "type" "imadd")
1683 (set_attr "accum_in" "3")
1684 (set_attr "mode" "SI")
1685 (set_attr "insn_count" "1,1,1,2")
1686 (set (attr "enabled")
1687 (cond [(and (eq_attr "alternative" "0")
1688 (match_test "!mips_lra_flag"))
1689 (const_string "yes")
1690 (and (eq_attr "alternative" "1")
1691 (match_test "mips_lra_flag"))
1692 (const_string "yes")
1693 (eq_attr "alternative" "2,3")
1694 (const_string "yes")]
1695 (const_string "no")))])
1697 ;; Split *mul_acc_si if both the source and destination accumulator
1700 [(set (match_operand:SI 0 "d_operand")
1701 (plus:SI (mult:SI (match_operand:SI 1 "d_operand")
1702 (match_operand:SI 2 "d_operand"))
1703 (match_operand:SI 3 "d_operand")))
1704 (clobber (match_operand:SI 4 "lo_operand"))
1705 (clobber (match_operand:SI 5 "d_operand"))]
1707 [(parallel [(set (match_dup 5)
1708 (mult:SI (match_dup 1) (match_dup 2)))
1709 (clobber (match_dup 4))])
1710 (set (match_dup 0) (plus:SI (match_dup 5) (match_dup 3)))]
1713 (define_insn "*macc"
1714 [(set (match_operand:SI 0 "register_operand" "=l,d")
1715 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1716 (match_operand:SI 2 "register_operand" "d,d"))
1717 (match_operand:SI 3 "register_operand" "0,l")))
1718 (clobber (match_scratch:SI 4 "=X,3"))]
1721 if (which_alternative == 1)
1722 return "macc\t%0,%1,%2";
1723 else if (TARGET_MIPS5500)
1724 return "madd\t%1,%2";
1726 /* The VR4130 assumes that there is a two-cycle latency between a macc
1727 that "writes" to $0 and an instruction that reads from it. We avoid
1728 this by assigning to $1 instead. */
1729 return "%[macc\t%@,%1,%2%]";
1731 [(set_attr "type" "imadd")
1732 (set_attr "accum_in" "3")
1733 (set_attr "mode" "SI")])
1735 (define_insn "*msac"
1736 [(set (match_operand:SI 0 "register_operand" "=l,d")
1737 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1738 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1739 (match_operand:SI 3 "register_operand" "d,d"))))
1740 (clobber (match_scratch:SI 4 "=X,1"))]
1743 if (which_alternative == 1)
1744 return "msac\t%0,%2,%3";
1745 else if (TARGET_MIPS5500)
1746 return "msub\t%2,%3";
1748 return "msac\t$0,%2,%3";
1750 [(set_attr "type" "imadd")
1751 (set_attr "accum_in" "1")
1752 (set_attr "mode" "SI")])
1754 ;; An msac-like instruction implemented using negation and a macc.
1755 (define_insn_and_split "*msac_using_macc"
1756 [(set (match_operand:SI 0 "register_operand" "=l,d")
1757 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1758 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1759 (match_operand:SI 3 "register_operand" "d,d"))))
1760 (clobber (match_scratch:SI 4 "=X,1"))
1761 (clobber (match_scratch:SI 5 "=d,d"))]
1762 "ISA_HAS_MACC && !ISA_HAS_MSAC"
1764 "&& reload_completed"
1766 (neg:SI (match_dup 3)))
1769 (plus:SI (mult:SI (match_dup 2)
1772 (clobber (match_dup 4))])]
1774 [(set_attr "type" "imadd")
1775 (set_attr "accum_in" "1")
1776 (set_attr "insn_count" "2")])
1778 ;; Patterns generated by the define_peephole2 below.
1780 (define_insn "*macc2"
1781 [(set (match_operand:SI 0 "muldiv_target_operand" "=l")
1782 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1783 (match_operand:SI 2 "register_operand" "d"))
1785 (set (match_operand:SI 3 "register_operand" "=d")
1786 (plus:SI (mult:SI (match_dup 1)
1789 "ISA_HAS_MACC && reload_completed"
1791 [(set_attr "type" "imadd")
1792 (set_attr "accum_in" "0")
1793 (set_attr "mode" "SI")])
1795 (define_insn "*msac2"
1796 [(set (match_operand:SI 0 "muldiv_target_operand" "=l")
1797 (minus:SI (match_dup 0)
1798 (mult:SI (match_operand:SI 1 "register_operand" "d")
1799 (match_operand:SI 2 "register_operand" "d"))))
1800 (set (match_operand:SI 3 "register_operand" "=d")
1801 (minus:SI (match_dup 0)
1802 (mult:SI (match_dup 1)
1804 "ISA_HAS_MSAC && reload_completed"
1806 [(set_attr "type" "imadd")
1807 (set_attr "accum_in" "0")
1808 (set_attr "mode" "SI")])
1810 ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1814 ;; Operand 1: macc/msac
1815 ;; Operand 2: GPR (destination)
1818 [(set (match_operand:SI 0 "lo_operand")
1819 (match_operand:SI 1 "macc_msac_operand"))
1820 (clobber (scratch:SI))])
1821 (set (match_operand:SI 2 "d_operand")
1824 [(parallel [(set (match_dup 0)
1829 ;; When we have a three-address multiplication instruction, it should
1830 ;; be faster to do a separate multiply and add, rather than moving
1831 ;; something into LO in order to use a macc instruction.
1833 ;; This peephole needs a scratch register to cater for the case when one
1834 ;; of the multiplication operands is the same as the destination.
1836 ;; Operand 0: GPR (scratch)
1838 ;; Operand 2: GPR (addend)
1839 ;; Operand 3: GPR (destination)
1840 ;; Operand 4: macc/msac
1841 ;; Operand 5: new multiplication
1842 ;; Operand 6: new addition/subtraction
1844 [(match_scratch:SI 0 "d")
1845 (set (match_operand:SI 1 "lo_operand")
1846 (match_operand:SI 2 "d_operand"))
1849 [(set (match_operand:SI 3 "d_operand")
1850 (match_operand:SI 4 "macc_msac_operand"))
1851 (clobber (match_dup 1))])]
1852 "ISA_HAS_MUL3 && peep2_reg_dead_p (2, operands[1])"
1853 [(parallel [(set (match_dup 0)
1855 (clobber (match_dup 1))])
1859 operands[5] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1860 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1861 operands[2], operands[0]);
1864 ;; Same as above, except LO is the initial target of the macc.
1866 ;; Operand 0: GPR (scratch)
1868 ;; Operand 2: GPR (addend)
1869 ;; Operand 3: macc/msac
1870 ;; Operand 4: GPR (destination)
1871 ;; Operand 5: new multiplication
1872 ;; Operand 6: new addition/subtraction
1874 [(match_scratch:SI 0 "d")
1875 (set (match_operand:SI 1 "lo_operand")
1876 (match_operand:SI 2 "d_operand"))
1880 (match_operand:SI 3 "macc_msac_operand"))
1881 (clobber (scratch:SI))])
1883 (set (match_operand:SI 4 "d_operand")
1885 "ISA_HAS_MUL3 && peep2_reg_dead_p (3, operands[1])"
1886 [(parallel [(set (match_dup 0)
1888 (clobber (match_dup 1))])
1892 operands[5] = XEXP (operands[3], GET_CODE (operands[3]) == PLUS ? 0 : 1);
1893 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
1894 operands[2], operands[0]);
1897 ;; See the comment above *mul_add_si for details.
1898 (define_insn "*mul_sub_si"
1899 [(set (match_operand:SI 0 "register_operand" "=l*?*?,l,d?")
1900 (minus:SI (match_operand:SI 1 "register_operand" "0,0,d")
1901 (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1902 (match_operand:SI 3 "register_operand" "d,d,d"))))
1903 (clobber (match_scratch:SI 4 "=X,X,l"))
1904 (clobber (match_scratch:SI 5 "=X,X,&d"))]
1905 "GENERATE_MADD_MSUB"
1910 [(set_attr "type" "imadd")
1911 (set_attr "accum_in" "1")
1912 (set_attr "mode" "SI")
1913 (set_attr "insn_count" "1,1,2")
1914 (set (attr "enabled")
1915 (cond [(and (eq_attr "alternative" "0")
1916 (match_test "!mips_lra_flag"))
1917 (const_string "yes")
1918 (and (eq_attr "alternative" "1")
1919 (match_test "mips_lra_flag"))
1920 (const_string "yes")
1921 (eq_attr "alternative" "2")
1922 (const_string "yes")]
1923 (const_string "no")))])
1925 ;; Split *mul_sub_si if both the source and destination accumulator
1928 [(set (match_operand:SI 0 "d_operand")
1929 (minus:SI (match_operand:SI 1 "d_operand")
1930 (mult:SI (match_operand:SI 2 "d_operand")
1931 (match_operand:SI 3 "d_operand"))))
1932 (clobber (match_operand:SI 4 "lo_operand"))
1933 (clobber (match_operand:SI 5 "d_operand"))]
1935 [(parallel [(set (match_dup 5)
1936 (mult:SI (match_dup 2) (match_dup 3)))
1937 (clobber (match_dup 4))])
1938 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 5)))]
1941 (define_insn "*muls"
1942 [(set (match_operand:SI 0 "register_operand" "=l,d")
1943 (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1944 (match_operand:SI 2 "register_operand" "d,d"))))
1945 (clobber (match_scratch:SI 3 "=X,l"))]
1950 [(set_attr "type" "imul,imul3")
1951 (set_attr "mode" "SI")])
1953 (define_expand "<u>mulsidi3"
1954 [(set (match_operand:DI 0 "register_operand")
1955 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1956 (any_extend:DI (match_operand:SI 2 "register_operand"))))]
1957 "mips_mulsidi3_gen_fn (<CODE>) != NULL"
1959 mulsidi3_gen_fn fn = mips_mulsidi3_gen_fn (<CODE>);
1960 emit_insn (fn (operands[0], operands[1], operands[2]));
1964 (define_expand "<u>mulsidi3_32bit_mips16"
1965 [(set (match_operand:DI 0 "register_operand")
1966 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1967 (any_extend:DI (match_operand:SI 2 "register_operand"))))]
1968 "!TARGET_64BIT && TARGET_MIPS16"
1972 hilo = gen_rtx_REG (DImode, MD_REG_FIRST);
1973 emit_insn (gen_<u>mulsidi3_32bit (hilo, operands[1], operands[2]));
1974 emit_move_insn (operands[0], hilo);
1978 ;; As well as being named patterns, these instructions are used by the
1979 ;; __builtin_mips_mult<u>() functions. We must always make those functions
1980 ;; available if !TARGET_64BIT && ISA_HAS_DSP.
1981 (define_insn "<u>mulsidi3_32bit"
1982 [(set (match_operand:DI 0 "muldiv_target_operand" "=ka")
1983 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1984 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1985 "!TARGET_64BIT && (!TARGET_FIX_R4000 || ISA_HAS_DSP)"
1987 if (ISA_HAS_DSP_MULT)
1988 return "mult<u>\t%q0,%1,%2";
1990 return "mult<u>\t%1,%2";
1992 [(set_attr "type" "imul")
1993 (set_attr "mode" "SI")])
1995 (define_insn "<u>mulsidi3_32bit_r4000"
1996 [(set (match_operand:DI 0 "register_operand" "=d")
1997 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1998 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1999 (clobber (match_scratch:DI 3 "=x"))]
2000 "!TARGET_64BIT && TARGET_FIX_R4000 && !ISA_HAS_DSP"
2001 "mult<u>\t%1,%2\;mflo\t%L0\;mfhi\t%M0"
2002 [(set_attr "type" "imul")
2003 (set_attr "mode" "SI")
2004 (set_attr "insn_count" "3")])
2006 (define_insn_and_split "<u>mulsidi3_64bit"
2007 [(set (match_operand:DI 0 "register_operand" "=d")
2008 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2009 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
2010 (clobber (match_scratch:TI 3 "=x"))
2011 (clobber (match_scratch:DI 4 "=d"))]
2012 "TARGET_64BIT && !TARGET_FIX_R4000 && !ISA_HAS_DMUL3 && !TARGET_MIPS16"
2014 "&& reload_completed"
2017 emit_insn (gen_<u>mulsidi3_64bit_split (operands[0], operands[1],
2018 operands[2], operands[4]));
2021 [(set_attr "type" "imul")
2022 (set_attr "mode" "SI")
2023 (set (attr "insn_count")
2024 (if_then_else (match_test "ISA_HAS_EXT_INS")
2028 (define_expand "<u>mulsidi3_64bit_mips16"
2029 [(set (match_operand:DI 0 "register_operand")
2030 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
2031 (any_extend:DI (match_operand:SI 2 "register_operand"))))]
2032 "TARGET_64BIT && TARGET_MIPS16"
2034 emit_insn (gen_<u>mulsidi3_64bit_split (operands[0], operands[1],
2035 operands[2], gen_reg_rtx (DImode)));
2039 (define_expand "<u>mulsidi3_64bit_split"
2040 [(set (match_operand:DI 0 "register_operand")
2041 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
2042 (any_extend:DI (match_operand:SI 2 "register_operand"))))
2043 (clobber (match_operand:DI 3 "register_operand"))]
2048 hilo = gen_rtx_REG (TImode, MD_REG_FIRST);
2049 emit_insn (gen_<u>mulsidi3_64bit_hilo (hilo, operands[1], operands[2]));
2051 emit_move_insn (operands[0], gen_rtx_REG (DImode, LO_REGNUM));
2052 emit_insn (gen_mfhidi_ti (operands[3], hilo));
2054 if (ISA_HAS_EXT_INS)
2055 emit_insn (gen_insvdi (operands[0], GEN_INT (32), GEN_INT (32),
2059 /* Zero-extend the low part. */
2060 mips_emit_binary (ASHIFT, operands[0], operands[0], GEN_INT (32));
2061 mips_emit_binary (LSHIFTRT, operands[0], operands[0], GEN_INT (32));
2063 /* Shift the high part into place. */
2064 mips_emit_binary (ASHIFT, operands[3], operands[3], GEN_INT (32));
2066 /* OR the two halves together. */
2067 mips_emit_binary (IOR, operands[0], operands[0], operands[3]);
2072 (define_insn "<u>mulsidi3_64bit_hilo"
2073 [(set (match_operand:TI 0 "muldiv_target_operand" "=x")
2076 (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2077 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))]
2079 "TARGET_64BIT && !TARGET_FIX_R4000"
2081 [(set_attr "type" "imul")
2082 (set_attr "mode" "SI")])
2084 ;; See comment before the ISA_HAS_DMUL3 case in mips_mulsidi3_gen_fn.
2085 (define_insn "mulsidi3_64bit_dmul"
2086 [(set (match_operand:DI 0 "register_operand" "=d")
2087 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2088 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
2089 (clobber (match_scratch:DI 3 "=l"))]
2092 [(set_attr "type" "imul3")
2093 (set_attr "mode" "DI")])
2095 ;; Widening multiply with negation.
2096 (define_insn "*muls<u>_di"
2097 [(set (match_operand:DI 0 "muldiv_target_operand" "=x")
2100 (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2101 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
2102 "!TARGET_64BIT && ISA_HAS_MULS"
2104 [(set_attr "type" "imul")
2105 (set_attr "mode" "SI")])
2107 ;; As well as being named patterns, these instructions are used by the
2108 ;; __builtin_mips_msub<u>() functions. We must always make those functions
2109 ;; available if !TARGET_64BIT && ISA_HAS_DSP.
2111 ;; This leads to a slight inconsistency. We honor any tuning overrides
2112 ;; in GENERATE_MADD_MSUB for -mno-dsp, but always ignore them for -mdsp,
2113 ;; even if !ISA_HAS_DSP_MULT.
2114 (define_insn "<u>msubsidi4"
2115 [(set (match_operand:DI 0 "muldiv_target_operand" "=ka")
2117 (match_operand:DI 3 "muldiv_target_operand" "0")
2119 (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2120 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
2121 "!TARGET_64BIT && (ISA_HAS_MSAC || GENERATE_MADD_MSUB || ISA_HAS_DSP)"
2123 if (ISA_HAS_DSP_MULT)
2124 return "msub<u>\t%q0,%1,%2";
2125 else if (TARGET_MIPS5500 || GENERATE_MADD_MSUB)
2126 return "msub<u>\t%1,%2";
2128 return "msac<u>\t$0,%1,%2";
2130 [(set_attr "type" "imadd")
2131 (set_attr "accum_in" "3")
2132 (set_attr "mode" "SI")])
2134 ;; _highpart patterns
2136 (define_expand "<su>mulsi3_highpart"
2137 [(set (match_operand:SI 0 "register_operand")
2140 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
2141 (any_extend:DI (match_operand:SI 2 "register_operand")))
2146 emit_insn (gen_<su>mulsi3_highpart_mulhi_internal (operands[0],
2149 else if (TARGET_MIPS16)
2150 emit_insn (gen_<su>mulsi3_highpart_split (operands[0], operands[1],
2153 emit_insn (gen_<su>mulsi3_highpart_internal (operands[0], operands[1],
2158 (define_insn_and_split "<su>mulsi3_highpart_internal"
2159 [(set (match_operand:SI 0 "register_operand" "=d")
2162 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2163 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
2165 (clobber (match_scratch:SI 3 "=l"))]
2166 "!ISA_HAS_MULHI && !TARGET_MIPS16"
2167 { return TARGET_FIX_R4000 ? "mult<u>\t%1,%2\n\tmfhi\t%0" : "#"; }
2168 "&& reload_completed && !TARGET_FIX_R4000"
2171 emit_insn (gen_<su>mulsi3_highpart_split (operands[0], operands[1],
2175 [(set_attr "type" "imul")
2176 (set_attr "mode" "SI")
2177 (set_attr "insn_count" "2")])
2179 (define_expand "<su>mulsi3_highpart_split"
2180 [(set (match_operand:SI 0 "register_operand")
2183 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
2184 (any_extend:DI (match_operand:SI 2 "register_operand")))
2192 hilo = gen_rtx_REG (TImode, MD_REG_FIRST);
2193 emit_insn (gen_<u>mulsidi3_64bit_hilo (hilo, operands[1], operands[2]));
2194 emit_insn (gen_mfhisi_ti (operands[0], hilo));
2198 hilo = gen_rtx_REG (DImode, MD_REG_FIRST);
2199 emit_insn (gen_<u>mulsidi3_32bit (hilo, operands[1], operands[2]));
2200 emit_insn (gen_mfhisi_di (operands[0], hilo));
2205 (define_insn "<su>mulsi3_highpart_mulhi_internal"
2206 [(set (match_operand:SI 0 "register_operand" "=d")
2210 (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2211 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
2213 (clobber (match_scratch:SI 3 "=l"))]
2215 "mulhi<u>\t%0,%1,%2"
2216 [(set_attr "type" "imul3")
2217 (set_attr "mode" "SI")])
2219 (define_insn "*<su>mulsi3_highpart_neg_mulhi_internal"
2220 [(set (match_operand:SI 0 "register_operand" "=d")
2225 (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2226 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
2228 (clobber (match_scratch:SI 3 "=l"))]
2230 "mulshi<u>\t%0,%1,%2"
2231 [(set_attr "type" "imul3")
2232 (set_attr "mode" "SI")])
2234 ;; Disable unsigned multiplication for -mfix-vr4120. This is for VR4120
2235 ;; errata MD(0), which says that dmultu does not always produce the
2237 (define_expand "<su>muldi3_highpart"
2238 [(set (match_operand:DI 0 "register_operand")
2241 (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
2242 (any_extend:TI (match_operand:DI 2 "register_operand")))
2244 "ISA_HAS_DMULT && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
2247 emit_insn (gen_<su>muldi3_highpart_split (operands[0], operands[1],
2250 emit_insn (gen_<su>muldi3_highpart_internal (operands[0], operands[1],
2255 (define_insn_and_split "<su>muldi3_highpart_internal"
2256 [(set (match_operand:DI 0 "register_operand" "=d")
2259 (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
2260 (any_extend:TI (match_operand:DI 2 "register_operand" "d")))
2262 (clobber (match_scratch:DI 3 "=l"))]
2265 && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
2266 { return TARGET_FIX_R4000 ? "dmult<u>\t%1,%2\n\tmfhi\t%0" : "#"; }
2267 "&& reload_completed && !TARGET_FIX_R4000"
2270 emit_insn (gen_<su>muldi3_highpart_split (operands[0], operands[1],
2274 [(set_attr "type" "imul")
2275 (set_attr "mode" "DI")
2276 (set_attr "insn_count" "2")])
2278 (define_expand "<su>muldi3_highpart_split"
2279 [(set (match_operand:DI 0 "register_operand")
2282 (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
2283 (any_extend:TI (match_operand:DI 2 "register_operand")))
2289 hilo = gen_rtx_REG (TImode, MD_REG_FIRST);
2290 emit_insn (gen_<u>mulditi3_internal (hilo, operands[1], operands[2]));
2291 emit_insn (gen_mfhidi_ti (operands[0], hilo));
2295 (define_expand "<u>mulditi3"
2296 [(set (match_operand:TI 0 "register_operand")
2297 (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
2298 (any_extend:TI (match_operand:DI 2 "register_operand"))))]
2299 "ISA_HAS_DMULT && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
2305 hilo = gen_rtx_REG (TImode, MD_REG_FIRST);
2306 emit_insn (gen_<u>mulditi3_internal (hilo, operands[1], operands[2]));
2307 emit_move_insn (operands[0], hilo);
2309 else if (TARGET_FIX_R4000)
2310 emit_insn (gen_<u>mulditi3_r4000 (operands[0], operands[1], operands[2]));
2312 emit_insn (gen_<u>mulditi3_internal (operands[0], operands[1],
2317 (define_insn "<u>mulditi3_internal"
2318 [(set (match_operand:TI 0 "muldiv_target_operand" "=x")
2319 (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
2320 (any_extend:TI (match_operand:DI 2 "register_operand" "d"))))]
2322 && !TARGET_FIX_R4000
2323 && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
2325 [(set_attr "type" "imul")
2326 (set_attr "mode" "DI")])
2328 (define_insn "<u>mulditi3_r4000"
2329 [(set (match_operand:TI 0 "register_operand" "=d")
2330 (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
2331 (any_extend:TI (match_operand:DI 2 "register_operand" "d"))))
2332 (clobber (match_scratch:TI 3 "=x"))]
2335 && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
2336 "dmult<u>\t%1,%2\;mflo\t%L0\;mfhi\t%M0"
2337 [(set_attr "type" "imul")
2338 (set_attr "mode" "DI")
2339 (set_attr "insn_count" "3")])
2341 ;; The R4650 supports a 32-bit multiply/ 64-bit accumulate
2342 ;; instruction. The HI/LO registers are used as a 64-bit accumulator.
2344 (define_insn "madsi"
2345 [(set (match_operand:SI 0 "register_operand" "+l")
2346 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
2347 (match_operand:SI 2 "register_operand" "d"))
2351 [(set_attr "type" "imadd")
2352 (set_attr "accum_in" "0")
2353 (set_attr "mode" "SI")])
2355 ;; See the comment above <u>msubsidi4 for the relationship between
2356 ;; ISA_HAS_DSP and ISA_HAS_DSP_MULT.
2357 (define_insn "<u>maddsidi4"
2358 [(set (match_operand:DI 0 "muldiv_target_operand" "=ka")
2360 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2361 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
2362 (match_operand:DI 3 "muldiv_target_operand" "0")))]
2363 "(TARGET_MAD || ISA_HAS_MACC || GENERATE_MADD_MSUB || ISA_HAS_DSP)
2367 return "mad<u>\t%1,%2";
2368 else if (ISA_HAS_DSP_MULT)
2369 return "madd<u>\t%q0,%1,%2";
2370 else if (GENERATE_MADD_MSUB || TARGET_MIPS5500)
2371 return "madd<u>\t%1,%2";
2373 /* See comment in *macc. */
2374 return "%[macc<u>\t%@,%1,%2%]";
2376 [(set_attr "type" "imadd")
2377 (set_attr "accum_in" "3")
2378 (set_attr "mode" "SI")])
2380 ;; Floating point multiply accumulate instructions.
2382 (define_insn "*madd4<mode>"
2383 [(set (match_operand:ANYF 0 "register_operand" "=f")
2384 (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
2385 (match_operand:ANYF 2 "register_operand" "f"))
2386 (match_operand:ANYF 3 "register_operand" "f")))]
2387 "ISA_HAS_FP_MADD4_MSUB4 && TARGET_FUSED_MADD"
2388 "madd.<fmt>\t%0,%3,%1,%2"
2389 [(set_attr "type" "fmadd")
2390 (set_attr "accum_in" "3")
2391 (set_attr "mode" "<UNITMODE>")])
2393 (define_insn "*madd3<mode>"
2394 [(set (match_operand:ANYF 0 "register_operand" "=f")
2395 (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
2396 (match_operand:ANYF 2 "register_operand" "f"))
2397 (match_operand:ANYF 3 "register_operand" "0")))]
2398 "ISA_HAS_FP_MADD3_MSUB3 && TARGET_FUSED_MADD"
2399 "madd.<fmt>\t%0,%1,%2"
2400 [(set_attr "type" "fmadd")
2401 (set_attr "accum_in" "3")
2402 (set_attr "mode" "<UNITMODE>")])
2404 (define_insn "*msub4<mode>"
2405 [(set (match_operand:ANYF 0 "register_operand" "=f")
2406 (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
2407 (match_operand:ANYF 2 "register_operand" "f"))
2408 (match_operand:ANYF 3 "register_operand" "f")))]
2409 "ISA_HAS_FP_MADD4_MSUB4 && TARGET_FUSED_MADD"
2410 "msub.<fmt>\t%0,%3,%1,%2"
2411 [(set_attr "type" "fmadd")
2412 (set_attr "accum_in" "3")
2413 (set_attr "mode" "<UNITMODE>")])
2415 (define_insn "*msub3<mode>"
2416 [(set (match_operand:ANYF 0 "register_operand" "=f")
2417 (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
2418 (match_operand:ANYF 2 "register_operand" "f"))
2419 (match_operand:ANYF 3 "register_operand" "0")))]
2420 "ISA_HAS_FP_MADD3_MSUB3 && TARGET_FUSED_MADD"
2421 "msub.<fmt>\t%0,%1,%2"
2422 [(set_attr "type" "fmadd")
2423 (set_attr "accum_in" "3")
2424 (set_attr "mode" "<UNITMODE>")])
2426 (define_insn "*nmadd4<mode>"
2427 [(set (match_operand:ANYF 0 "register_operand" "=f")
2428 (neg:ANYF (plus:ANYF
2429 (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
2430 (match_operand:ANYF 2 "register_operand" "f"))
2431 (match_operand:ANYF 3 "register_operand" "f"))))]
2432 "ISA_HAS_NMADD4_NMSUB4
2433 && TARGET_FUSED_MADD
2434 && HONOR_SIGNED_ZEROS (<MODE>mode)
2435 && !HONOR_NANS (<MODE>mode)"
2436 "nmadd.<fmt>\t%0,%3,%1,%2"
2437 [(set_attr "type" "fmadd")
2438 (set_attr "accum_in" "3")
2439 (set_attr "mode" "<UNITMODE>")])
2441 (define_insn "*nmadd3<mode>"
2442 [(set (match_operand:ANYF 0 "register_operand" "=f")
2443 (neg:ANYF (plus:ANYF
2444 (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
2445 (match_operand:ANYF 2 "register_operand" "f"))
2446 (match_operand:ANYF 3 "register_operand" "0"))))]
2447 "ISA_HAS_NMADD3_NMSUB3
2448 && TARGET_FUSED_MADD
2449 && HONOR_SIGNED_ZEROS (<MODE>mode)
2450 && !HONOR_NANS (<MODE>mode)"
2451 "nmadd.<fmt>\t%0,%1,%2"
2452 [(set_attr "type" "fmadd")
2453 (set_attr "accum_in" "3")
2454 (set_attr "mode" "<UNITMODE>")])
2456 (define_insn "*nmadd4<mode>_fastmath"
2457 [(set (match_operand:ANYF 0 "register_operand" "=f")
2459 (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
2460 (match_operand:ANYF 2 "register_operand" "f"))
2461 (match_operand:ANYF 3 "register_operand" "f")))]
2462 "ISA_HAS_NMADD4_NMSUB4
2463 && TARGET_FUSED_MADD
2464 && !HONOR_SIGNED_ZEROS (<MODE>mode)
2465 && !HONOR_NANS (<MODE>mode)"
2466 "nmadd.<fmt>\t%0,%3,%1,%2"
2467 [(set_attr "type" "fmadd")
2468 (set_attr "accum_in" "3")
2469 (set_attr "mode" "<UNITMODE>")])
2471 (define_insn "*nmadd3<mode>_fastmath"
2472 [(set (match_operand:ANYF 0 "register_operand" "=f")
2474 (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
2475 (match_operand:ANYF 2 "register_operand" "f"))
2476 (match_operand:ANYF 3 "register_operand" "0")))]
2477 "ISA_HAS_NMADD3_NMSUB3
2478 && TARGET_FUSED_MADD
2479 && !HONOR_SIGNED_ZEROS (<MODE>mode)
2480 && !HONOR_NANS (<MODE>mode)"
2481 "nmadd.<fmt>\t%0,%1,%2"
2482 [(set_attr "type" "fmadd")
2483 (set_attr "accum_in" "3")
2484 (set_attr "mode" "<UNITMODE>")])
2486 (define_insn "*nmsub4<mode>"
2487 [(set (match_operand:ANYF 0 "register_operand" "=f")
2488 (neg:ANYF (minus:ANYF
2489 (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
2490 (match_operand:ANYF 3 "register_operand" "f"))
2491 (match_operand:ANYF 1 "register_operand" "f"))))]
2492 "ISA_HAS_NMADD4_NMSUB4
2493 && TARGET_FUSED_MADD
2494 && HONOR_SIGNED_ZEROS (<MODE>mode)
2495 && !HONOR_NANS (<MODE>mode)"
2496 "nmsub.<fmt>\t%0,%1,%2,%3"
2497 [(set_attr "type" "fmadd")
2498 (set_attr "accum_in" "1")
2499 (set_attr "mode" "<UNITMODE>")])
2501 (define_insn "*nmsub3<mode>"
2502 [(set (match_operand:ANYF 0 "register_operand" "=f")
2503 (neg:ANYF (minus:ANYF
2504 (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
2505 (match_operand:ANYF 3 "register_operand" "f"))
2506 (match_operand:ANYF 1 "register_operand" "0"))))]
2507 "ISA_HAS_NMADD3_NMSUB3
2508 && TARGET_FUSED_MADD
2509 && HONOR_SIGNED_ZEROS (<MODE>mode)
2510 && !HONOR_NANS (<MODE>mode)"
2511 "nmsub.<fmt>\t%0,%1,%2"
2512 [(set_attr "type" "fmadd")
2513 (set_attr "accum_in" "1")
2514 (set_attr "mode" "<UNITMODE>")])
2516 (define_insn "*nmsub4<mode>_fastmath"
2517 [(set (match_operand:ANYF 0 "register_operand" "=f")
2519 (match_operand:ANYF 1 "register_operand" "f")
2520 (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
2521 (match_operand:ANYF 3 "register_operand" "f"))))]
2522 "ISA_HAS_NMADD4_NMSUB4
2523 && TARGET_FUSED_MADD
2524 && !HONOR_SIGNED_ZEROS (<MODE>mode)
2525 && !HONOR_NANS (<MODE>mode)"
2526 "nmsub.<fmt>\t%0,%1,%2,%3"
2527 [(set_attr "type" "fmadd")
2528 (set_attr "accum_in" "1")
2529 (set_attr "mode" "<UNITMODE>")])
2531 (define_insn "*nmsub3<mode>_fastmath"
2532 [(set (match_operand:ANYF 0 "register_operand" "=f")
2534 (match_operand:ANYF 1 "register_operand" "f")
2535 (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
2536 (match_operand:ANYF 3 "register_operand" "0"))))]
2537 "ISA_HAS_NMADD3_NMSUB3
2538 && TARGET_FUSED_MADD
2539 && !HONOR_SIGNED_ZEROS (<MODE>mode)
2540 && !HONOR_NANS (<MODE>mode)"
2541 "nmsub.<fmt>\t%0,%1,%2"
2542 [(set_attr "type" "fmadd")
2543 (set_attr "accum_in" "1")
2544 (set_attr "mode" "<UNITMODE>")])
2547 ;; ....................
2549 ;; DIVISION and REMAINDER
2551 ;; ....................
2554 (define_expand "div<mode>3"
2555 [(set (match_operand:ANYF 0 "register_operand")
2556 (div:ANYF (match_operand:ANYF 1 "reg_or_1_operand")
2557 (match_operand:ANYF 2 "register_operand")))]
2558 "<divide_condition>"
2560 if (const_1_operand (operands[1], <MODE>mode))
2561 if (!(ISA_HAS_FP_RECIP_RSQRT (<MODE>mode)
2562 && flag_unsafe_math_optimizations))
2563 operands[1] = force_reg (<MODE>mode, operands[1]);
2566 ;; These patterns work around the early SB-1 rev2 core "F1" erratum:
2568 ;; If an mfc1 or dmfc1 happens to access the floating point register
2569 ;; file at the same time a long latency operation (div, sqrt, recip,
2570 ;; sqrt) iterates an intermediate result back through the floating
2571 ;; point register file bypass, then instead returning the correct
2572 ;; register value the mfc1 or dmfc1 operation returns the intermediate
2573 ;; result of the long latency operation.
2575 ;; The workaround is to insert an unconditional 'mov' from/to the
2576 ;; long latency op destination register.
2578 (define_insn "*div<mode>3"
2579 [(set (match_operand:ANYF 0 "register_operand" "=f")
2580 (div:ANYF (match_operand:ANYF 1 "register_operand" "f")
2581 (match_operand:ANYF 2 "register_operand" "f")))]
2582 "<divide_condition>"
2585 return "div.<fmt>\t%0,%1,%2\;mov.<fmt>\t%0,%0";
2587 return "div.<fmt>\t%0,%1,%2";
2589 [(set_attr "type" "fdiv")
2590 (set_attr "mode" "<UNITMODE>")
2591 (set (attr "insn_count")
2592 (if_then_else (match_test "TARGET_FIX_SB1")
2596 (define_insn "*recip<mode>3"
2597 [(set (match_operand:ANYF 0 "register_operand" "=f")
2598 (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
2599 (match_operand:ANYF 2 "register_operand" "f")))]
2600 "ISA_HAS_FP_RECIP_RSQRT (<MODE>mode) && flag_unsafe_math_optimizations"
2603 return "recip.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
2605 return "recip.<fmt>\t%0,%2";
2607 [(set_attr "type" "frdiv")
2608 (set_attr "mode" "<UNITMODE>")
2609 (set (attr "insn_count")
2610 (if_then_else (match_test "TARGET_FIX_SB1")
2614 ;; VR4120 errata MD(A1): signed division instructions do not work correctly
2615 ;; with negative operands. We use special libgcc functions instead.
2616 (define_expand "divmod<mode>4"
2618 [(set (match_operand:GPR 0 "register_operand")
2619 (div:GPR (match_operand:GPR 1 "register_operand")
2620 (match_operand:GPR 2 "register_operand")))
2621 (set (match_operand:GPR 3 "register_operand")
2622 (mod:GPR (match_dup 1)
2624 "ISA_HAS_<D>DIV && !TARGET_FIX_VR4120"
2628 rtx lo = gen_rtx_REG (<MODE>mode, LO_REGNUM);
2629 emit_insn (gen_divmod<mode>4_mips16 (operands[0], operands[1],
2630 operands[2], operands[3], lo));
2635 (define_insn_and_split "*divmod<mode>4"
2636 [(set (match_operand:GPR 0 "register_operand" "=l")
2637 (div:GPR (match_operand:GPR 1 "register_operand" "d")
2638 (match_operand:GPR 2 "register_operand" "d")))
2639 (set (match_operand:GPR 3 "register_operand" "=d")
2640 (mod:GPR (match_dup 1)
2642 "ISA_HAS_<D>DIV && !TARGET_FIX_VR4120 && !TARGET_MIPS16"
2644 "&& reload_completed"
2647 emit_insn (gen_divmod<mode>4_split (operands[3], operands[1], operands[2]));
2650 [(set_attr "type" "idiv")
2651 (set_attr "mode" "<MODE>")
2652 (set_attr "insn_count" "2")])
2654 ;; Expand generates divmod instructions for individual division and modulus
2655 ;; operations. We then rely on CSE to reuse earlier divmods where possible.
2656 ;; This means that, when generating MIPS16 code, it is better not to expose
2657 ;; the fixed LO register until after CSE has finished. However, it's still
2658 ;; better to split before register allocation, so that we don't allocate
2659 ;; one of the scarce MIPS16 registers to an unused result.
2660 (define_insn_and_split "divmod<mode>4_mips16"
2661 [(set (match_operand:GPR 0 "register_operand" "=d")
2662 (div:GPR (match_operand:GPR 1 "register_operand" "d")
2663 (match_operand:GPR 2 "register_operand" "d")))
2664 (set (match_operand:GPR 3 "register_operand" "=d")
2665 (mod:GPR (match_dup 1)
2667 (clobber (match_operand:GPR 4 "lo_operand" "=l"))]
2668 "ISA_HAS_<D>DIV && !TARGET_FIX_VR4120 && TARGET_MIPS16"
2670 "&& cse_not_expected"
2673 emit_insn (gen_divmod<mode>4_split (operands[3], operands[1], operands[2]));
2674 emit_move_insn (operands[0], operands[4]);
2677 [(set_attr "type" "idiv")
2678 (set_attr "mode" "<MODE>")
2679 (set_attr "insn_count" "3")])
2681 (define_expand "udivmod<mode>4"
2683 [(set (match_operand:GPR 0 "register_operand")
2684 (udiv:GPR (match_operand:GPR 1 "register_operand")
2685 (match_operand:GPR 2 "register_operand")))
2686 (set (match_operand:GPR 3 "register_operand")
2687 (umod:GPR (match_dup 1)
2689 "ISA_HAS_<D>DIV && !TARGET_FIX_VR4120"
2693 rtx lo = gen_rtx_REG (<MODE>mode, LO_REGNUM);
2694 emit_insn (gen_udivmod<mode>4_mips16 (operands[0], operands[1],
2695 operands[2], operands[3], lo));
2700 (define_insn_and_split "*udivmod<mode>4"
2701 [(set (match_operand:GPR 0 "register_operand" "=l")
2702 (udiv:GPR (match_operand:GPR 1 "register_operand" "d")
2703 (match_operand:GPR 2 "register_operand" "d")))
2704 (set (match_operand:GPR 3 "register_operand" "=d")
2705 (umod:GPR (match_dup 1)
2707 "ISA_HAS_<D>DIV && !TARGET_MIPS16"
2712 emit_insn (gen_udivmod<mode>4_split (operands[3], operands[1], operands[2]));
2715 [(set_attr "type" "idiv")
2716 (set_attr "mode" "<MODE>")
2717 (set_attr "insn_count" "2")])
2719 ;; See the comment above "divmod<mode>4_mips16" for the split timing.
2720 (define_insn_and_split "udivmod<mode>4_mips16"
2721 [(set (match_operand:GPR 0 "register_operand" "=d")
2722 (udiv:GPR (match_operand:GPR 1 "register_operand" "d")
2723 (match_operand:GPR 2 "register_operand" "d")))
2724 (set (match_operand:GPR 3 "register_operand" "=d")
2725 (umod:GPR (match_dup 1)
2727 (clobber (match_operand:GPR 4 "lo_operand" "=l"))]
2728 "ISA_HAS_<D>DIV && TARGET_MIPS16"
2733 emit_insn (gen_udivmod<mode>4_split (operands[3], operands[1], operands[2]));
2734 emit_move_insn (operands[0], operands[4]);
2737 [(set_attr "type" "idiv")
2738 (set_attr "mode" "<MODE>")
2739 (set_attr "insn_count" "3")])
2741 (define_expand "<u>divmod<mode>4_split"
2742 [(set (match_operand:GPR 0 "register_operand")
2743 (any_mod:GPR (match_operand:GPR 1 "register_operand")
2744 (match_operand:GPR 2 "register_operand")))]
2751 hilo = gen_rtx_REG (TImode, MD_REG_FIRST);
2752 emit_insn (gen_<u>divmod<mode>4_hilo_ti (hilo, operands[1],
2754 emit_insn (gen_mfhi<mode>_ti (operands[0], hilo));
2758 hilo = gen_rtx_REG (DImode, MD_REG_FIRST);
2759 emit_insn (gen_<u>divmod<mode>4_hilo_di (hilo, operands[1],
2761 emit_insn (gen_mfhi<mode>_di (operands[0], hilo));
2766 (define_insn "<u>divmod<GPR:mode>4_hilo_<HILO:mode>"
2767 [(set (match_operand:HILO 0 "muldiv_target_operand" "=x")
2769 [(any_div:GPR (match_operand:GPR 1 "register_operand" "d")
2770 (match_operand:GPR 2 "register_operand" "d"))]
2772 "ISA_HAS_<GPR:D>DIV"
2773 { return mips_output_division ("<GPR:d>div<u>\t%.,%1,%2", operands); }
2774 [(set_attr "type" "idiv")
2775 (set_attr "mode" "<GPR:MODE>")])
2778 ;; ....................
2782 ;; ....................
2784 ;; These patterns work around the early SB-1 rev2 core "F1" erratum (see
2785 ;; "*div[sd]f3" comment for details).
2787 (define_insn "sqrt<mode>2"
2788 [(set (match_operand:ANYF 0 "register_operand" "=f")
2789 (sqrt:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2793 return "sqrt.<fmt>\t%0,%1\;mov.<fmt>\t%0,%0";
2795 return "sqrt.<fmt>\t%0,%1";
2797 [(set_attr "type" "fsqrt")
2798 (set_attr "mode" "<UNITMODE>")
2799 (set (attr "insn_count")
2800 (if_then_else (match_test "TARGET_FIX_SB1")
2804 (define_insn "*rsqrt<mode>a"
2805 [(set (match_operand:ANYF 0 "register_operand" "=f")
2806 (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
2807 (sqrt:ANYF (match_operand:ANYF 2 "register_operand" "f"))))]
2808 "ISA_HAS_FP_RECIP_RSQRT (<MODE>mode) && flag_unsafe_math_optimizations"
2811 return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
2813 return "rsqrt.<fmt>\t%0,%2";
2815 [(set_attr "type" "frsqrt")
2816 (set_attr "mode" "<UNITMODE>")
2817 (set (attr "insn_count")
2818 (if_then_else (match_test "TARGET_FIX_SB1")
2822 (define_insn "*rsqrt<mode>b"
2823 [(set (match_operand:ANYF 0 "register_operand" "=f")
2824 (sqrt:ANYF (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
2825 (match_operand:ANYF 2 "register_operand" "f"))))]
2826 "ISA_HAS_FP_RECIP_RSQRT (<MODE>mode) && flag_unsafe_math_optimizations"
2829 return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
2831 return "rsqrt.<fmt>\t%0,%2";
2833 [(set_attr "type" "frsqrt")
2834 (set_attr "mode" "<UNITMODE>")
2835 (set (attr "insn_count")
2836 (if_then_else (match_test "TARGET_FIX_SB1")
2841 ;; ....................
2845 ;; ....................
2847 ;; Do not use the integer abs macro instruction, since that signals an
2848 ;; exception on -2147483648 (sigh).
2850 ;; The "legacy" (as opposed to "2008") form of ABS.fmt is an arithmetic
2851 ;; instruction that treats all NaN inputs as invalid; it does not clear
2852 ;; their sign bit. We therefore can't use that form if the signs of
2855 (define_insn "abs<mode>2"
2856 [(set (match_operand:ANYF 0 "register_operand" "=f")
2857 (abs:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2858 "mips_abs == MIPS_IEEE_754_2008 || !HONOR_NANS (<MODE>mode)"
2860 [(set_attr "type" "fabs")
2861 (set_attr "mode" "<UNITMODE>")])
2864 ;; ...................
2866 ;; Count leading zeroes.
2868 ;; ...................
2871 (define_insn "clz<mode>2"
2872 [(set (match_operand:GPR 0 "register_operand" "=d")
2873 (clz:GPR (match_operand:GPR 1 "register_operand" "d")))]
2876 [(set_attr "type" "clz")
2877 (set_attr "mode" "<MODE>")])
2880 ;; ...................
2882 ;; Count number of set bits.
2884 ;; ...................
2887 (define_insn "popcount<mode>2"
2888 [(set (match_operand:GPR 0 "register_operand" "=d")
2889 (popcount:GPR (match_operand:GPR 1 "register_operand" "d")))]
2892 [(set_attr "type" "pop")
2893 (set_attr "mode" "<MODE>")])
2895 ;; The POP instruction is special as it does not take into account the upper
2896 ;; 32bits and is documented that way.
2897 (define_insn "*popcountdi2_trunc"
2898 [(set (match_operand:SI 0 "register_operand" "=d")
2899 (popcount:SI (truncate:SI (match_operand:DI 1 "register_operand" "d"))))]
2900 "ISA_HAS_POP && TARGET_64BIT"
2902 [(set_attr "type" "pop")
2903 (set_attr "mode" "SI")])
2906 ;; ....................
2908 ;; NEGATION and ONE'S COMPLEMENT
2910 ;; ....................
2912 (define_insn "negsi2"
2913 [(set (match_operand:SI 0 "register_operand" "=d")
2914 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2918 return "neg\t%0,%1";
2920 return "subu\t%0,%.,%1";
2922 [(set_attr "alu_type" "sub")
2923 (set_attr "mode" "SI")])
2925 (define_insn "negdi2"
2926 [(set (match_operand:DI 0 "register_operand" "=d")
2927 (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2928 "TARGET_64BIT && !TARGET_MIPS16"
2930 [(set_attr "alu_type" "sub")
2931 (set_attr "mode" "DI")])
2933 ;; The "legacy" (as opposed to "2008") form of NEG.fmt is an arithmetic
2934 ;; instruction that treats all NaN inputs as invalid; it does not flip
2935 ;; their sign bit. We therefore can't use that form if the signs of
2938 (define_insn "neg<mode>2"
2939 [(set (match_operand:ANYF 0 "register_operand" "=f")
2940 (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2941 "mips_abs == MIPS_IEEE_754_2008 || !HONOR_NANS (<MODE>mode)"
2943 [(set_attr "type" "fneg")
2944 (set_attr "mode" "<UNITMODE>")])
2946 (define_insn "one_cmpl<mode>2"
2947 [(set (match_operand:GPR 0 "register_operand" "=!u,d")
2948 (not:GPR (match_operand:GPR 1 "register_operand" "!u,d")))]
2952 return "not\t%0,%1";
2954 return "nor\t%0,%.,%1";
2956 [(set_attr "alu_type" "not")
2957 (set_attr "compression" "micromips,*")
2958 (set_attr "mode" "<MODE>")])
2961 ;; ....................
2965 ;; ....................
2968 ;; Many of these instructions use trivial define_expands, because we
2969 ;; want to use a different set of constraints when TARGET_MIPS16.
2971 (define_expand "and<mode>3"
2972 [(set (match_operand:GPR 0 "register_operand")
2973 (and:GPR (match_operand:GPR 1 "register_operand")
2974 (match_operand:GPR 2 "and_reg_operand")))])
2976 ;; The middle-end is not allowed to convert ANDing with 0xffff_ffff into a
2977 ;; zero_extendsidi2 because of TRULY_NOOP_TRUNCATION, so handle these here.
2978 ;; Note that this variant does not trigger for SI mode because we require
2979 ;; a 64-bit HOST_WIDE_INT and 0xffff_ffff wouldn't be a canonical
2980 ;; sign-extended SImode value.
2982 ;; These are possible combinations for operand 1 and 2. The table
2983 ;; includes both MIPS and MIPS16 cases. (r=register, mem=memory,
2984 ;; 16=MIPS16, x=match, S=split):
2986 ;; \ op1 r/EXT r/!EXT mem r/16 mem/16
2992 ;; 0xffff_ffff x S x S x
2997 (define_insn "*and<mode>3"
2998 [(set (match_operand:GPR 0 "register_operand" "=d,d,d,!u,d,d,d,!u,d")
2999 (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "o,o,W,!u,d,d,d,0,d")
3000 (match_operand:GPR 2 "and_operand" "Yb,Yh,Yw,Uean,K,Yx,Yw,!u,d")))]
3001 "!TARGET_MIPS16 && and_operands_ok (<MODE>mode, operands[1], operands[2])"
3005 switch (which_alternative)
3008 operands[1] = gen_lowpart (QImode, operands[1]);
3009 return "lbu\t%0,%1";
3011 operands[1] = gen_lowpart (HImode, operands[1]);
3012 return "lhu\t%0,%1";
3014 operands[1] = gen_lowpart (SImode, operands[1]);
3015 return "lwu\t%0,%1";
3018 return "andi\t%0,%1,%x2";
3020 len = low_bitmask_len (<MODE>mode, INTVAL (operands[2]));
3021 operands[2] = GEN_INT (len);
3022 return "<d>ext\t%0,%1,0,%2";
3027 return "and\t%0,%1,%2";
3032 [(set_attr "move_type" "load,load,load,andi,andi,ext_ins,shift_shift,logical,logical")
3033 (set_attr "compression" "*,*,*,micromips,*,*,*,micromips,*")
3034 (set_attr "mode" "<MODE>")])
3036 (define_insn "*and<mode>3_mips16"
3037 [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d")
3038 (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "%W,W,W,d,0")
3039 (match_operand:GPR 2 "and_operand" "Yb,Yh,Yw,Yw,d")))]
3040 "TARGET_MIPS16 && and_operands_ok (<MODE>mode, operands[1], operands[2])"
3042 switch (which_alternative)
3045 operands[1] = gen_lowpart (QImode, operands[1]);
3046 return "lbu\t%0,%1";
3048 operands[1] = gen_lowpart (HImode, operands[1]);
3049 return "lhu\t%0,%1";
3051 operands[1] = gen_lowpart (SImode, operands[1]);
3052 return "lwu\t%0,%1";
3056 return "and\t%0,%2";
3061 [(set_attr "move_type" "load,load,load,shift_shift,logical")
3062 (set_attr "mode" "<MODE>")])
3064 (define_expand "ior<mode>3"
3065 [(set (match_operand:GPR 0 "register_operand")
3066 (ior:GPR (match_operand:GPR 1 "register_operand")
3067 (match_operand:GPR 2 "uns_arith_operand")))]
3071 operands[2] = force_reg (<MODE>mode, operands[2]);
3074 (define_insn "*ior<mode>3"
3075 [(set (match_operand:GPR 0 "register_operand" "=!u,d,d")
3076 (ior:GPR (match_operand:GPR 1 "register_operand" "%0,d,d")
3077 (match_operand:GPR 2 "uns_arith_operand" "!u,d,K")))]
3083 [(set_attr "alu_type" "or")
3084 (set_attr "compression" "micromips,*,*")
3085 (set_attr "mode" "<MODE>")])
3087 (define_insn "*ior<mode>3_mips16"
3088 [(set (match_operand:GPR 0 "register_operand" "=d")
3089 (ior:GPR (match_operand:GPR 1 "register_operand" "%0")
3090 (match_operand:GPR 2 "register_operand" "d")))]
3093 [(set_attr "alu_type" "or")
3094 (set_attr "mode" "<MODE>")])
3096 (define_expand "xor<mode>3"
3097 [(set (match_operand:GPR 0 "register_operand")
3098 (xor:GPR (match_operand:GPR 1 "register_operand")
3099 (match_operand:GPR 2 "uns_arith_operand")))]
3103 (define_insn "*xor<mode>3"
3104 [(set (match_operand:GPR 0 "register_operand" "=!u,d,d")
3105 (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d")
3106 (match_operand:GPR 2 "uns_arith_operand" "!u,d,K")))]
3112 [(set_attr "alu_type" "xor")
3113 (set_attr "compression" "micromips,*,*")
3114 (set_attr "mode" "<MODE>")])
3116 (define_insn "*xor<mode>3_mips16"
3117 [(set (match_operand:GPR 0 "register_operand" "=d,t,t,t")
3118 (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d,d")
3119 (match_operand:GPR 2 "uns_arith_operand" "d,Uub8,K,d")))]
3126 [(set_attr "alu_type" "xor")
3127 (set_attr "mode" "<MODE>")
3128 (set_attr "extended_mips16" "no,no,yes,no")])
3130 (define_insn "*nor<mode>3"
3131 [(set (match_operand:GPR 0 "register_operand" "=d")
3132 (and:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
3133 (not:GPR (match_operand:GPR 2 "register_operand" "d"))))]
3136 [(set_attr "alu_type" "nor")
3137 (set_attr "mode" "<MODE>")])
3140 ;; ....................
3144 ;; ....................
3148 (define_insn "truncdfsf2"
3149 [(set (match_operand:SF 0 "register_operand" "=f")
3150 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3151 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3153 [(set_attr "type" "fcvt")
3154 (set_attr "cnv_mode" "D2S")
3155 (set_attr "mode" "SF")])
3157 ;; Integer truncation patterns. Truncating SImode values to smaller
3158 ;; modes is a no-op, as it is for most other GCC ports. Truncating
3159 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
3160 ;; need to make sure that the lower 32 bits are properly sign-extended
3161 ;; (see TRULY_NOOP_TRUNCATION). Truncating DImode values into modes
3162 ;; smaller than SImode is equivalent to two separate truncations:
3165 ;; DI ---> HI == DI ---> SI ---> HI
3166 ;; DI ---> QI == DI ---> SI ---> QI
3168 ;; Step A needs a real instruction but step B does not.
3170 (define_insn "truncdi<mode>2"
3171 [(set (match_operand:SUBDI 0 "nonimmediate_operand" "=d,m")
3172 (truncate:SUBDI (match_operand:DI 1 "register_operand" "d,d")))]
3177 [(set_attr "move_type" "sll0,store")
3178 (set_attr "mode" "SI")])
3180 ;; Combiner patterns to optimize shift/truncate combinations.
3182 (define_insn "*ashr_trunc<mode>"
3183 [(set (match_operand:SUBDI 0 "register_operand" "=d")
3185 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
3186 (match_operand:DI 2 "const_arith_operand" ""))))]
3187 "TARGET_64BIT && !TARGET_MIPS16 && IN_RANGE (INTVAL (operands[2]), 32, 63)"
3189 [(set_attr "type" "shift")
3190 (set_attr "mode" "<MODE>")])
3192 (define_insn "*lshr32_trunc<mode>"
3193 [(set (match_operand:SUBDI 0 "register_operand" "=d")
3195 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
3197 "TARGET_64BIT && !TARGET_MIPS16"
3199 [(set_attr "type" "shift")
3200 (set_attr "mode" "<MODE>")])
3202 ;; Logical shift by more than 32 results in proper SI values so truncation is
3203 ;; removed by the middle end. Note that a logical shift by 32 is handled by
3204 ;; the previous pattern.
3205 (define_insn "*<optab>_trunc<mode>_exts"
3206 [(set (match_operand:SUBDI 0 "register_operand" "=d")
3208 (any_shiftrt:DI (match_operand:DI 1 "register_operand" "d")
3209 (match_operand:DI 2 "const_arith_operand" ""))))]
3210 "ISA_HAS_EXTS && TARGET_64BIT && UINTVAL (operands[2]) < 32"
3212 [(set_attr "type" "arith")
3213 (set_attr "mode" "<MODE>")])
3216 ;; ....................
3220 ;; ....................
3224 (define_expand "zero_extendsidi2"
3225 [(set (match_operand:DI 0 "register_operand")
3226 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3229 (define_insn_and_split "*zero_extendsidi2"
3230 [(set (match_operand:DI 0 "register_operand" "=d,d")
3231 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,W")))]
3232 "TARGET_64BIT && !ISA_HAS_EXT_INS"
3236 "&& reload_completed && REG_P (operands[1])"
3238 (ashift:DI (match_dup 1) (const_int 32)))
3240 (lshiftrt:DI (match_dup 0) (const_int 32)))]
3241 { operands[1] = gen_lowpart (DImode, operands[1]); }
3242 [(set_attr "move_type" "shift_shift,load")
3243 (set_attr "mode" "DI")])
3245 (define_insn "*zero_extendsidi2_dext"
3246 [(set (match_operand:DI 0 "register_operand" "=d,d")
3247 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,W")))]
3248 "TARGET_64BIT && ISA_HAS_EXT_INS"
3252 [(set_attr "move_type" "arith,load")
3253 (set_attr "mode" "DI")])
3255 ;; See the comment before the *and<mode>3 pattern why this is generated by
3259 [(set (match_operand:DI 0 "register_operand")
3260 (and:DI (match_operand:DI 1 "register_operand")
3261 (const_int 4294967295)))]
3262 "TARGET_64BIT && !ISA_HAS_EXT_INS && reload_completed"
3264 (ashift:DI (match_dup 1) (const_int 32)))
3266 (lshiftrt:DI (match_dup 0) (const_int 32)))])
3268 (define_expand "zero_extend<SHORT:mode><GPR:mode>2"
3269 [(set (match_operand:GPR 0 "register_operand")
3270 (zero_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
3273 if (TARGET_MIPS16 && !GENERATE_MIPS16E
3274 && !memory_operand (operands[1], <SHORT:MODE>mode))
3276 emit_insn (gen_and<GPR:mode>3 (operands[0],
3277 gen_lowpart (<GPR:MODE>mode, operands[1]),
3278 force_reg (<GPR:MODE>mode,
3279 GEN_INT (<SHORT:mask>))));
3284 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2"
3285 [(set (match_operand:GPR 0 "register_operand" "=!u,d,d")
3287 (match_operand:SHORT 1 "nonimmediate_operand" "!u,d,m")))]
3290 andi\t%0,%1,<SHORT:mask>
3291 andi\t%0,%1,<SHORT:mask>
3292 l<SHORT:size>u\t%0,%1"
3293 [(set_attr "move_type" "andi,andi,load")
3294 (set_attr "compression" "micromips,*,*")
3295 (set_attr "mode" "<GPR:MODE>")])
3297 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16e"
3298 [(set (match_operand:GPR 0 "register_operand" "=d")
3299 (zero_extend:GPR (match_operand:SHORT 1 "register_operand" "0")))]
3301 "ze<SHORT:size>\t%0"
3302 ;; This instruction is effectively a special encoding of ANDI.
3303 [(set_attr "move_type" "andi")
3304 (set_attr "mode" "<GPR:MODE>")])
3306 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16"
3307 [(set (match_operand:GPR 0 "register_operand" "=d")
3308 (zero_extend:GPR (match_operand:SHORT 1 "memory_operand" "m")))]
3310 "l<SHORT:size>u\t%0,%1"
3311 [(set_attr "move_type" "load")
3312 (set_attr "mode" "<GPR:MODE>")])
3314 (define_expand "zero_extendqihi2"
3315 [(set (match_operand:HI 0 "register_operand")
3316 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3319 if (TARGET_MIPS16 && !memory_operand (operands[1], QImode))
3321 emit_insn (gen_zero_extendqisi2 (gen_lowpart (SImode, operands[0]),
3327 (define_insn "*zero_extendqihi2"
3328 [(set (match_operand:HI 0 "register_operand" "=d,d")
3329 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3334 [(set_attr "move_type" "andi,load")
3335 (set_attr "mode" "HI")])
3337 (define_insn "*zero_extendqihi2_mips16"
3338 [(set (match_operand:HI 0 "register_operand" "=d")
3339 (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3342 [(set_attr "move_type" "load")
3343 (set_attr "mode" "HI")])
3345 ;; Combiner patterns to optimize truncate/zero_extend combinations.
3347 (define_insn "*zero_extend<GPR:mode>_trunc<SHORT:mode>"
3348 [(set (match_operand:GPR 0 "register_operand" "=d")
3350 (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
3351 "TARGET_64BIT && !TARGET_MIPS16"
3353 operands[2] = GEN_INT (GET_MODE_MASK (<SHORT:MODE>mode));
3354 return "andi\t%0,%1,%x2";
3356 [(set_attr "alu_type" "and")
3357 (set_attr "mode" "<GPR:MODE>")])
3359 (define_insn "*zero_extendhi_truncqi"
3360 [(set (match_operand:HI 0 "register_operand" "=d")
3362 (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
3363 "TARGET_64BIT && !TARGET_MIPS16"
3365 [(set_attr "alu_type" "and")
3366 (set_attr "mode" "HI")])
3369 ;; ....................
3373 ;; ....................
3376 ;; Those for integer source operand are ordered widest source type first.
3378 ;; When TARGET_64BIT, all SImode integer and accumulator registers
3379 ;; should already be in sign-extended form (see TRULY_NOOP_TRUNCATION
3380 ;; and truncdisi2). We can therefore get rid of register->register
3381 ;; instructions if we constrain the source to be in the same register as
3384 ;; Only the pre-reload scheduler sees the type of the register alternatives;
3385 ;; we split them into nothing before the post-reload scheduler runs.
3386 ;; These alternatives therefore have type "move" in order to reflect
3387 ;; what happens if the two pre-reload operands cannot be tied, and are
3388 ;; instead allocated two separate GPRs. We don't distinguish between
3389 ;; the GPR and LO cases because we don't usually know during pre-reload
3390 ;; scheduling whether an operand will be LO or not.
3391 (define_insn_and_split "extendsidi2"
3392 [(set (match_operand:DI 0 "register_operand" "=d,l,d")
3393 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,0,m")))]
3399 "&& reload_completed && register_operand (operands[1], VOIDmode)"
3402 emit_note (NOTE_INSN_DELETED);
3405 [(set_attr "move_type" "move,move,load")
3406 (set_attr "mode" "DI")])
3408 (define_expand "extend<SHORT:mode><GPR:mode>2"
3409 [(set (match_operand:GPR 0 "register_operand")
3410 (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
3413 (define_insn "*extend<SHORT:mode><GPR:mode>2_mips16e"
3414 [(set (match_operand:GPR 0 "register_operand" "=d,d")
3415 (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand" "0,m")))]
3419 l<SHORT:size>\t%0,%1"
3420 [(set_attr "move_type" "signext,load")
3421 (set_attr "mode" "<GPR:MODE>")])
3423 (define_insn_and_split "*extend<SHORT:mode><GPR:mode>2"
3424 [(set (match_operand:GPR 0 "register_operand" "=d,d")
3426 (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
3427 "!ISA_HAS_SEB_SEH && !GENERATE_MIPS16E"
3430 l<SHORT:size>\t%0,%1"
3431 "&& reload_completed && REG_P (operands[1])"
3432 [(set (match_dup 0) (ashift:GPR (match_dup 1) (match_dup 2)))
3433 (set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))]
3435 operands[1] = gen_lowpart (<GPR:MODE>mode, operands[1]);
3436 operands[2] = GEN_INT (GET_MODE_BITSIZE (<GPR:MODE>mode)
3437 - GET_MODE_BITSIZE (<SHORT:MODE>mode));
3439 [(set_attr "move_type" "shift_shift,load")
3440 (set_attr "mode" "<GPR:MODE>")])
3442 (define_insn "*extend<SHORT:mode><GPR:mode>2_se<SHORT:size>"
3443 [(set (match_operand:GPR 0 "register_operand" "=d,d")
3445 (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
3448 se<SHORT:size>\t%0,%1
3449 l<SHORT:size>\t%0,%1"
3450 [(set_attr "move_type" "signext,load")
3451 (set_attr "mode" "<GPR:MODE>")])
3453 (define_expand "extendqihi2"
3454 [(set (match_operand:HI 0 "register_operand")
3455 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3458 (define_insn "*extendqihi2_mips16e"
3459 [(set (match_operand:HI 0 "register_operand" "=d,d")
3460 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,m")))]
3465 [(set_attr "move_type" "signext,load")
3466 (set_attr "mode" "SI")])
3468 (define_insn_and_split "*extendqihi2"
3469 [(set (match_operand:HI 0 "register_operand" "=d,d")
3471 (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3472 "!ISA_HAS_SEB_SEH && !GENERATE_MIPS16E"
3476 "&& reload_completed && REG_P (operands[1])"
3477 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
3478 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
3480 operands[0] = gen_lowpart (SImode, operands[0]);
3481 operands[1] = gen_lowpart (SImode, operands[1]);
3482 operands[2] = GEN_INT (GET_MODE_BITSIZE (SImode)
3483 - GET_MODE_BITSIZE (QImode));
3485 [(set_attr "move_type" "shift_shift,load")
3486 (set_attr "mode" "SI")])
3488 (define_insn "*extendqihi2_seb"
3489 [(set (match_operand:HI 0 "register_operand" "=d,d")
3491 (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3496 [(set_attr "move_type" "signext,load")
3497 (set_attr "mode" "SI")])
3499 ;; Combiner patterns for truncate/sign_extend combinations. The SI versions
3500 ;; use the shift/truncate patterns.
3502 (define_insn_and_split "*extenddi_truncate<mode>"
3503 [(set (match_operand:DI 0 "register_operand" "=d")
3505 (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
3506 "TARGET_64BIT && !TARGET_MIPS16 && !ISA_HAS_EXTS"
3508 "&& reload_completed"
3510 (ashift:DI (match_dup 1)
3513 (ashiftrt:DI (match_dup 2)
3516 operands[2] = gen_lowpart (DImode, operands[0]);
3517 operands[3] = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (<MODE>mode));
3519 [(set_attr "move_type" "shift_shift")
3520 (set_attr "mode" "DI")])
3522 (define_insn_and_split "*extendsi_truncate<mode>"
3523 [(set (match_operand:SI 0 "register_operand" "=d")
3525 (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
3526 "TARGET_64BIT && !TARGET_MIPS16 && !ISA_HAS_EXTS"
3528 "&& reload_completed"
3530 (ashift:DI (match_dup 1)
3533 (truncate:SI (ashiftrt:DI (match_dup 2)
3536 operands[2] = gen_lowpart (DImode, operands[0]);
3537 operands[3] = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (<MODE>mode));
3539 [(set_attr "move_type" "shift_shift")
3540 (set_attr "mode" "SI")])
3542 (define_insn_and_split "*extendhi_truncateqi"
3543 [(set (match_operand:HI 0 "register_operand" "=d")
3545 (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
3546 "TARGET_64BIT && !TARGET_MIPS16 && !ISA_HAS_EXTS"
3548 "&& reload_completed"
3550 (ashift:DI (match_dup 1)
3553 (truncate:HI (ashiftrt:DI (match_dup 2)
3556 operands[2] = gen_lowpart (DImode, operands[0]);
3558 [(set_attr "move_type" "shift_shift")
3559 (set_attr "mode" "SI")])
3561 (define_insn "*extend<GPR:mode>_truncate<SHORT:mode>_exts"
3562 [(set (match_operand:GPR 0 "register_operand" "=d")
3564 (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
3565 "TARGET_64BIT && !TARGET_MIPS16 && ISA_HAS_EXTS"
3567 operands[2] = GEN_INT (GET_MODE_BITSIZE (<SHORT:MODE>mode));
3568 return "exts\t%0,%1,0,%m2";
3570 [(set_attr "type" "arith")
3571 (set_attr "mode" "<GPR:MODE>")])
3573 (define_insn "*extendhi_truncateqi_exts"
3574 [(set (match_operand:HI 0 "register_operand" "=d")
3576 (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
3577 "TARGET_64BIT && !TARGET_MIPS16 && ISA_HAS_EXTS"
3579 [(set_attr "type" "arith")
3580 (set_attr "mode" "SI")])
3582 (define_insn "extendsfdf2"
3583 [(set (match_operand:DF 0 "register_operand" "=f")
3584 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
3585 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3587 [(set_attr "type" "fcvt")
3588 (set_attr "cnv_mode" "S2D")
3589 (set_attr "mode" "DF")])
3592 ;; ....................
3596 ;; ....................
3598 (define_expand "fix_truncdfsi2"
3599 [(set (match_operand:SI 0 "register_operand")
3600 (fix:SI (match_operand:DF 1 "register_operand")))]
3601 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3603 if (!ISA_HAS_TRUNC_W)
3605 emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
3610 (define_insn "fix_truncdfsi2_insn"
3611 [(set (match_operand:SI 0 "register_operand" "=f")
3612 (fix:SI (match_operand:DF 1 "register_operand" "f")))]
3613 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
3615 [(set_attr "type" "fcvt")
3616 (set_attr "mode" "DF")
3617 (set_attr "cnv_mode" "D2I")])
3619 (define_insn "fix_truncdfsi2_macro"
3620 [(set (match_operand:SI 0 "register_operand" "=f")
3621 (fix:SI (match_operand:DF 1 "register_operand" "f")))
3622 (clobber (match_scratch:DF 2 "=d"))]
3623 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
3625 if (mips_nomacro.nesting_level > 0)
3626 return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
3628 return "trunc.w.d %0,%1,%2";
3630 [(set_attr "type" "fcvt")
3631 (set_attr "mode" "DF")
3632 (set_attr "cnv_mode" "D2I")
3633 (set_attr "insn_count" "9")])
3635 (define_expand "fix_truncsfsi2"
3636 [(set (match_operand:SI 0 "register_operand")
3637 (fix:SI (match_operand:SF 1 "register_operand")))]
3640 if (!ISA_HAS_TRUNC_W)
3642 emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
3647 (define_insn "fix_truncsfsi2_insn"
3648 [(set (match_operand:SI 0 "register_operand" "=f")
3649 (fix:SI (match_operand:SF 1 "register_operand" "f")))]
3650 "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
3652 [(set_attr "type" "fcvt")
3653 (set_attr "mode" "SF")
3654 (set_attr "cnv_mode" "S2I")])
3656 (define_insn "fix_truncsfsi2_macro"
3657 [(set (match_operand:SI 0 "register_operand" "=f")
3658 (fix:SI (match_operand:SF 1 "register_operand" "f")))
3659 (clobber (match_scratch:SF 2 "=d"))]
3660 "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
3662 if (mips_nomacro.nesting_level > 0)
3663 return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
3665 return "trunc.w.s %0,%1,%2";
3667 [(set_attr "type" "fcvt")
3668 (set_attr "mode" "SF")
3669 (set_attr "cnv_mode" "S2I")
3670 (set_attr "insn_count" "9")])
3673 (define_insn "fix_truncdfdi2"
3674 [(set (match_operand:DI 0 "register_operand" "=f")
3675 (fix:DI (match_operand:DF 1 "register_operand" "f")))]
3676 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3678 [(set_attr "type" "fcvt")
3679 (set_attr "mode" "DF")
3680 (set_attr "cnv_mode" "D2I")])
3683 (define_insn "fix_truncsfdi2"
3684 [(set (match_operand:DI 0 "register_operand" "=f")
3685 (fix:DI (match_operand:SF 1 "register_operand" "f")))]
3686 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3688 [(set_attr "type" "fcvt")
3689 (set_attr "mode" "SF")
3690 (set_attr "cnv_mode" "S2I")])
3693 (define_insn "floatsidf2"
3694 [(set (match_operand:DF 0 "register_operand" "=f")
3695 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3696 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3698 [(set_attr "type" "fcvt")
3699 (set_attr "mode" "DF")
3700 (set_attr "cnv_mode" "I2D")])
3703 (define_insn "floatdidf2"
3704 [(set (match_operand:DF 0 "register_operand" "=f")
3705 (float:DF (match_operand:DI 1 "register_operand" "f")))]
3706 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3708 [(set_attr "type" "fcvt")
3709 (set_attr "mode" "DF")
3710 (set_attr "cnv_mode" "I2D")])
3713 (define_insn "floatsisf2"
3714 [(set (match_operand:SF 0 "register_operand" "=f")
3715 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3718 [(set_attr "type" "fcvt")
3719 (set_attr "mode" "SF")
3720 (set_attr "cnv_mode" "I2S")])
3723 (define_insn "floatdisf2"
3724 [(set (match_operand:SF 0 "register_operand" "=f")
3725 (float:SF (match_operand:DI 1 "register_operand" "f")))]
3726 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3728 [(set_attr "type" "fcvt")
3729 (set_attr "mode" "SF")
3730 (set_attr "cnv_mode" "I2S")])
3733 (define_expand "fixuns_truncdfsi2"
3734 [(set (match_operand:SI 0 "register_operand")
3735 (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
3736 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3738 rtx reg1 = gen_reg_rtx (DFmode);
3739 rtx reg2 = gen_reg_rtx (DFmode);
3740 rtx reg3 = gen_reg_rtx (SImode);
3741 rtx_code_label *label1 = gen_label_rtx ();
3742 rtx_code_label *label2 = gen_label_rtx ();
3744 REAL_VALUE_TYPE offset;
3746 real_2expN (&offset, 31, DFmode);
3748 if (reg1) /* Turn off complaints about unreached code. */
3750 mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3751 do_pending_stack_adjust ();
3753 test = gen_rtx_GE (VOIDmode, operands[1], reg1);
3754 emit_jump_insn (gen_cbranchdf4 (test, operands[1], reg1, label1));
3756 emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
3757 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3758 gen_rtx_LABEL_REF (VOIDmode, label2)));
3761 emit_label (label1);
3762 mips_emit_move (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3763 mips_emit_move (reg3, GEN_INT (trunc_int_for_mode
3764 (BITMASK_HIGH, SImode)));
3766 emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
3767 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3769 emit_label (label2);
3771 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3772 fields, and can't be used for REG_NOTES anyway). */
3773 emit_use (stack_pointer_rtx);
3779 (define_expand "fixuns_truncdfdi2"
3780 [(set (match_operand:DI 0 "register_operand")
3781 (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
3782 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3784 rtx reg1 = gen_reg_rtx (DFmode);
3785 rtx reg2 = gen_reg_rtx (DFmode);
3786 rtx reg3 = gen_reg_rtx (DImode);
3787 rtx_code_label *label1 = gen_label_rtx ();
3788 rtx_code_label *label2 = gen_label_rtx ();
3790 REAL_VALUE_TYPE offset;
3792 real_2expN (&offset, 63, DFmode);
3794 mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3795 do_pending_stack_adjust ();
3797 test = gen_rtx_GE (VOIDmode, operands[1], reg1);
3798 emit_jump_insn (gen_cbranchdf4 (test, operands[1], reg1, label1));
3800 emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
3801 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3802 gen_rtx_LABEL_REF (VOIDmode, label2)));
3805 emit_label (label1);
3806 mips_emit_move (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3807 mips_emit_move (reg3, GEN_INT (BITMASK_HIGH));
3808 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3810 emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
3811 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3813 emit_label (label2);
3815 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3816 fields, and can't be used for REG_NOTES anyway). */
3817 emit_use (stack_pointer_rtx);
3822 (define_expand "fixuns_truncsfsi2"
3823 [(set (match_operand:SI 0 "register_operand")
3824 (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
3827 rtx reg1 = gen_reg_rtx (SFmode);
3828 rtx reg2 = gen_reg_rtx (SFmode);
3829 rtx reg3 = gen_reg_rtx (SImode);
3830 rtx_code_label *label1 = gen_label_rtx ();
3831 rtx_code_label *label2 = gen_label_rtx ();
3833 REAL_VALUE_TYPE offset;
3835 real_2expN (&offset, 31, SFmode);
3837 mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3838 do_pending_stack_adjust ();
3840 test = gen_rtx_GE (VOIDmode, operands[1], reg1);
3841 emit_jump_insn (gen_cbranchsf4 (test, operands[1], reg1, label1));
3843 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
3844 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3845 gen_rtx_LABEL_REF (VOIDmode, label2)));
3848 emit_label (label1);
3849 mips_emit_move (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3850 mips_emit_move (reg3, GEN_INT (trunc_int_for_mode
3851 (BITMASK_HIGH, SImode)));
3853 emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
3854 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3856 emit_label (label2);
3858 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3859 fields, and can't be used for REG_NOTES anyway). */
3860 emit_use (stack_pointer_rtx);
3865 (define_expand "fixuns_truncsfdi2"
3866 [(set (match_operand:DI 0 "register_operand")
3867 (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
3868 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3870 rtx reg1 = gen_reg_rtx (SFmode);
3871 rtx reg2 = gen_reg_rtx (SFmode);
3872 rtx reg3 = gen_reg_rtx (DImode);
3873 rtx_code_label *label1 = gen_label_rtx ();
3874 rtx_code_label *label2 = gen_label_rtx ();
3876 REAL_VALUE_TYPE offset;
3878 real_2expN (&offset, 63, SFmode);
3880 mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3881 do_pending_stack_adjust ();
3883 test = gen_rtx_GE (VOIDmode, operands[1], reg1);
3884 emit_jump_insn (gen_cbranchsf4 (test, operands[1], reg1, label1));
3886 emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
3887 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3888 gen_rtx_LABEL_REF (VOIDmode, label2)));
3891 emit_label (label1);
3892 mips_emit_move (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3893 mips_emit_move (reg3, GEN_INT (BITMASK_HIGH));
3894 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3896 emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
3897 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3899 emit_label (label2);
3901 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3902 fields, and can't be used for REG_NOTES anyway). */
3903 emit_use (stack_pointer_rtx);
3908 ;; ....................
3912 ;; ....................
3914 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
3916 (define_expand "extvmisalign<mode>"
3917 [(set (match_operand:GPR 0 "register_operand")
3918 (sign_extract:GPR (match_operand:BLK 1 "memory_operand")
3919 (match_operand 2 "const_int_operand")
3920 (match_operand 3 "const_int_operand")))]
3923 if (mips_expand_ext_as_unaligned_load (operands[0], operands[1],
3924 INTVAL (operands[2]),
3925 INTVAL (operands[3]),
3926 /*unsigned=*/ false))
3932 (define_expand "extv<mode>"
3933 [(set (match_operand:GPR 0 "register_operand")
3934 (sign_extract:GPR (match_operand:GPR 1 "register_operand")
3935 (match_operand 2 "const_int_operand")
3936 (match_operand 3 "const_int_operand")))]
3939 if (UINTVAL (operands[2]) > 32)
3943 (define_insn "*extv<mode>"
3944 [(set (match_operand:GPR 0 "register_operand" "=d")
3945 (sign_extract:GPR (match_operand:GPR 1 "register_operand" "d")
3946 (match_operand 2 "const_int_operand" "")
3947 (match_operand 3 "const_int_operand" "")))]
3948 "ISA_HAS_EXTS && UINTVAL (operands[2]) <= 32"
3949 "exts\t%0,%1,%3,%m2"
3950 [(set_attr "type" "arith")
3951 (set_attr "mode" "<MODE>")])
3953 (define_expand "extzvmisalign<mode>"
3954 [(set (match_operand:GPR 0 "register_operand")
3955 (zero_extract:GPR (match_operand:BLK 1 "memory_operand")
3956 (match_operand 2 "const_int_operand")
3957 (match_operand 3 "const_int_operand")))]
3960 if (mips_expand_ext_as_unaligned_load (operands[0], operands[1],
3961 INTVAL (operands[2]),
3962 INTVAL (operands[3]),
3963 /*unsigned=*/ true))
3969 (define_expand "extzv<mode>"
3970 [(set (match_operand:GPR 0 "register_operand")
3971 (zero_extract:GPR (match_operand:GPR 1 "register_operand")
3972 (match_operand 2 "const_int_operand")
3973 (match_operand 3 "const_int_operand")))]
3976 if (!mips_use_ins_ext_p (operands[1], INTVAL (operands[2]),
3977 INTVAL (operands[3])))
3981 (define_insn "*extzv<mode>"
3982 [(set (match_operand:GPR 0 "register_operand" "=d")
3983 (zero_extract:GPR (match_operand:GPR 1 "register_operand" "d")
3984 (match_operand 2 "const_int_operand" "")
3985 (match_operand 3 "const_int_operand" "")))]
3986 "mips_use_ins_ext_p (operands[1], INTVAL (operands[2]),
3987 INTVAL (operands[3]))"
3988 "<d>ext\t%0,%1,%3,%2"
3989 [(set_attr "type" "arith")
3990 (set_attr "mode" "<MODE>")])
3992 (define_insn "*extzv_truncsi_exts"
3993 [(set (match_operand:SI 0 "register_operand" "=d")
3995 (zero_extract:DI (match_operand:DI 1 "register_operand" "d")
3996 (match_operand 2 "const_int_operand" "")
3997 (match_operand 3 "const_int_operand" ""))))]
3998 "ISA_HAS_EXTS && TARGET_64BIT && IN_RANGE (INTVAL (operands[2]), 32, 63)"
4000 [(set_attr "type" "arith")
4001 (set_attr "mode" "SI")])
4004 (define_expand "insvmisalign<mode>"
4005 [(set (zero_extract:GPR (match_operand:BLK 0 "memory_operand")
4006 (match_operand 1 "const_int_operand")
4007 (match_operand 2 "const_int_operand"))
4008 (match_operand:GPR 3 "reg_or_0_operand"))]
4011 if (mips_expand_ins_as_unaligned_store (operands[0], operands[3],
4012 INTVAL (operands[1]),
4013 INTVAL (operands[2])))
4019 (define_expand "insv<mode>"
4020 [(set (zero_extract:GPR (match_operand:GPR 0 "register_operand")
4021 (match_operand 1 "const_int_operand")
4022 (match_operand 2 "const_int_operand"))
4023 (match_operand:GPR 3 "reg_or_0_operand"))]
4026 if (!mips_use_ins_ext_p (operands[0], INTVAL (operands[1]),
4027 INTVAL (operands[2])))
4031 (define_insn "*insv<mode>"
4032 [(set (zero_extract:GPR (match_operand:GPR 0 "register_operand" "+d")
4033 (match_operand:SI 1 "const_int_operand" "")
4034 (match_operand:SI 2 "const_int_operand" ""))
4035 (match_operand:GPR 3 "reg_or_0_operand" "dJ"))]
4036 "mips_use_ins_ext_p (operands[0], INTVAL (operands[1]),
4037 INTVAL (operands[2]))"
4038 "<d>ins\t%0,%z3,%2,%1"
4039 [(set_attr "type" "arith")
4040 (set_attr "mode" "<MODE>")])
4042 ;; Combiner pattern for cins (clear and insert bit field). We can
4043 ;; implement mask-and-shift-left operation with this. Note that if
4044 ;; the upper bit of the mask is set in an SImode operation, the mask
4045 ;; itself will be sign-extended. mask_low_and_shift_len will
4046 ;; therefore be greater than our threshold of 32.
4048 (define_insn "*cins<mode>"
4049 [(set (match_operand:GPR 0 "register_operand" "=d")
4051 (ashift:GPR (match_operand:GPR 1 "register_operand" "d")
4052 (match_operand:GPR 2 "const_int_operand" ""))
4053 (match_operand:GPR 3 "const_int_operand" "")))]
4055 && mask_low_and_shift_p (<MODE>mode, operands[3], operands[2], 32)"
4058 GEN_INT (mask_low_and_shift_len (<MODE>mode, operands[3], operands[2]));
4059 return "cins\t%0,%1,%2,%m3";
4061 [(set_attr "type" "shift")
4062 (set_attr "mode" "<MODE>")])
4064 ;; Unaligned word moves generated by the bit field patterns.
4066 ;; As far as the rtl is concerned, both the left-part and right-part
4067 ;; instructions can access the whole field. However, the real operand
4068 ;; refers to just the first or the last byte (depending on endianness).
4069 ;; We therefore use two memory operands to each instruction, one to
4070 ;; describe the rtl effect and one to use in the assembly output.
4072 ;; Operands 0 and 1 are the rtl-level target and source respectively.
4073 ;; This allows us to use the standard length calculations for the "load"
4074 ;; and "store" type attributes.
4076 (define_insn "mov_<load>l"
4077 [(set (match_operand:GPR 0 "register_operand" "=d")
4078 (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
4079 (match_operand:QI 2 "memory_operand" "ZC")]
4081 "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
4083 [(set_attr "move_type" "load")
4084 (set_attr "mode" "<MODE>")])
4086 (define_insn "mov_<load>r"
4087 [(set (match_operand:GPR 0 "register_operand" "=d")
4088 (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
4089 (match_operand:QI 2 "memory_operand" "ZC")
4090 (match_operand:GPR 3 "register_operand" "0")]
4091 UNSPEC_LOAD_RIGHT))]
4092 "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
4094 [(set_attr "move_type" "load")
4095 (set_attr "mode" "<MODE>")])
4097 (define_insn "mov_<store>l"
4098 [(set (match_operand:BLK 0 "memory_operand" "=m")
4099 (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
4100 (match_operand:QI 2 "memory_operand" "ZC")]
4101 UNSPEC_STORE_LEFT))]
4102 "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
4104 [(set_attr "move_type" "store")
4105 (set_attr "mode" "<MODE>")])
4107 (define_insn "mov_<store>r"
4108 [(set (match_operand:BLK 0 "memory_operand" "+m")
4109 (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
4110 (match_operand:QI 2 "memory_operand" "ZC")
4112 UNSPEC_STORE_RIGHT))]
4113 "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
4115 [(set_attr "move_type" "store")
4116 (set_attr "mode" "<MODE>")])
4118 ;; An instruction to calculate the high part of a 64-bit SYMBOL_ABSOLUTE.
4119 ;; The required value is:
4121 ;; (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
4123 ;; which translates to:
4125 ;; lui op0,%highest(op1)
4126 ;; daddiu op0,op0,%higher(op1)
4128 ;; daddiu op0,op0,%hi(op1)
4131 ;; The split is deferred until after flow2 to allow the peephole2 below
4133 (define_insn_and_split "*lea_high64"
4134 [(set (match_operand:DI 0 "register_operand" "=d")
4135 (high:DI (match_operand:DI 1 "absolute_symbolic_operand" "")))]
4136 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
4138 "&& epilogue_completed"
4139 [(set (match_dup 0) (high:DI (match_dup 2)))
4140 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
4141 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
4142 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
4143 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
4145 operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
4146 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
4148 [(set_attr "insn_count" "5")])
4150 ;; Use a scratch register to reduce the latency of the above pattern
4151 ;; on superscalar machines. The optimized sequence is:
4153 ;; lui op1,%highest(op2)
4155 ;; daddiu op1,op1,%higher(op2)
4157 ;; daddu op1,op1,op0
4159 [(set (match_operand:DI 1 "d_operand")
4160 (high:DI (match_operand:DI 2 "absolute_symbolic_operand")))
4161 (match_scratch:DI 0 "d")]
4162 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
4163 [(set (match_dup 1) (high:DI (match_dup 3)))
4164 (set (match_dup 0) (high:DI (match_dup 4)))
4165 (set (match_dup 1) (lo_sum:DI (match_dup 1) (match_dup 3)))
4166 (set (match_dup 1) (ashift:DI (match_dup 1) (const_int 32)))
4167 (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 0)))]
4169 operands[3] = mips_unspec_address (operands[2], SYMBOL_64_HIGH);
4170 operands[4] = mips_unspec_address (operands[2], SYMBOL_64_LOW);
4173 ;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
4174 ;; SYMBOL_ABSOLUTE X will take 6 cycles. This next pattern allows combine
4175 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
4176 ;; used once. We can then use the sequence:
4178 ;; lui op0,%highest(op1)
4180 ;; daddiu op0,op0,%higher(op1)
4181 ;; daddiu op2,op2,%lo(op1)
4183 ;; daddu op0,op0,op2
4185 ;; which takes 4 cycles on most superscalar targets.
4186 (define_insn_and_split "*lea64"
4187 [(set (match_operand:DI 0 "register_operand" "=d")
4188 (match_operand:DI 1 "absolute_symbolic_operand" ""))
4189 (clobber (match_scratch:DI 2 "=&d"))]
4191 && TARGET_EXPLICIT_RELOCS
4192 && ABI_HAS_64BIT_SYMBOLS
4193 && cse_not_expected"
4195 "&& reload_completed"
4196 [(set (match_dup 0) (high:DI (match_dup 3)))
4197 (set (match_dup 2) (high:DI (match_dup 4)))
4198 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
4199 (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
4200 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
4201 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
4203 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
4204 operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
4206 [(set_attr "insn_count" "6")])
4208 ;; Split HIGHs into:
4213 ;; on MIPS16 targets.
4215 [(set (match_operand:P 0 "d_operand")
4216 (high:P (match_operand:P 1 "symbolic_operand_with_high")))]
4217 "TARGET_MIPS16 && reload_completed"
4218 [(set (match_dup 0) (unspec:P [(match_dup 1)] UNSPEC_UNSHIFTED_HIGH))
4219 (set (match_dup 0) (ashift:P (match_dup 0) (const_int 16)))])
4221 (define_insn "*unshifted_high"
4222 [(set (match_operand:P 0 "d_operand" "=d")
4223 (unspec:P [(match_operand:P 1 "symbolic_operand_with_high")]
4224 UNSPEC_UNSHIFTED_HIGH))]
4227 [(set_attr "extended_mips16" "yes")])
4229 ;; Insns to fetch a symbol from a big GOT.
4231 (define_insn_and_split "*xgot_hi<mode>"
4232 [(set (match_operand:P 0 "register_operand" "=d")
4233 (high:P (match_operand:P 1 "got_disp_operand" "")))]
4234 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
4236 "&& reload_completed"
4237 [(set (match_dup 0) (high:P (match_dup 2)))
4238 (set (match_dup 0) (plus:P (match_dup 0) (match_dup 3)))]
4240 operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_DISP);
4241 operands[3] = pic_offset_table_rtx;
4243 [(set_attr "got" "xgot_high")
4244 (set_attr "mode" "<MODE>")])
4246 (define_insn_and_split "*xgot_lo<mode>"
4247 [(set (match_operand:P 0 "register_operand" "=d")
4248 (lo_sum:P (match_operand:P 1 "register_operand" "d")
4249 (match_operand:P 2 "got_disp_operand" "")))]
4250 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
4252 "&& reload_completed"
4254 (unspec:P [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
4255 { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_DISP); }
4256 [(set_attr "got" "load")
4257 (set_attr "mode" "<MODE>")])
4259 ;; Insns to fetch a symbol from a normal GOT.
4261 (define_insn_and_split "*got_disp<mode>"
4262 [(set (match_operand:P 0 "register_operand" "=d")
4263 (match_operand:P 1 "got_disp_operand" ""))]
4264 "TARGET_EXPLICIT_RELOCS && !mips_split_p[SYMBOL_GOT_DISP]"
4266 "&& reload_completed"
4267 [(set (match_dup 0) (match_dup 2))]
4268 { operands[2] = mips_got_load (NULL, operands[1], SYMBOL_GOTOFF_DISP); }
4269 [(set_attr "got" "load")
4270 (set_attr "mode" "<MODE>")])
4272 ;; Insns for loading the "page" part of a page/ofst address from the GOT.
4274 (define_insn_and_split "*got_page<mode>"
4275 [(set (match_operand:P 0 "register_operand" "=d")
4276 (high:P (match_operand:P 1 "got_page_ofst_operand" "")))]
4277 "TARGET_EXPLICIT_RELOCS && !mips_split_hi_p[SYMBOL_GOT_PAGE_OFST]"
4279 "&& reload_completed"
4280 [(set (match_dup 0) (match_dup 2))]
4281 { operands[2] = mips_got_load (NULL, operands[1], SYMBOL_GOTOFF_PAGE); }
4282 [(set_attr "got" "load")
4283 (set_attr "mode" "<MODE>")])
4285 ;; Convenience expander that generates the rhs of a load_got<mode> insn.
4286 (define_expand "unspec_got_<mode>"
4287 [(unspec:P [(match_operand:P 0)
4288 (match_operand:P 1)] UNSPEC_LOAD_GOT)])
4290 ;; Lower-level instructions for loading an address from the GOT.
4291 ;; We could use MEMs, but an unspec gives more optimization
4294 (define_insn "load_got<mode>"
4295 [(set (match_operand:P 0 "register_operand" "=d")
4296 (unspec:P [(match_operand:P 1 "register_operand" "d")
4297 (match_operand:P 2 "immediate_operand" "")]
4300 "<load>\t%0,%R2(%1)"
4301 [(set_attr "got" "load")
4302 (set_attr "mode" "<MODE>")])
4304 ;; Instructions for adding the low 16 bits of an address to a register.
4305 ;; Operand 2 is the address: mips_print_operand works out which relocation
4306 ;; should be applied.
4308 (define_insn "*low<mode>"
4309 [(set (match_operand:P 0 "register_operand" "=d")
4310 (lo_sum:P (match_operand:P 1 "register_operand" "d")
4311 (match_operand:P 2 "immediate_operand" "")))]
4313 "<d>addiu\t%0,%1,%R2"
4314 [(set_attr "alu_type" "add")
4315 (set_attr "mode" "<MODE>")])
4317 (define_insn "*low<mode>_mips16"
4318 [(set (match_operand:P 0 "register_operand" "=d")
4319 (lo_sum:P (match_operand:P 1 "register_operand" "0")
4320 (match_operand:P 2 "immediate_operand" "")))]
4323 [(set_attr "alu_type" "add")
4324 (set_attr "mode" "<MODE>")
4325 (set_attr "extended_mips16" "yes")])
4327 ;; Expose MIPS16 uses of the global pointer after reload if the function
4328 ;; is responsible for setting up the register itself.
4330 [(set (match_operand:GPR 0 "d_operand")
4331 (const:GPR (unspec:GPR [(const_int 0)] UNSPEC_GP)))]
4332 "TARGET_MIPS16 && TARGET_USE_GOT && reload_completed"
4333 [(set (match_dup 0) (match_dup 1))]
4334 { operands[1] = pic_offset_table_rtx; })
4336 ;; Allow combine to split complex const_int load sequences, using operand 2
4337 ;; to store the intermediate results. See move_operand for details.
4339 [(set (match_operand:GPR 0 "register_operand")
4340 (match_operand:GPR 1 "splittable_const_int_operand"))
4341 (clobber (match_operand:GPR 2 "register_operand"))]
4345 mips_move_integer (operands[2], operands[0], INTVAL (operands[1]));
4349 ;; Likewise, for symbolic operands.
4351 [(set (match_operand:P 0 "register_operand")
4352 (match_operand:P 1))
4353 (clobber (match_operand:P 2 "register_operand"))]
4354 "mips_split_symbol (operands[2], operands[1], MAX_MACHINE_MODE, NULL)"
4355 [(set (match_dup 0) (match_dup 3))]
4357 mips_split_symbol (operands[2], operands[1],
4358 MAX_MACHINE_MODE, &operands[3]);
4361 ;; 64-bit integer moves
4363 ;; Unlike most other insns, the move insns can't be split with
4364 ;; different predicates, because register spilling and other parts of
4365 ;; the compiler, have memoized the insn number already.
4367 (define_expand "movdi"
4368 [(set (match_operand:DI 0 "")
4369 (match_operand:DI 1 ""))]
4372 if (mips_legitimize_move (DImode, operands[0], operands[1]))
4376 ;; For mips16, we need a special case to handle storing $31 into
4377 ;; memory, since we don't have a constraint to match $31. This
4378 ;; instruction can be generated by save_restore_insns.
4380 (define_insn "*mov<mode>_ra"
4381 [(set (match_operand:GPR 0 "stack_operand" "=m")
4382 (reg:GPR RETURN_ADDR_REGNUM))]
4385 [(set_attr "move_type" "store")
4386 (set_attr "mode" "<MODE>")])
4388 (define_insn "*movdi_32bit"
4389 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*a,*a,*d,*f,*f,*d,*m,*B*C*D,*B*C*D,*d,*m")
4390 (match_operand:DI 1 "move_operand" "d,i,m,d,*J,*d,*a,*J*d,*m,*f,*f,*d,*m,*B*C*D,*B*C*D"))]
4391 "!TARGET_64BIT && !TARGET_MIPS16
4392 && (register_operand (operands[0], DImode)
4393 || reg_or_0_operand (operands[1], DImode))"
4394 { return mips_output_move (operands[0], operands[1]); }
4395 [(set_attr "move_type" "move,const,load,store,imul,mtlo,mflo,mtc,fpload,mfc,fpstore,mtc,fpload,mfc,fpstore")
4397 (if_then_else (eq_attr "move_type" "imul")
4399 (const_string "DI")))])
4401 (define_insn "*movdi_32bit_mips16"
4402 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4403 (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
4404 "!TARGET_64BIT && TARGET_MIPS16
4405 && (register_operand (operands[0], DImode)
4406 || register_operand (operands[1], DImode))"
4407 { return mips_output_move (operands[0], operands[1]); }
4408 [(set_attr "move_type" "move,move,move,const,constN,load,store,mflo")
4409 (set_attr "mode" "DI")])
4411 (define_insn "*movdi_64bit"
4412 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*d,*m,*a,*d,*B*C*D,*B*C*D,*d,*m")
4413 (match_operand:DI 1 "move_operand" "d,Yd,Yf,m,dJ,*d*J,*m,*f,*f,*J*d,*a,*d,*m,*B*C*D,*B*C*D"))]
4414 "TARGET_64BIT && !TARGET_MIPS16
4415 && (register_operand (operands[0], DImode)
4416 || reg_or_0_operand (operands[1], DImode))"
4417 { return mips_output_move (operands[0], operands[1]); }
4418 [(set_attr "move_type" "move,const,const,load,store,mtc,fpload,mfc,fpstore,mtlo,mflo,mtc,fpload,mfc,fpstore")
4419 (set_attr "mode" "DI")])
4421 (define_insn "*movdi_64bit_mips16"
4422 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,m,*d")
4423 (match_operand:DI 1 "move_operand" "d,d,y,K,N,Yd,kf,m,d,*a"))]
4424 "TARGET_64BIT && TARGET_MIPS16
4425 && (register_operand (operands[0], DImode)
4426 || register_operand (operands[1], DImode))"
4427 { return mips_output_move (operands[0], operands[1]); }
4428 [(set_attr "move_type" "move,move,move,const,constN,const,loadpool,load,store,mflo")
4429 (set_attr "mode" "DI")])
4431 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
4432 ;; when the original load is a 4 byte instruction but the add and the
4433 ;; load are 2 2 byte instructions.
4436 [(set (match_operand:DI 0 "d_operand")
4437 (mem:DI (plus:DI (match_dup 0)
4438 (match_operand:DI 1 "const_int_operand"))))]
4439 "TARGET_64BIT && TARGET_MIPS16 && reload_completed
4440 && !TARGET_DEBUG_D_MODE
4441 && ((INTVAL (operands[1]) < 0
4442 && INTVAL (operands[1]) >= -0x10)
4443 || (INTVAL (operands[1]) >= 32 * 8
4444 && INTVAL (operands[1]) <= 31 * 8 + 0x8)
4445 || (INTVAL (operands[1]) >= 0
4446 && INTVAL (operands[1]) < 32 * 8
4447 && (INTVAL (operands[1]) & 7) != 0))"
4448 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
4449 (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
4451 HOST_WIDE_INT val = INTVAL (operands[1]);
4454 operands[2] = const0_rtx;
4455 else if (val >= 32 * 8)
4459 operands[1] = GEN_INT (0x8 + off);
4460 operands[2] = GEN_INT (val - off - 0x8);
4466 operands[1] = GEN_INT (off);
4467 operands[2] = GEN_INT (val - off);
4471 ;; 32-bit Integer moves
4473 ;; Unlike most other insns, the move insns can't be split with
4474 ;; different predicates, because register spilling and other parts of
4475 ;; the compiler, have memoized the insn number already.
4477 (define_expand "mov<mode>"
4478 [(set (match_operand:IMOVE32 0 "")
4479 (match_operand:IMOVE32 1 ""))]
4482 if (mips_legitimize_move (<MODE>mode, operands[0], operands[1]))
4486 ;; The difference between these two is whether or not ints are allowed
4487 ;; in FP registers (off by default, use -mdebugh to enable).
4489 (define_insn "*mov<mode>_internal"
4490 [(set (match_operand:IMOVE32 0 "nonimmediate_operand" "=d,!u,!u,d,e,!u,!ks,d,ZS,ZT,m,*f,*f,*d,*m,*d,*z,*a,*d,*B*C*D,*B*C*D,*d,*m")
4491 (match_operand:IMOVE32 1 "move_operand" "d,J,Udb7,Yd,Yf,ZT,ZS,m,!ks,!kbJ,dJ,*d*J,*m,*f,*f,*z,*d,*J*d,*a,*d,*m,*B*C*D,*B*C*D"))]
4493 && (register_operand (operands[0], <MODE>mode)
4494 || reg_or_0_operand (operands[1], <MODE>mode))"
4495 { return mips_output_move (operands[0], operands[1]); }
4496 [(set_attr "move_type" "move,move,const,const,const,load,load,load,store,store,store,mtc,fpload,mfc,fpstore,mfc,mtc,mtlo,mflo,mtc,fpload,mfc,fpstore")
4497 (set_attr "compression" "all,micromips,micromips,*,*,micromips,micromips,*,micromips,micromips,*,*,*,*,*,*,*,*,*,*,*,*,*")
4498 (set_attr "mode" "SI")])
4500 (define_insn "*mov<mode>_mips16"
4501 [(set (match_operand:IMOVE32 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,m,*d")
4502 (match_operand:IMOVE32 1 "move_operand" "d,d,y,K,N,Yd,kf,m,d,*a"))]
4504 && (register_operand (operands[0], <MODE>mode)
4505 || register_operand (operands[1], <MODE>mode))"
4506 { return mips_output_move (operands[0], operands[1]); }
4507 [(set_attr "move_type" "move,move,move,const,constN,const,loadpool,load,store,mflo")
4508 (set_attr "mode" "SI")])
4510 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
4511 ;; when the original load is a 4 byte instruction but the add and the
4512 ;; load are 2 2 byte instructions.
4515 [(set (match_operand:SI 0 "d_operand")
4516 (mem:SI (plus:SI (match_dup 0)
4517 (match_operand:SI 1 "const_int_operand"))))]
4518 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4519 && ((INTVAL (operands[1]) < 0
4520 && INTVAL (operands[1]) >= -0x80)
4521 || (INTVAL (operands[1]) >= 32 * 4
4522 && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
4523 || (INTVAL (operands[1]) >= 0
4524 && INTVAL (operands[1]) < 32 * 4
4525 && (INTVAL (operands[1]) & 3) != 0))"
4526 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4527 (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
4529 HOST_WIDE_INT val = INTVAL (operands[1]);
4532 operands[2] = const0_rtx;
4533 else if (val >= 32 * 4)
4537 operands[1] = GEN_INT (0x7c + off);
4538 operands[2] = GEN_INT (val - off - 0x7c);
4544 operands[1] = GEN_INT (off);
4545 operands[2] = GEN_INT (val - off);
4549 ;; On the mips16, we can split a load of certain constants into a load
4550 ;; and an add. This turns a 4 byte instruction into 2 2 byte
4554 [(set (match_operand:SI 0 "d_operand")
4555 (match_operand:SI 1 "const_int_operand"))]
4556 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4557 && INTVAL (operands[1]) >= 0x100
4558 && INTVAL (operands[1]) <= 0xff + 0x7f"
4559 [(set (match_dup 0) (match_dup 1))
4560 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
4562 int val = INTVAL (operands[1]);
4564 operands[1] = GEN_INT (0xff);
4565 operands[2] = GEN_INT (val - 0xff);
4568 ;; MIPS4 supports loading and storing a floating point register from
4569 ;; the sum of two general registers. We use two versions for each of
4570 ;; these four instructions: one where the two general registers are
4571 ;; SImode, and one where they are DImode. This is because general
4572 ;; registers will be in SImode when they hold 32-bit values, but,
4573 ;; since the 32-bit values are always sign extended, the [ls][wd]xc1
4574 ;; instructions will still work correctly.
4576 ;; ??? Perhaps it would be better to support these instructions by
4577 ;; modifying TARGET_LEGITIMATE_ADDRESS_P and friends. However, since
4578 ;; these instructions can only be used to load and store floating
4579 ;; point registers, that would probably cause trouble in reload.
4581 (define_insn "*<ANYF:loadx>_<P:mode>"
4582 [(set (match_operand:ANYF 0 "register_operand" "=f")
4583 (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d")
4584 (match_operand:P 2 "register_operand" "d"))))]
4586 "<ANYF:loadx>\t%0,%1(%2)"
4587 [(set_attr "type" "fpidxload")
4588 (set_attr "mode" "<ANYF:UNITMODE>")])
4590 (define_insn "*<ANYF:storex>_<P:mode>"
4591 [(set (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d")
4592 (match_operand:P 2 "register_operand" "d")))
4593 (match_operand:ANYF 0 "register_operand" "f"))]
4595 "<ANYF:storex>\t%0,%1(%2)"
4596 [(set_attr "type" "fpidxstore")
4597 (set_attr "mode" "<ANYF:UNITMODE>")])
4599 ;; Scaled indexed address load.
4600 ;; Per md.texi, we only need to look for a pattern with multiply in the
4601 ;; address expression, not shift.
4603 (define_insn "*lwxs"
4604 [(set (match_operand:IMOVE32 0 "register_operand" "=d")
4606 (plus:P (mult:P (match_operand:P 1 "register_operand" "d")
4608 (match_operand:P 2 "register_operand" "d"))))]
4611 [(set_attr "type" "load")
4612 (set_attr "mode" "SI")])
4614 ;; 16-bit Integer moves
4616 ;; Unlike most other insns, the move insns can't be split with
4617 ;; different predicates, because register spilling and other parts of
4618 ;; the compiler, have memoized the insn number already.
4619 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4621 (define_expand "movhi"
4622 [(set (match_operand:HI 0 "")
4623 (match_operand:HI 1 ""))]
4626 if (mips_legitimize_move (HImode, operands[0], operands[1]))
4630 (define_insn "*movhi_internal"
4631 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,!u,d,!u,d,ZU,m,*a,*d")
4632 (match_operand:HI 1 "move_operand" "d,J,I,ZU,m,!kbJ,dJ,*d*J,*a"))]
4634 && (register_operand (operands[0], HImode)
4635 || reg_or_0_operand (operands[1], HImode))"
4636 { return mips_output_move (operands[0], operands[1]); }
4637 [(set_attr "move_type" "move,const,const,load,load,store,store,mtlo,mflo")
4638 (set_attr "compression" "all,micromips,*,micromips,*,micromips,*,*,*")
4639 (set_attr "mode" "HI")])
4641 (define_insn "*movhi_mips16"
4642 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4643 (match_operand:HI 1 "move_operand" "d,d,y,K,N,m,d,*a"))]
4645 && (register_operand (operands[0], HImode)
4646 || register_operand (operands[1], HImode))"
4647 { return mips_output_move (operands[0], operands[1]); }
4648 [(set_attr "move_type" "move,move,move,const,constN,load,store,mflo")
4649 (set_attr "mode" "HI")])
4651 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
4652 ;; when the original load is a 4 byte instruction but the add and the
4653 ;; load are 2 2 byte instructions.
4656 [(set (match_operand:HI 0 "d_operand")
4657 (mem:HI (plus:SI (match_dup 0)
4658 (match_operand:SI 1 "const_int_operand"))))]
4659 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4660 && ((INTVAL (operands[1]) < 0
4661 && INTVAL (operands[1]) >= -0x80)
4662 || (INTVAL (operands[1]) >= 32 * 2
4663 && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
4664 || (INTVAL (operands[1]) >= 0
4665 && INTVAL (operands[1]) < 32 * 2
4666 && (INTVAL (operands[1]) & 1) != 0))"
4667 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4668 (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
4670 HOST_WIDE_INT val = INTVAL (operands[1]);
4673 operands[2] = const0_rtx;
4674 else if (val >= 32 * 2)
4678 operands[1] = GEN_INT (0x7e + off);
4679 operands[2] = GEN_INT (val - off - 0x7e);
4685 operands[1] = GEN_INT (off);
4686 operands[2] = GEN_INT (val - off);
4690 ;; 8-bit Integer moves
4692 ;; Unlike most other insns, the move insns can't be split with
4693 ;; different predicates, because register spilling and other parts of
4694 ;; the compiler, have memoized the insn number already.
4695 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4697 (define_expand "movqi"
4698 [(set (match_operand:QI 0 "")
4699 (match_operand:QI 1 ""))]
4702 if (mips_legitimize_move (QImode, operands[0], operands[1]))
4706 (define_insn "*movqi_internal"
4707 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,!u,d,!u,d,ZV,m,*a,*d")
4708 (match_operand:QI 1 "move_operand" "d,J,I,ZW,m,!kbJ,dJ,*d*J,*a"))]
4710 && (register_operand (operands[0], QImode)
4711 || reg_or_0_operand (operands[1], QImode))"
4712 { return mips_output_move (operands[0], operands[1]); }
4713 [(set_attr "move_type" "move,const,const,load,load,store,store,mtlo,mflo")
4714 (set_attr "compression" "all,micromips,*,micromips,*,micromips,*,*,*")
4715 (set_attr "mode" "QI")])
4717 (define_insn "*movqi_mips16"
4718 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4719 (match_operand:QI 1 "move_operand" "d,d,y,K,N,m,d,*a"))]
4721 && (register_operand (operands[0], QImode)
4722 || register_operand (operands[1], QImode))"
4723 { return mips_output_move (operands[0], operands[1]); }
4724 [(set_attr "move_type" "move,move,move,const,constN,load,store,mflo")
4725 (set_attr "mode" "QI")])
4727 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
4728 ;; when the original load is a 4 byte instruction but the add and the
4729 ;; load are 2 2 byte instructions.
4732 [(set (match_operand:QI 0 "d_operand")
4733 (mem:QI (plus:SI (match_dup 0)
4734 (match_operand:SI 1 "const_int_operand"))))]
4735 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4736 && ((INTVAL (operands[1]) < 0
4737 && INTVAL (operands[1]) >= -0x80)
4738 || (INTVAL (operands[1]) >= 32
4739 && INTVAL (operands[1]) <= 31 + 0x7f))"
4740 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4741 (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
4743 HOST_WIDE_INT val = INTVAL (operands[1]);
4746 operands[2] = const0_rtx;
4749 operands[1] = GEN_INT (0x7f);
4750 operands[2] = GEN_INT (val - 0x7f);
4754 ;; 32-bit floating point moves
4756 (define_expand "movsf"
4757 [(set (match_operand:SF 0 "")
4758 (match_operand:SF 1 ""))]
4761 if (mips_legitimize_move (SFmode, operands[0], operands[1]))
4765 (define_insn "*movsf_hardfloat"
4766 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
4767 (match_operand:SF 1 "move_operand" "f,G,m,f,G,*d,*f,*G*d,*m,*d"))]
4769 && (register_operand (operands[0], SFmode)
4770 || reg_or_0_operand (operands[1], SFmode))"
4771 { return mips_output_move (operands[0], operands[1]); }
4772 [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
4773 (set_attr "mode" "SF")])
4775 (define_insn "*movsf_softfloat"
4776 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
4777 (match_operand:SF 1 "move_operand" "Gd,m,d"))]
4778 "TARGET_SOFT_FLOAT && !TARGET_MIPS16
4779 && (register_operand (operands[0], SFmode)
4780 || reg_or_0_operand (operands[1], SFmode))"
4781 { return mips_output_move (operands[0], operands[1]); }
4782 [(set_attr "move_type" "move,load,store")
4783 (set_attr "mode" "SF")])
4785 (define_insn "*movsf_mips16"
4786 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
4787 (match_operand:SF 1 "move_operand" "d,d,y,m,d"))]
4789 && (register_operand (operands[0], SFmode)
4790 || register_operand (operands[1], SFmode))"
4791 { return mips_output_move (operands[0], operands[1]); }
4792 [(set_attr "move_type" "move,move,move,load,store")
4793 (set_attr "mode" "SF")])
4795 ;; 64-bit floating point moves
4797 (define_expand "movdf"
4798 [(set (match_operand:DF 0 "")
4799 (match_operand:DF 1 ""))]
4802 if (mips_legitimize_move (DFmode, operands[0], operands[1]))
4806 (define_insn "*movdf_hardfloat"
4807 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
4808 (match_operand:DF 1 "move_operand" "f,G,m,f,G,*d,*f,*d*G,*m,*d"))]
4809 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
4810 && (register_operand (operands[0], DFmode)
4811 || reg_or_0_operand (operands[1], DFmode))"
4812 { return mips_output_move (operands[0], operands[1]); }
4813 [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
4814 (set_attr "mode" "DF")])
4816 (define_insn "*movdf_softfloat"
4817 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m")
4818 (match_operand:DF 1 "move_operand" "dG,m,dG"))]
4819 "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
4820 && (register_operand (operands[0], DFmode)
4821 || reg_or_0_operand (operands[1], DFmode))"
4822 { return mips_output_move (operands[0], operands[1]); }
4823 [(set_attr "move_type" "move,load,store")
4824 (set_attr "mode" "DF")])
4826 (define_insn "*movdf_mips16"
4827 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
4828 (match_operand:DF 1 "move_operand" "d,d,y,m,d"))]
4830 && (register_operand (operands[0], DFmode)
4831 || register_operand (operands[1], DFmode))"
4832 { return mips_output_move (operands[0], operands[1]); }
4833 [(set_attr "move_type" "move,move,move,load,store")
4834 (set_attr "mode" "DF")])
4836 ;; 128-bit integer moves
4838 (define_expand "movti"
4839 [(set (match_operand:TI 0)
4840 (match_operand:TI 1))]
4843 if (mips_legitimize_move (TImode, operands[0], operands[1]))
4847 (define_insn "*movti"
4848 [(set (match_operand:TI 0 "nonimmediate_operand" "=d,d,d,m,*a,*a,*d")
4849 (match_operand:TI 1 "move_operand" "d,i,m,dJ,*J,*d,*a"))]
4852 && (register_operand (operands[0], TImode)
4853 || reg_or_0_operand (operands[1], TImode))"
4854 { return mips_output_move (operands[0], operands[1]); }
4855 [(set_attr "move_type" "move,const,load,store,imul,mtlo,mflo")
4857 (if_then_else (eq_attr "move_type" "imul")
4859 (const_string "TI")))])
4861 (define_insn "*movti_mips16"
4862 [(set (match_operand:TI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4863 (match_operand:TI 1 "move_operand" "d,d,y,K,N,m,d,*a"))]
4866 && (register_operand (operands[0], TImode)
4867 || register_operand (operands[1], TImode))"
4869 [(set_attr "move_type" "move,move,move,const,constN,load,store,mflo")
4870 (set_attr "mode" "TI")])
4872 ;; 128-bit floating point moves
4874 (define_expand "movtf"
4875 [(set (match_operand:TF 0)
4876 (match_operand:TF 1))]
4879 if (mips_legitimize_move (TFmode, operands[0], operands[1]))
4883 ;; This pattern handles both hard- and soft-float cases.
4884 (define_insn "*movtf"
4885 [(set (match_operand:TF 0 "nonimmediate_operand" "=d,d,m,f,d,f,m")
4886 (match_operand:TF 1 "move_operand" "dG,m,dG,dG,f,m,f"))]
4889 && (register_operand (operands[0], TFmode)
4890 || reg_or_0_operand (operands[1], TFmode))"
4892 [(set_attr "move_type" "move,load,store,mtc,mfc,fpload,fpstore")
4893 (set_attr "mode" "TF")])
4895 (define_insn "*movtf_mips16"
4896 [(set (match_operand:TF 0 "nonimmediate_operand" "=d,y,d,d,m")
4897 (match_operand:TF 1 "move_operand" "d,d,y,m,d"))]
4900 && (register_operand (operands[0], TFmode)
4901 || register_operand (operands[1], TFmode))"
4903 [(set_attr "move_type" "move,move,move,load,store")
4904 (set_attr "mode" "TF")])
4907 [(set (match_operand:MOVE64 0 "nonimmediate_operand")
4908 (match_operand:MOVE64 1 "move_operand"))]
4909 "reload_completed && mips_split_move_insn_p (operands[0], operands[1], insn)"
4912 mips_split_move_insn (operands[0], operands[1], curr_insn);
4917 [(set (match_operand:MOVE128 0 "nonimmediate_operand")
4918 (match_operand:MOVE128 1 "move_operand"))]
4919 "reload_completed && mips_split_move_insn_p (operands[0], operands[1], insn)"
4922 mips_split_move_insn (operands[0], operands[1], curr_insn);
4926 ;; When generating mips16 code, split moves of negative constants into
4927 ;; a positive "li" followed by a negation.
4929 [(set (match_operand 0 "d_operand")
4930 (match_operand 1 "const_int_operand"))]
4931 "TARGET_MIPS16 && reload_completed && INTVAL (operands[1]) < 0"
4935 (neg:SI (match_dup 2)))]
4937 operands[2] = gen_lowpart (SImode, operands[0]);
4938 operands[3] = GEN_INT (-INTVAL (operands[1]));
4941 ;; 64-bit paired-single floating point moves
4943 (define_expand "movv2sf"
4944 [(set (match_operand:V2SF 0)
4945 (match_operand:V2SF 1))]
4946 "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
4948 if (mips_legitimize_move (V2SFmode, operands[0], operands[1]))
4952 (define_insn "*movv2sf"
4953 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
4954 (match_operand:V2SF 1 "move_operand" "f,YG,m,f,YG,*d,*f,*d*YG,*m,*d"))]
4956 && TARGET_PAIRED_SINGLE_FLOAT
4957 && (register_operand (operands[0], V2SFmode)
4958 || reg_or_0_operand (operands[1], V2SFmode))"
4959 { return mips_output_move (operands[0], operands[1]); }
4960 [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
4961 (set_attr "mode" "DF")])
4963 ;; Extract the high part of a HI/LO value. See mips_hard_regno_mode_ok_p
4964 ;; for the reason why we can't just use (reg:GPR HI_REGNUM).
4966 ;; When generating VR4120 or VR4130 code, we use MACCHI and DMACCHI
4967 ;; instead of MFHI. This avoids both the normal MIPS III hi/lo hazards
4968 ;; and the errata related to -mfix-vr4130.
4969 (define_insn "mfhi<GPR:mode>_<HILO:mode>"
4970 [(set (match_operand:GPR 0 "register_operand" "=d")
4971 (unspec:GPR [(match_operand:HILO 1 "hilo_operand" "x")]
4974 { return ISA_HAS_MACCHI ? "<GPR:d>macchi\t%0,%.,%." : "mfhi\t%0"; }
4975 [(set_attr "type" "mfhi")
4976 (set_attr "mode" "<GPR:MODE>")])
4978 ;; Set the high part of a HI/LO value, given that the low part has
4979 ;; already been set. See mips_hard_regno_mode_ok_p for the reason
4980 ;; why we can't just use (reg:GPR HI_REGNUM).
4981 (define_insn "mthi<GPR:mode>_<HILO:mode>"
4982 [(set (match_operand:HILO 0 "register_operand" "=x")
4983 (unspec:HILO [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
4984 (match_operand:GPR 2 "register_operand" "l")]
4988 [(set_attr "type" "mthi")
4989 (set_attr "mode" "SI")])
4991 ;; Emit a doubleword move in which exactly one of the operands is
4992 ;; a floating-point register. We can't just emit two normal moves
4993 ;; because of the constraints imposed by the FPU register model;
4994 ;; see mips_cannot_change_mode_class for details. Instead, we keep
4995 ;; the FPR whole and use special patterns to refer to each word of
4996 ;; the other operand.
4998 (define_expand "move_doubleword_fpr<mode>"
4999 [(set (match_operand:SPLITF 0)
5000 (match_operand:SPLITF 1))]
5003 if (FP_REG_RTX_P (operands[0]))
5005 rtx low = mips_subword (operands[1], 0);
5006 rtx high = mips_subword (operands[1], 1);
5007 emit_insn (gen_load_low<mode> (operands[0], low));
5008 if (ISA_HAS_MXHC1 && !TARGET_64BIT)
5009 emit_insn (gen_mthc1<mode> (operands[0], high, operands[0]));
5011 emit_insn (gen_load_high<mode> (operands[0], high, operands[0]));
5015 rtx low = mips_subword (operands[0], 0);
5016 rtx high = mips_subword (operands[0], 1);
5017 emit_insn (gen_store_word<mode> (low, operands[1], const0_rtx));
5018 if (ISA_HAS_MXHC1 && !TARGET_64BIT)
5019 emit_insn (gen_mfhc1<mode> (high, operands[1]));
5021 emit_insn (gen_store_word<mode> (high, operands[1], const1_rtx));
5026 ;; Load the low word of operand 0 with operand 1.
5027 (define_insn "load_low<mode>"
5028 [(set (match_operand:SPLITF 0 "register_operand" "=f,f")
5029 (unspec:SPLITF [(match_operand:<HALFMODE> 1 "general_operand" "dJ,m")]
5033 operands[0] = mips_subword (operands[0], 0);
5034 return mips_output_move (operands[0], operands[1]);
5036 [(set_attr "move_type" "mtc,fpload")
5037 (set_attr "mode" "<HALFMODE>")])
5039 ;; Load the high word of operand 0 from operand 1, preserving the value
5041 (define_insn "load_high<mode>"
5042 [(set (match_operand:SPLITF 0 "register_operand" "=f,f")
5043 (unspec:SPLITF [(match_operand:<HALFMODE> 1 "general_operand" "dJ,m")
5044 (match_operand:SPLITF 2 "register_operand" "0,0")]
5048 operands[0] = mips_subword (operands[0], 1);
5049 return mips_output_move (operands[0], operands[1]);
5051 [(set_attr "move_type" "mtc,fpload")
5052 (set_attr "mode" "<HALFMODE>")])
5054 ;; Store one word of operand 1 in operand 0. Operand 2 is 1 to store the
5055 ;; high word and 0 to store the low word.
5056 (define_insn "store_word<mode>"
5057 [(set (match_operand:<HALFMODE> 0 "nonimmediate_operand" "=d,m")
5058 (unspec:<HALFMODE> [(match_operand:SPLITF 1 "register_operand" "f,f")
5059 (match_operand 2 "const_int_operand")]
5060 UNSPEC_STORE_WORD))]
5063 operands[1] = mips_subword (operands[1], INTVAL (operands[2]));
5064 return mips_output_move (operands[0], operands[1]);
5066 [(set_attr "move_type" "mfc,fpstore")
5067 (set_attr "mode" "<HALFMODE>")])
5069 ;; Move operand 1 to the high word of operand 0 using mthc1, preserving the
5070 ;; value in the low word.
5071 (define_insn "mthc1<mode>"
5072 [(set (match_operand:SPLITF 0 "register_operand" "=f")
5073 (unspec:SPLITF [(match_operand:<HALFMODE> 1 "reg_or_0_operand" "dJ")
5074 (match_operand:SPLITF 2 "register_operand" "0")]
5076 "TARGET_HARD_FLOAT && ISA_HAS_MXHC1"
5078 [(set_attr "move_type" "mtc")
5079 (set_attr "mode" "<HALFMODE>")])
5081 ;; Move high word of operand 1 to operand 0 using mfhc1.
5082 (define_insn "mfhc1<mode>"
5083 [(set (match_operand:<HALFMODE> 0 "register_operand" "=d")
5084 (unspec:<HALFMODE> [(match_operand:SPLITF 1 "register_operand" "f")]
5086 "TARGET_HARD_FLOAT && ISA_HAS_MXHC1"
5088 [(set_attr "move_type" "mfc")
5089 (set_attr "mode" "<HALFMODE>")])
5091 ;; Move a constant that satisfies CONST_GP_P into operand 0.
5092 (define_expand "load_const_gp_<mode>"
5093 [(set (match_operand:P 0 "register_operand" "=d")
5094 (const:P (unspec:P [(const_int 0)] UNSPEC_GP)))])
5096 ;; Insn to initialize $gp for n32/n64 abicalls. Operand 0 is the offset
5097 ;; of _gp from the start of this function. Operand 1 is the incoming
5098 ;; function address.
5099 (define_insn_and_split "loadgp_newabi_<mode>"
5100 [(set (match_operand:P 0 "register_operand" "=&d")
5101 (unspec:P [(match_operand:P 1)
5102 (match_operand:P 2 "register_operand" "d")]
5104 "mips_current_loadgp_style () == LOADGP_NEWABI"
5105 { return mips_must_initialize_gp_p () ? "#" : ""; }
5106 "&& mips_must_initialize_gp_p ()"
5107 [(set (match_dup 0) (match_dup 3))
5108 (set (match_dup 0) (match_dup 4))
5109 (set (match_dup 0) (match_dup 5))]
5111 operands[3] = gen_rtx_HIGH (Pmode, operands[1]);
5112 operands[4] = gen_rtx_PLUS (Pmode, operands[0], operands[2]);
5113 operands[5] = gen_rtx_LO_SUM (Pmode, operands[0], operands[1]);
5115 [(set_attr "type" "ghost")])
5117 ;; Likewise, for -mno-shared code. Operand 0 is the __gnu_local_gp symbol.
5118 (define_insn_and_split "loadgp_absolute_<mode>"
5119 [(set (match_operand:P 0 "register_operand" "=d")
5120 (unspec:P [(match_operand:P 1)] UNSPEC_LOADGP))]
5121 "mips_current_loadgp_style () == LOADGP_ABSOLUTE"
5122 { return mips_must_initialize_gp_p () ? "#" : ""; }
5123 "&& mips_must_initialize_gp_p ()"
5126 mips_emit_move (operands[0], operands[1]);
5129 [(set_attr "type" "ghost")])
5131 ;; This blockage instruction prevents the gp load from being
5132 ;; scheduled after an implicit use of gp. It also prevents
5133 ;; the load from being deleted as dead.
5134 (define_insn "loadgp_blockage"
5135 [(unspec_volatile [(reg:SI 28)] UNSPEC_BLOCKAGE)]
5138 [(set_attr "type" "ghost")])
5140 ;; Initialize $gp for RTP PIC. Operand 0 is the __GOTT_BASE__ symbol
5141 ;; and operand 1 is the __GOTT_INDEX__ symbol.
5142 (define_insn_and_split "loadgp_rtp_<mode>"
5143 [(set (match_operand:P 0 "register_operand" "=d")
5144 (unspec:P [(match_operand:P 1 "symbol_ref_operand")
5145 (match_operand:P 2 "symbol_ref_operand")]
5147 "mips_current_loadgp_style () == LOADGP_RTP"
5148 { return mips_must_initialize_gp_p () ? "#" : ""; }
5149 "&& mips_must_initialize_gp_p ()"
5150 [(set (match_dup 0) (high:P (match_dup 3)))
5151 (set (match_dup 0) (unspec:P [(match_dup 0)
5152 (match_dup 3)] UNSPEC_LOAD_GOT))
5153 (set (match_dup 0) (unspec:P [(match_dup 0)
5154 (match_dup 4)] UNSPEC_LOAD_GOT))]
5156 operands[3] = mips_unspec_address (operands[1], SYMBOL_ABSOLUTE);
5157 operands[4] = mips_unspec_address (operands[2], SYMBOL_HALF);
5159 [(set_attr "type" "ghost")])
5161 ;; Initialize the global pointer for MIPS16 code. Operand 0 is the
5162 ;; global pointer and operand 1 is the MIPS16 register that holds
5163 ;; the required value.
5164 (define_insn_and_split "copygp_mips16_<mode>"
5165 [(set (match_operand:P 0 "register_operand" "=y")
5166 (unspec:P [(match_operand:P 1 "register_operand" "d")]
5169 { return mips_must_initialize_gp_p () ? "#" : ""; }
5170 "&& mips_must_initialize_gp_p ()"
5171 [(set (match_dup 0) (match_dup 1))]
5173 [(set_attr "type" "ghost")])
5175 ;; A placeholder for where the cprestore instruction should go,
5176 ;; if we decide we need one. Operand 0 and operand 1 are as for
5177 ;; "cprestore". Operand 2 is a register that holds the gp value.
5179 ;; The "cprestore" pattern requires operand 2 to be pic_offset_table_rtx,
5180 ;; otherwise any register that holds the correct value will do.
5181 (define_insn_and_split "potential_cprestore_<mode>"
5182 [(set (match_operand:P 0 "cprestore_save_slot_operand" "=X,X")
5183 (unspec:P [(match_operand:P 1 "const_int_operand" "I,i")
5184 (match_operand:P 2 "register_operand" "d,d")]
5185 UNSPEC_POTENTIAL_CPRESTORE))
5186 (clobber (match_operand:P 3 "scratch_operand" "=X,&d"))]
5187 "!TARGET_CPRESTORE_DIRECTIVE || operands[2] == pic_offset_table_rtx"
5188 { return mips_must_initialize_gp_p () ? "#" : ""; }
5189 "mips_must_initialize_gp_p ()"
5192 mips_save_gp_to_cprestore_slot (operands[0], operands[1],
5193 operands[2], operands[3]);
5196 [(set_attr "type" "ghost")])
5198 ;; Emit a .cprestore directive, which normally expands to a single store
5199 ;; instruction. Operand 0 is a (possibly illegitimate) sp-based MEM
5200 ;; for the cprestore slot. Operand 1 is the offset of the slot from
5201 ;; the stack pointer. (This is redundant with operand 0, but it makes
5202 ;; things a little simpler.)
5203 (define_insn "cprestore_<mode>"
5204 [(set (match_operand:P 0 "cprestore_save_slot_operand" "=X,X")
5205 (unspec:P [(match_operand:P 1 "const_int_operand" "I,i")
5208 "TARGET_CPRESTORE_DIRECTIVE"
5210 if (mips_nomacro.nesting_level > 0 && which_alternative == 1)
5211 return ".set\tmacro\;.cprestore\t%1\;.set\tnomacro";
5213 return ".cprestore\t%1";
5215 [(set_attr "type" "store")
5216 (set_attr "insn_count" "1,3")])
5218 (define_insn "use_cprestore_<mode>"
5219 [(set (reg:P CPRESTORE_SLOT_REGNUM)
5220 (match_operand:P 0 "cprestore_load_slot_operand"))]
5223 [(set_attr "type" "ghost")])
5225 ;; Expand in-line code to clear the instruction cache between operand[0] and
5227 (define_expand "clear_cache"
5228 [(match_operand 0 "pmode_register_operand")
5229 (match_operand 1 "pmode_register_operand")]
5235 mips_expand_synci_loop (operands[0], operands[1]);
5236 emit_insn (gen_sync ());
5237 emit_insn (PMODE_INSN (gen_clear_hazard, ()));
5239 else if (mips_cache_flush_func && mips_cache_flush_func[0])
5241 rtx len = gen_reg_rtx (Pmode);
5242 emit_insn (gen_sub3_insn (len, operands[1], operands[0]));
5243 MIPS_ICACHE_SYNC (operands[0], len);
5249 [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)]
5251 { return mips_output_sync (); })
5253 (define_insn "synci"
5254 [(unspec_volatile [(match_operand 0 "pmode_register_operand" "d")]
5259 (define_insn "rdhwr_synci_step_<mode>"
5260 [(set (match_operand:P 0 "register_operand" "=d")
5261 (unspec_volatile [(const_int 1)]
5266 (define_insn "clear_hazard_<mode>"
5267 [(unspec_volatile [(const_int 0)] UNSPEC_CLEAR_HAZARD)
5268 (clobber (reg:P RETURN_ADDR_REGNUM))]
5271 return "%(%<bal\t1f\n"
5273 "1:\t<d>addiu\t$31,$31,12\n"
5277 [(set_attr "insn_count" "5")])
5279 ;; Cache operations for R4000-style caches.
5280 (define_insn "mips_cache"
5281 [(set (mem:BLK (scratch))
5282 (unspec:BLK [(match_operand:SI 0 "const_int_operand")
5283 (match_operand:QI 1 "address_operand" "p")]
5284 UNSPEC_MIPS_CACHE))]
5288 ;; Similar, but with the operands hard-coded to an R10K cache barrier
5289 ;; operation. We keep the pattern distinct so that we can identify
5290 ;; cache operations inserted by -mr10k-cache-barrier=, and so that
5291 ;; the operation is never inserted into a delay slot.
5292 (define_insn "r10k_cache_barrier"
5293 [(set (mem:BLK (scratch))
5294 (unspec:BLK [(const_int 0)] UNSPEC_R10K_CACHE_BARRIER))]
5297 [(set_attr "can_delay" "no")])
5299 ;; Block moves, see mips.c for more details.
5300 ;; Argument 0 is the destination
5301 ;; Argument 1 is the source
5302 ;; Argument 2 is the length
5303 ;; Argument 3 is the alignment
5305 (define_expand "movmemsi"
5306 [(parallel [(set (match_operand:BLK 0 "general_operand")
5307 (match_operand:BLK 1 "general_operand"))
5308 (use (match_operand:SI 2 ""))
5309 (use (match_operand:SI 3 "const_int_operand"))])]
5310 "!TARGET_MIPS16 && !TARGET_MEMCPY"
5312 if (mips_expand_block_move (operands[0], operands[1], operands[2]))
5319 ;; ....................
5323 ;; ....................
5325 (define_expand "<optab><mode>3"
5326 [(set (match_operand:GPR 0 "register_operand")
5327 (any_shift:GPR (match_operand:GPR 1 "register_operand")
5328 (match_operand:SI 2 "arith_operand")))]
5331 /* On the mips16, a shift of more than 8 is a four byte instruction,
5332 so, for a shift between 8 and 16, it is just as fast to do two
5333 shifts of 8 or less. If there is a lot of shifting going on, we
5334 may win in CSE. Otherwise combine will put the shifts back
5335 together again. This can be called by mips_function_arg, so we must
5336 be careful not to allocate a new register if we've reached the
5340 && CONST_INT_P (operands[2])
5341 && INTVAL (operands[2]) > 8
5342 && INTVAL (operands[2]) <= 16
5343 && !reload_in_progress
5344 && !reload_completed)
5346 rtx temp = gen_reg_rtx (<MODE>mode);
5348 emit_insn (gen_<optab><mode>3 (temp, operands[1], GEN_INT (8)));
5349 emit_insn (gen_<optab><mode>3 (operands[0], temp,
5350 GEN_INT (INTVAL (operands[2]) - 8)));
5355 (define_insn "*<optab><mode>3"
5356 [(set (match_operand:GPR 0 "register_operand" "=!u,d")
5357 (any_shift:GPR (match_operand:GPR 1 "register_operand" "!u,d")
5358 (match_operand:SI 2 "arith_operand" "Uib3,dI")))]
5361 if (CONST_INT_P (operands[2]))
5362 operands[2] = GEN_INT (INTVAL (operands[2])
5363 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
5365 return "<d><insn>\t%0,%1,%2";
5367 [(set_attr "type" "shift")
5368 (set_attr "compression" "<shift_compression>,none")
5369 (set_attr "mode" "<MODE>")])
5371 (define_insn "*<optab>si3_extend"
5372 [(set (match_operand:DI 0 "register_operand" "=d")
5374 (any_shift:SI (match_operand:SI 1 "register_operand" "d")
5375 (match_operand:SI 2 "arith_operand" "dI"))))]
5376 "TARGET_64BIT && !TARGET_MIPS16"
5378 if (CONST_INT_P (operands[2]))
5379 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5381 return "<insn>\t%0,%1,%2";
5383 [(set_attr "type" "shift")
5384 (set_attr "mode" "SI")])
5386 (define_insn "*<optab>si3_mips16"
5387 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
5388 (any_shift:SI (match_operand:SI 1 "register_operand" "0,d,d")
5389 (match_operand:SI 2 "arith_operand" "d,Uib3,I")))]
5392 if (which_alternative == 0)
5393 return "<insn>\t%0,%2";
5395 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5396 return "<insn>\t%0,%1,%2";
5398 [(set_attr "type" "shift")
5399 (set_attr "mode" "SI")
5400 (set_attr "extended_mips16" "no,no,yes")])
5402 ;; We need separate DImode MIPS16 patterns because of the irregularity
5404 (define_insn "*ashldi3_mips16"
5405 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
5406 (ashift:DI (match_operand:DI 1 "register_operand" "0,d,d")
5407 (match_operand:SI 2 "arith_operand" "d,Uib3,I")))]
5408 "TARGET_64BIT && TARGET_MIPS16"
5410 if (which_alternative == 0)
5411 return "dsll\t%0,%2";
5413 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5414 return "dsll\t%0,%1,%2";
5416 [(set_attr "type" "shift")
5417 (set_attr "mode" "DI")
5418 (set_attr "extended_mips16" "no,no,yes")])
5420 (define_insn "*ashrdi3_mips16"
5421 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
5422 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0,0")
5423 (match_operand:SI 2 "arith_operand" "d,Uib3,I")))]
5424 "TARGET_64BIT && TARGET_MIPS16"
5426 if (CONST_INT_P (operands[2]))
5427 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5429 return "dsra\t%0,%2";
5431 [(set_attr "type" "shift")
5432 (set_attr "mode" "DI")
5433 (set_attr "extended_mips16" "no,no,yes")])
5435 (define_insn "*lshrdi3_mips16"
5436 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
5437 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0,0")
5438 (match_operand:SI 2 "arith_operand" "d,Uib3,I")))]
5439 "TARGET_64BIT && TARGET_MIPS16"
5441 if (CONST_INT_P (operands[2]))
5442 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5444 return "dsrl\t%0,%2";
5446 [(set_attr "type" "shift")
5447 (set_attr "mode" "DI")
5448 (set_attr "extended_mips16" "no,no,yes")])
5450 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5453 [(set (match_operand:GPR 0 "d_operand")
5454 (any_shift:GPR (match_operand:GPR 1 "d_operand")
5455 (match_operand:GPR 2 "const_int_operand")))]
5456 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5457 && INTVAL (operands[2]) > 8
5458 && INTVAL (operands[2]) <= 16"
5459 [(set (match_dup 0) (any_shift:GPR (match_dup 1) (const_int 8)))
5460 (set (match_dup 0) (any_shift:GPR (match_dup 0) (match_dup 2)))]
5461 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5463 ;; If we load a byte on the mips16 as a bitfield, the resulting
5464 ;; sequence of instructions is too complicated for combine, because it
5465 ;; involves four instructions: a load, a shift, a constant load into a
5466 ;; register, and an and (the key problem here is that the mips16 does
5467 ;; not have and immediate). We recognize a shift of a load in order
5468 ;; to make it simple enough for combine to understand.
5470 ;; The instruction count here is the worst case.
5471 (define_insn_and_split ""
5472 [(set (match_operand:SI 0 "register_operand" "=d")
5473 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
5474 (match_operand:SI 2 "immediate_operand" "I")))]
5478 [(set (match_dup 0) (match_dup 1))
5479 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
5481 [(set_attr "type" "load")
5482 (set_attr "mode" "SI")
5483 (set (attr "insn_count")
5484 (symbol_ref "mips_load_store_insns (operands[1], insn) + 2"))])
5486 (define_insn "rotr<mode>3"
5487 [(set (match_operand:GPR 0 "register_operand" "=d")
5488 (rotatert:GPR (match_operand:GPR 1 "register_operand" "d")
5489 (match_operand:SI 2 "arith_operand" "dI")))]
5492 if (CONST_INT_P (operands[2]))
5493 gcc_assert (INTVAL (operands[2]) >= 0
5494 && INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode));
5496 return "<d>ror\t%0,%1,%2";
5498 [(set_attr "type" "shift")
5499 (set_attr "mode" "<MODE>")])
5501 (define_insn "bswaphi2"
5502 [(set (match_operand:HI 0 "register_operand" "=d")
5503 (bswap:HI (match_operand:HI 1 "register_operand" "d")))]
5506 [(set_attr "type" "shift")])
5508 (define_insn_and_split "bswapsi2"
5509 [(set (match_operand:SI 0 "register_operand" "=d")
5510 (bswap:SI (match_operand:SI 1 "register_operand" "d")))]
5511 "ISA_HAS_WSBH && ISA_HAS_ROR"
5514 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_WSBH))
5515 (set (match_dup 0) (rotatert:SI (match_dup 0) (const_int 16)))]
5517 [(set_attr "insn_count" "2")])
5519 (define_insn_and_split "bswapdi2"
5520 [(set (match_operand:DI 0 "register_operand" "=d")
5521 (bswap:DI (match_operand:DI 1 "register_operand" "d")))]
5522 "TARGET_64BIT && ISA_HAS_WSBH"
5525 [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_DSBH))
5526 (set (match_dup 0) (unspec:DI [(match_dup 0)] UNSPEC_DSHD))]
5528 [(set_attr "insn_count" "2")])
5531 [(set (match_operand:SI 0 "register_operand" "=d")
5532 (unspec:SI [(match_operand:SI 1 "register_operand" "d")] UNSPEC_WSBH))]
5535 [(set_attr "type" "shift")])
5538 [(set (match_operand:DI 0 "register_operand" "=d")
5539 (unspec:DI [(match_operand:DI 1 "register_operand" "d")] UNSPEC_DSBH))]
5540 "TARGET_64BIT && ISA_HAS_WSBH"
5542 [(set_attr "type" "shift")])
5545 [(set (match_operand:DI 0 "register_operand" "=d")
5546 (unspec:DI [(match_operand:DI 1 "register_operand" "d")] UNSPEC_DSHD))]
5547 "TARGET_64BIT && ISA_HAS_WSBH"
5549 [(set_attr "type" "shift")])
5552 ;; ....................
5554 ;; CONDITIONAL BRANCHES
5556 ;; ....................
5558 ;; Conditional branches on floating-point equality tests.
5560 (define_insn "*branch_fp"
5563 (match_operator 1 "equality_operator"
5564 [(match_operand:CC 2 "register_operand" "z")
5566 (label_ref (match_operand 0 "" ""))
5570 return mips_output_conditional_branch (insn, operands,
5571 MIPS_BRANCH ("b%F1", "%Z2%0"),
5572 MIPS_BRANCH ("b%W1", "%Z2%0"));
5574 [(set_attr "type" "branch")])
5576 (define_insn "*branch_fp_inverted"
5579 (match_operator 1 "equality_operator"
5580 [(match_operand:CC 2 "register_operand" "z")
5583 (label_ref (match_operand 0 "" ""))))]
5586 return mips_output_conditional_branch (insn, operands,
5587 MIPS_BRANCH ("b%W1", "%Z2%0"),
5588 MIPS_BRANCH ("b%F1", "%Z2%0"));
5590 [(set_attr "type" "branch")])
5592 ;; Conditional branches on ordered comparisons with zero.
5594 (define_insn "*branch_order<mode>"
5597 (match_operator 1 "order_operator"
5598 [(match_operand:GPR 2 "register_operand" "d")
5600 (label_ref (match_operand 0 "" ""))
5603 { return mips_output_order_conditional_branch (insn, operands, false); }
5604 [(set_attr "type" "branch")])
5606 (define_insn "*branch_order<mode>_inverted"
5609 (match_operator 1 "order_operator"
5610 [(match_operand:GPR 2 "register_operand" "d")
5613 (label_ref (match_operand 0 "" ""))))]
5615 { return mips_output_order_conditional_branch (insn, operands, true); }
5616 [(set_attr "type" "branch")])
5618 ;; Conditional branch on equality comparison.
5620 (define_insn "*branch_equality<mode>"
5623 (match_operator 1 "equality_operator"
5624 [(match_operand:GPR 2 "register_operand" "d")
5625 (match_operand:GPR 3 "reg_or_0_operand" "dJ")])
5626 (label_ref (match_operand 0 "" ""))
5630 /* For a simple BNEZ or BEQZ microMIPS branch. */
5631 if (TARGET_MICROMIPS
5632 && operands[3] == const0_rtx
5633 && get_attr_length (insn) <= 8)
5634 return mips_output_conditional_branch (insn, operands,
5636 "%*b%N1z%:\t%2,%0");
5638 return mips_output_conditional_branch (insn, operands,
5639 MIPS_BRANCH ("b%C1", "%2,%z3,%0"),
5640 MIPS_BRANCH ("b%N1", "%2,%z3,%0"));
5642 [(set_attr "type" "branch")])
5644 (define_insn "*branch_equality<mode>_inverted"
5647 (match_operator 1 "equality_operator"
5648 [(match_operand:GPR 2 "register_operand" "d")
5649 (match_operand:GPR 3 "reg_or_0_operand" "dJ")])
5651 (label_ref (match_operand 0 "" ""))))]
5654 /* For a simple BNEZ or BEQZ microMIPS branch. */
5655 if (TARGET_MICROMIPS
5656 && operands[3] == const0_rtx
5657 && get_attr_length (insn) <= 8)
5658 return mips_output_conditional_branch (insn, operands,
5660 "%*b%C0z%:\t%2,%1");
5662 return mips_output_conditional_branch (insn, operands,
5663 MIPS_BRANCH ("b%N1", "%2,%z3,%0"),
5664 MIPS_BRANCH ("b%C1", "%2,%z3,%0"));
5666 [(set_attr "type" "branch")])
5670 (define_insn "*branch_equality<mode>_mips16"
5673 (match_operator 1 "equality_operator"
5674 [(match_operand:GPR 2 "register_operand" "d,t")
5676 (label_ref (match_operand 0 "" ""))
5682 [(set_attr "type" "branch")])
5684 (define_insn "*branch_equality<mode>_mips16_inverted"
5687 (match_operator 1 "equality_operator"
5688 [(match_operand:GPR 2 "register_operand" "d,t")
5691 (label_ref (match_operand 0 "" ""))))]
5696 [(set_attr "type" "branch")])
5698 (define_expand "cbranch<mode>4"
5700 (if_then_else (match_operator 0 "comparison_operator"
5701 [(match_operand:GPR 1 "register_operand")
5702 (match_operand:GPR 2 "nonmemory_operand")])
5703 (label_ref (match_operand 3 ""))
5707 mips_expand_conditional_branch (operands);
5711 (define_expand "cbranch<mode>4"
5713 (if_then_else (match_operator 0 "comparison_operator"
5714 [(match_operand:SCALARF 1 "register_operand")
5715 (match_operand:SCALARF 2 "register_operand")])
5716 (label_ref (match_operand 3 ""))
5720 mips_expand_conditional_branch (operands);
5724 ;; Used to implement built-in functions.
5725 (define_expand "condjump"
5727 (if_then_else (match_operand 0)
5728 (label_ref (match_operand 1))
5731 ;; Branch if bit is set/clear.
5733 (define_insn "*branch_bit<bbv><mode>"
5736 (equality_op (zero_extract:GPR
5737 (match_operand:GPR 1 "register_operand" "d")
5739 (match_operand 2 "const_int_operand" ""))
5741 (label_ref (match_operand 0 ""))
5743 "ISA_HAS_BBIT && UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
5746 mips_output_conditional_branch (insn, operands,
5747 MIPS_BRANCH ("bbit<bbv>", "%1,%2,%0"),
5748 MIPS_BRANCH ("bbit<bbinv>", "%1,%2,%0"));
5750 [(set_attr "type" "branch")
5751 (set_attr "branch_likely" "no")])
5753 (define_insn "*branch_bit<bbv><mode>_inverted"
5756 (equality_op (zero_extract:GPR
5757 (match_operand:GPR 1 "register_operand" "d")
5759 (match_operand 2 "const_int_operand" ""))
5762 (label_ref (match_operand 0 ""))))]
5763 "ISA_HAS_BBIT && UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
5766 mips_output_conditional_branch (insn, operands,
5767 MIPS_BRANCH ("bbit<bbinv>", "%1,%2,%0"),
5768 MIPS_BRANCH ("bbit<bbv>", "%1,%2,%0"));
5770 [(set_attr "type" "branch")
5771 (set_attr "branch_likely" "no")])
5774 ;; ....................
5776 ;; SETTING A REGISTER FROM A COMPARISON
5778 ;; ....................
5780 ;; Destination is always set in SI mode.
5782 (define_expand "cstore<mode>4"
5783 [(set (match_operand:SI 0 "register_operand")
5784 (match_operator:SI 1 "mips_cstore_operator"
5785 [(match_operand:GPR 2 "register_operand")
5786 (match_operand:GPR 3 "nonmemory_operand")]))]
5789 mips_expand_scc (operands);
5793 (define_insn "*seq_zero_<GPR:mode><GPR2:mode>"
5794 [(set (match_operand:GPR2 0 "register_operand" "=d")
5795 (eq:GPR2 (match_operand:GPR 1 "register_operand" "d")
5797 "!TARGET_MIPS16 && !ISA_HAS_SEQ_SNE"
5799 [(set_attr "type" "slt")
5800 (set_attr "mode" "<GPR:MODE>")])
5802 (define_insn "*seq_zero_<GPR:mode><GPR2:mode>_mips16"
5803 [(set (match_operand:GPR2 0 "register_operand" "=t")
5804 (eq:GPR2 (match_operand:GPR 1 "register_operand" "d")
5806 "TARGET_MIPS16 && !ISA_HAS_SEQ_SNE"
5808 [(set_attr "type" "slt")
5809 (set_attr "mode" "<GPR:MODE>")])
5811 ;; Generate sltiu unless using seq results in better code.
5812 (define_insn "*seq_<GPR:mode><GPR2:mode>_seq"
5813 [(set (match_operand:GPR2 0 "register_operand" "=d,d,d")
5814 (eq:GPR2 (match_operand:GPR 1 "register_operand" "%d,d,d")
5815 (match_operand:GPR 2 "reg_imm10_operand" "d,J,YB")))]
5821 [(set_attr "type" "slt")
5822 (set_attr "mode" "<GPR:MODE>")])
5824 (define_insn "*sne_zero_<GPR:mode><GPR2:mode>"
5825 [(set (match_operand:GPR2 0 "register_operand" "=d")
5826 (ne:GPR2 (match_operand:GPR 1 "register_operand" "d")
5828 "!TARGET_MIPS16 && !ISA_HAS_SEQ_SNE"
5830 [(set_attr "type" "slt")
5831 (set_attr "mode" "<GPR:MODE>")])
5833 ;; Generate sltu unless using sne results in better code.
5834 (define_insn "*sne_<GPR:mode><GPR2:mode>_sne"
5835 [(set (match_operand:GPR2 0 "register_operand" "=d,d,d")
5836 (ne:GPR2 (match_operand:GPR 1 "register_operand" "%d,d,d")
5837 (match_operand:GPR 2 "reg_imm10_operand" "d,J,YB")))]
5843 [(set_attr "type" "slt")
5844 (set_attr "mode" "<GPR:MODE>")])
5846 (define_insn "*sgt<u>_<GPR:mode><GPR2:mode>"
5847 [(set (match_operand:GPR2 0 "register_operand" "=d")
5848 (any_gt:GPR2 (match_operand:GPR 1 "register_operand" "d")
5849 (match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
5852 [(set_attr "type" "slt")
5853 (set_attr "mode" "<GPR:MODE>")])
5855 (define_insn "*sgt<u>_<GPR:mode><GPR2:mode>_mips16"
5856 [(set (match_operand:GPR2 0 "register_operand" "=t")
5857 (any_gt:GPR2 (match_operand:GPR 1 "register_operand" "d")
5858 (match_operand:GPR 2 "register_operand" "d")))]
5861 [(set_attr "type" "slt")
5862 (set_attr "mode" "<GPR:MODE>")])
5864 (define_insn "*sge<u>_<GPR:mode><GPR2:mode>"
5865 [(set (match_operand:GPR2 0 "register_operand" "=d")
5866 (any_ge:GPR2 (match_operand:GPR 1 "register_operand" "d")
5870 [(set_attr "type" "slt")
5871 (set_attr "mode" "<GPR:MODE>")])
5873 (define_insn "*slt<u>_<GPR:mode><GPR2:mode>"
5874 [(set (match_operand:GPR2 0 "register_operand" "=d")
5875 (any_lt:GPR2 (match_operand:GPR 1 "register_operand" "d")
5876 (match_operand:GPR 2 "arith_operand" "dI")))]
5879 [(set_attr "type" "slt")
5880 (set_attr "mode" "<GPR:MODE>")])
5882 (define_insn "*slt<u>_<GPR:mode><GPR2:mode>_mips16"
5883 [(set (match_operand:GPR2 0 "register_operand" "=t,t,t")
5884 (any_lt:GPR2 (match_operand:GPR 1 "register_operand" "d,d,d")
5885 (match_operand:GPR 2 "arith_operand" "d,Uub8,I")))]
5888 [(set_attr "type" "slt")
5889 (set_attr "mode" "<GPR:MODE>")
5890 (set_attr "extended_mips16" "no,no,yes")])
5892 (define_insn "*sle<u>_<GPR:mode><GPR2:mode>"
5893 [(set (match_operand:GPR2 0 "register_operand" "=d")
5894 (any_le:GPR2 (match_operand:GPR 1 "register_operand" "d")
5895 (match_operand:GPR 2 "sle_operand" "")))]
5898 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5899 return "slt<u>\t%0,%1,%2";
5901 [(set_attr "type" "slt")
5902 (set_attr "mode" "<GPR:MODE>")])
5904 (define_insn "*sle<u>_<GPR:mode><GPR2:mode>_mips16"
5905 [(set (match_operand:GPR2 0 "register_operand" "=t,t")
5906 (any_le:GPR2 (match_operand:GPR 1 "register_operand" "d,d")
5907 (match_operand:GPR 2 "sle_operand" "Udb8,i")))]
5910 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5911 return "slt<u>\t%1,%2";
5913 [(set_attr "type" "slt")
5914 (set_attr "mode" "<GPR:MODE>")
5915 (set_attr "extended_mips16" "no,yes")])
5918 ;; ....................
5920 ;; FLOATING POINT COMPARISONS
5922 ;; ....................
5924 (define_insn "s<code>_<mode>"
5925 [(set (match_operand:CC 0 "register_operand" "=z")
5926 (fcond:CC (match_operand:SCALARF 1 "register_operand" "f")
5927 (match_operand:SCALARF 2 "register_operand" "f")))]
5929 "c.<fcond>.<fmt>\t%Z0%1,%2"
5930 [(set_attr "type" "fcmp")
5931 (set_attr "mode" "FPSW")])
5933 (define_insn "s<code>_<mode>"
5934 [(set (match_operand:CC 0 "register_operand" "=z")
5935 (swapped_fcond:CC (match_operand:SCALARF 1 "register_operand" "f")
5936 (match_operand:SCALARF 2 "register_operand" "f")))]
5938 "c.<swapped_fcond>.<fmt>\t%Z0%2,%1"
5939 [(set_attr "type" "fcmp")
5940 (set_attr "mode" "FPSW")])
5943 ;; ....................
5945 ;; UNCONDITIONAL BRANCHES
5947 ;; ....................
5949 ;; Unconditional branches.
5951 (define_expand "jump"
5953 (label_ref (match_operand 0)))])
5955 (define_insn "*jump_absolute"
5957 (label_ref (match_operand 0)))]
5958 "!TARGET_MIPS16 && TARGET_ABSOLUTE_JUMPS"
5960 if (get_attr_length (insn) <= 8)
5961 return "%*b\t%l0%/";
5963 return MIPS_ABSOLUTE_JUMP ("%*j\t%l0%/");
5965 [(set_attr "type" "branch")])
5967 (define_insn "*jump_pic"
5969 (label_ref (match_operand 0)))]
5970 "!TARGET_MIPS16 && !TARGET_ABSOLUTE_JUMPS"
5972 if (get_attr_length (insn) <= 8)
5973 return "%*b\t%l0%/";
5976 mips_output_load_label (operands[0]);
5977 return "%*jr\t%@%/%]";
5980 [(set_attr "type" "branch")])
5982 ;; We need a different insn for the mips16, because a mips16 branch
5983 ;; does not have a delay slot.
5985 (define_insn "*jump_mips16"
5987 (label_ref (match_operand 0 "" "")))]
5990 [(set_attr "type" "branch")
5991 (set (attr "length")
5992 ;; This calculation is like the normal branch one, but the
5993 ;; range of the unextended instruction is [-0x800, 0x7fe] rather
5994 ;; than [-0x100, 0xfe]. This translates to a range of:
5996 ;; [-(0x800 - sizeof (branch)), 0x7fe]
5997 ;; == [-0x7fe, 0x7fe]
5999 ;; from the shorten_branches reference address. Long-branch
6000 ;; sequences will replace this one, so the minimum length
6001 ;; is one instruction shorter than for conditional branches.
6002 (cond [(and (le (minus (match_dup 0) (pc)) (const_int 2046))
6003 (le (minus (pc) (match_dup 0)) (const_int 2046)))
6005 (and (le (minus (match_dup 0) (pc)) (const_int 65534))
6006 (le (minus (pc) (match_dup 0)) (const_int 65532)))
6008 (and (match_test "TARGET_ABICALLS")
6009 (not (match_test "TARGET_ABSOLUTE_ABICALLS")))
6011 (match_test "Pmode == SImode")
6013 ] (const_int 22)))])
6015 (define_expand "indirect_jump"
6016 [(set (pc) (match_operand 0 "register_operand"))]
6019 operands[0] = force_reg (Pmode, operands[0]);
6020 emit_jump_insn (PMODE_INSN (gen_indirect_jump, (operands[0])));
6024 (define_insn "indirect_jump_<mode>"
6025 [(set (pc) (match_operand:P 0 "register_operand" "d"))]
6028 if (TARGET_MICROMIPS)
6029 return "%*jr%:\t%0";
6033 [(set_attr "type" "jump")
6034 (set_attr "mode" "none")])
6036 ;; A combined jump-and-move instruction, used for MIPS16 long-branch
6037 ;; sequences. Having a dedicated pattern is more convenient than
6038 ;; creating a SEQUENCE for this special case.
6039 (define_insn "indirect_jump_and_restore_<mode>"
6040 [(set (pc) (match_operand:P 1 "register_operand" "d"))
6041 (set (match_operand:P 0 "register_operand" "=d")
6042 (match_operand:P 2 "register_operand" "y"))]
6044 "%(%<jr\t%1\;move\t%0,%2%>%)"
6045 [(set_attr "type" "multi")
6046 (set_attr "extended_mips16" "yes")])
6048 (define_expand "tablejump"
6050 (match_operand 0 "register_operand"))
6051 (use (label_ref (match_operand 1 "")))]
6052 "!TARGET_MIPS16_SHORT_JUMP_TABLES"
6055 operands[0] = expand_binop (Pmode, add_optab, operands[0],
6056 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
6057 else if (TARGET_RTP_PIC)
6059 /* When generating RTP PIC, we use case table entries that are relative
6060 to the start of the function. Add the function's address to the
6062 rtx start = get_hard_reg_initial_val (Pmode, PIC_FUNCTION_ADDR_REGNUM);
6063 operands[0] = expand_binop (ptr_mode, add_optab, operands[0],
6064 start, 0, 0, OPTAB_WIDEN);
6067 emit_jump_insn (PMODE_INSN (gen_tablejump, (operands[0], operands[1])));
6071 (define_insn "tablejump_<mode>"
6073 (match_operand:P 0 "register_operand" "d"))
6074 (use (label_ref (match_operand 1 "" "")))]
6077 if (TARGET_MICROMIPS)
6078 return "%*jr%:\t%0";
6082 [(set_attr "type" "jump")
6083 (set_attr "mode" "none")])
6085 ;; For MIPS16, we don't know whether a given jump table will use short or
6086 ;; word-sized offsets until late in compilation, when we are able to determine
6087 ;; the sizes of the insns which comprise the containing function. This
6088 ;; necessitates the use of the casesi rather than the tablejump pattern, since
6089 ;; the latter tries to calculate the index of the offset to jump through early
6090 ;; in compilation, i.e. at expand time, when nothing is known about the
6091 ;; eventual function layout.
6093 (define_expand "casesi"
6094 [(match_operand:SI 0 "register_operand" "") ; index to jump on
6095 (match_operand:SI 1 "const_int_operand" "") ; lower bound
6096 (match_operand:SI 2 "const_int_operand" "") ; total range
6097 (match_operand 3 "" "") ; table label
6098 (match_operand 4 "" "")] ; out of range label
6099 "TARGET_MIPS16_SHORT_JUMP_TABLES"
6101 if (operands[1] != const0_rtx)
6103 rtx reg = gen_reg_rtx (SImode);
6104 rtx offset = gen_int_mode (-INTVAL (operands[1]), SImode);
6106 if (!arith_operand (offset, SImode))
6107 offset = force_reg (SImode, offset);
6109 emit_insn (gen_addsi3 (reg, operands[0], offset));
6113 if (!arith_operand (operands[0], SImode))
6114 operands[0] = force_reg (SImode, operands[0]);
6116 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6118 emit_jump_insn (PMODE_INSN (gen_casesi_internal_mips16,
6119 (operands[0], operands[2],
6120 operands[3], operands[4])));
6125 (define_insn "casesi_internal_mips16_<mode>"
6128 (leu (match_operand:SI 0 "register_operand" "d")
6129 (match_operand:SI 1 "arith_operand" "dI"))
6132 (label_ref (match_operand 2 "" ""))]
6133 UNSPEC_CASESI_DISPATCH)
6134 (label_ref (match_operand 3 "" ""))))
6135 (clobber (match_scratch:P 4 "=d"))
6136 (clobber (match_scratch:P 5 "=d"))
6137 (clobber (reg:SI MIPS16_T_REGNUM))]
6138 "TARGET_MIPS16_SHORT_JUMP_TABLES"
6140 rtx diff_vec = PATTERN (NEXT_INSN (as_a <rtx_insn *> (operands[2])));
6142 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
6144 output_asm_insn ("sltu\t%0, %1", operands);
6145 output_asm_insn ("bteqz\t%3", operands);
6147 switch (GET_MODE (diff_vec))
6150 output_asm_insn ("sll\t%5, %0, 1", operands);
6151 output_asm_insn ("la\t%4, %2", operands);
6152 output_asm_insn ("<d>addu\t%5, %4, %5", operands);
6153 output_asm_insn ("lh\t%5, 0(%5)", operands);
6157 output_asm_insn ("sll\t%5, %0, 2", operands);
6158 output_asm_insn ("la\t%4, %2", operands);
6159 output_asm_insn ("<d>addu\t%5, %4, %5", operands);
6160 output_asm_insn ("lw\t%5, 0(%5)", operands);
6167 output_asm_insn ("addu\t%4, %4, %5", operands);
6171 [(set_attr "insn_count" "16")])
6173 ;; For TARGET_USE_GOT, we save the gp in the jmp_buf as well.
6174 ;; While it is possible to either pull it off the stack (in the
6175 ;; o32 case) or recalculate it given t9 and our target label,
6176 ;; it takes 3 or 4 insns to do so.
6178 (define_expand "builtin_setjmp_setup"
6179 [(use (match_operand 0 "register_operand"))]
6184 addr = plus_constant (Pmode, operands[0], GET_MODE_SIZE (Pmode) * 3);
6185 mips_emit_move (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
6189 ;; Restore the gp that we saved above. Despite the earlier comment, it seems
6190 ;; that older code did recalculate the gp from $25. Continue to jump through
6191 ;; $25 for compatibility (we lose nothing by doing so).
6193 (define_expand "builtin_longjmp"
6194 [(use (match_operand 0 "register_operand"))]
6197 /* The elements of the buffer are, in order: */
6198 int W = GET_MODE_SIZE (Pmode);
6199 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
6200 rtx lab = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], 1*W));
6201 rtx stack = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], 2*W));
6202 rtx gpv = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], 3*W));
6203 rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
6204 /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
6205 The target is bound to be using $28 as the global pointer
6206 but the current function might not be. */
6207 rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
6209 /* This bit is similar to expand_builtin_longjmp except that it
6210 restores $gp as well. */
6211 mips_emit_move (hard_frame_pointer_rtx, fp);
6212 mips_emit_move (pv, lab);
6213 emit_stack_restore (SAVE_NONLOCAL, stack);
6214 mips_emit_move (gp, gpv);
6215 emit_use (hard_frame_pointer_rtx);
6216 emit_use (stack_pointer_rtx);
6218 emit_indirect_jump (pv);
6223 ;; ....................
6225 ;; Function prologue/epilogue
6227 ;; ....................
6230 (define_expand "prologue"
6234 mips_expand_prologue ();
6238 ;; Block any insns from being moved before this point, since the
6239 ;; profiling call to mcount can use various registers that aren't
6240 ;; saved or used to pass arguments.
6242 (define_insn "blockage"
6243 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
6246 [(set_attr "type" "ghost")
6247 (set_attr "mode" "none")])
6249 (define_insn "probe_stack_range_<P:mode>"
6250 [(set (match_operand:P 0 "register_operand" "=d")
6251 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6252 (match_operand:P 2 "register_operand" "d")]
6253 UNSPEC_PROBE_STACK_RANGE))]
6255 { return mips_output_probe_stack_range (operands[0], operands[2]); }
6256 [(set_attr "type" "unknown")
6257 (set_attr "can_delay" "no")
6258 (set_attr "mode" "<MODE>")])
6260 (define_expand "epilogue"
6264 mips_expand_epilogue (false);
6268 (define_expand "sibcall_epilogue"
6272 mips_expand_epilogue (true);
6276 ;; Trivial return. Make it look like a normal return insn as that
6277 ;; allows jump optimizations to work better.
6279 (define_expand "return"
6281 "mips_can_use_return_insn ()"
6282 { mips_expand_before_return (); })
6284 (define_expand "simple_return"
6287 { mips_expand_before_return (); })
6289 (define_insn "*<optab>"
6293 if (TARGET_MICROMIPS)
6294 return "%*jr%:\t$31";
6296 return "%*j\t$31%/";
6298 [(set_attr "type" "jump")
6299 (set_attr "mode" "none")])
6303 (define_insn "<optab>_internal"
6305 (use (match_operand 0 "pmode_register_operand" ""))]
6308 if (TARGET_MICROMIPS)
6309 return "%*jr%:\t%0";
6313 [(set_attr "type" "jump")
6314 (set_attr "mode" "none")])
6316 ;; Exception return.
6317 (define_insn "mips_eret"
6319 (unspec_volatile [(const_int 0)] UNSPEC_ERET)]
6322 [(set_attr "type" "trap")
6323 (set_attr "mode" "none")])
6325 ;; Debug exception return.
6326 (define_insn "mips_deret"
6328 (unspec_volatile [(const_int 0)] UNSPEC_DERET)]
6331 [(set_attr "type" "trap")
6332 (set_attr "mode" "none")])
6334 ;; Disable interrupts.
6335 (define_insn "mips_di"
6336 [(unspec_volatile [(const_int 0)] UNSPEC_DI)]
6339 [(set_attr "type" "trap")
6340 (set_attr "mode" "none")])
6342 ;; Execution hazard barrier.
6343 (define_insn "mips_ehb"
6344 [(unspec_volatile [(const_int 0)] UNSPEC_EHB)]
6347 [(set_attr "type" "trap")
6348 (set_attr "mode" "none")])
6350 ;; Read GPR from previous shadow register set.
6351 (define_insn "mips_rdpgpr"
6352 [(set (match_operand:SI 0 "register_operand" "=d")
6353 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "d")]
6357 [(set_attr "type" "move")
6358 (set_attr "mode" "SI")])
6360 ;; Move involving COP0 registers.
6361 (define_insn "cop0_move"
6362 [(set (match_operand:SI 0 "register_operand" "=B,d")
6363 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "d,B")]
6366 { return mips_output_move (operands[0], operands[1]); }
6367 [(set_attr "type" "mtc,mfc")
6368 (set_attr "mode" "SI")])
6370 ;; This is used in compiling the unwind routines.
6371 (define_expand "eh_return"
6372 [(use (match_operand 0 "general_operand"))]
6375 if (GET_MODE (operands[0]) != word_mode)
6376 operands[0] = convert_to_mode (word_mode, operands[0], 0);
6378 emit_insn (gen_eh_set_lr_di (operands[0]));
6380 emit_insn (gen_eh_set_lr_si (operands[0]));
6384 ;; Clobber the return address on the stack. We can't expand this
6385 ;; until we know where it will be put in the stack frame.
6387 (define_insn "eh_set_lr_si"
6388 [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
6389 (clobber (match_scratch:SI 1 "=&d"))]
6393 (define_insn "eh_set_lr_di"
6394 [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
6395 (clobber (match_scratch:DI 1 "=&d"))]
6400 [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
6401 (clobber (match_scratch 1))]
6405 mips_set_return_address (operands[0], operands[1]);
6409 (define_expand "exception_receiver"
6413 /* See the comment above load_call<mode> for details. */
6414 emit_insn (gen_set_got_version ());
6416 /* If we have a call-clobbered $gp, restore it from its save slot. */
6417 if (HAVE_restore_gp_si)
6418 emit_insn (gen_restore_gp_si ());
6419 else if (HAVE_restore_gp_di)
6420 emit_insn (gen_restore_gp_di ());
6424 (define_expand "nonlocal_goto_receiver"
6428 /* See the comment above load_call<mode> for details. */
6429 emit_insn (gen_set_got_version ());
6433 ;; Restore $gp from its .cprestore stack slot. The instruction remains
6434 ;; volatile until all uses of $28 are exposed.
6435 (define_insn_and_split "restore_gp_<mode>"
6437 (unspec_volatile:P [(const_int 0)] UNSPEC_RESTORE_GP))
6438 (clobber (match_scratch:P 0 "=&d"))]
6439 "TARGET_CALL_CLOBBERED_GP"
6441 "&& epilogue_completed"
6444 mips_restore_gp_from_cprestore_slot (operands[0]);
6447 [(set_attr "type" "ghost")])
6449 ;; Move between $gp and its register save slot.
6450 (define_insn_and_split "move_gp<mode>"
6451 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,m")
6452 (unspec:GPR [(match_operand:GPR 1 "move_operand" "m,d")]
6455 { return mips_must_initialize_gp_p () ? "#" : ""; }
6456 "mips_must_initialize_gp_p ()"
6459 mips_emit_move (operands[0], operands[1]);
6462 [(set_attr "type" "ghost")])
6465 ;; ....................
6469 ;; ....................
6471 ;; Instructions to load a call address from the GOT. The address might
6472 ;; point to a function or to a lazy binding stub. In the latter case,
6473 ;; the stub will use the dynamic linker to resolve the function, which
6474 ;; in turn will change the GOT entry to point to the function's real
6477 ;; This means that every call, even pure and constant ones, can
6478 ;; potentially modify the GOT entry. And once a stub has been called,
6479 ;; we must not call it again.
6481 ;; We represent this restriction using an imaginary, fixed, call-saved
6482 ;; register called GOT_VERSION_REGNUM. The idea is to make the register
6483 ;; live throughout the function and to change its value after every
6484 ;; potential call site. This stops any rtx value that uses the register
6485 ;; from being computed before an earlier call. To do this, we:
6487 ;; - Ensure that the register is live on entry to the function,
6488 ;; so that it is never thought to be used uninitalized.
6490 ;; - Ensure that the register is live on exit from the function,
6491 ;; so that it is live throughout.
6493 ;; - Make each call (lazily-bound or not) use the current value
6494 ;; of GOT_VERSION_REGNUM, so that updates of the register are
6495 ;; not moved across call boundaries.
6497 ;; - Add "ghost" definitions of the register to the beginning of
6498 ;; blocks reached by EH and ABNORMAL_CALL edges, because those
6499 ;; edges may involve calls that normal paths don't. (E.g. the
6500 ;; unwinding code that handles a non-call exception may change
6501 ;; lazily-bound GOT entries.) We do this by making the
6502 ;; exception_receiver and nonlocal_goto_receiver expanders emit
6503 ;; a set_got_version instruction.
6505 ;; - After each call (lazily-bound or not), use a "ghost"
6506 ;; update_got_version instruction to change the register's value.
6507 ;; This instruction mimics the _possible_ effect of the dynamic
6508 ;; resolver during the call and it remains live even if the call
6509 ;; itself becomes dead.
6511 ;; - Leave GOT_VERSION_REGNUM out of all register classes.
6512 ;; The register is therefore not a valid register_operand
6513 ;; and cannot be moved to or from other registers.
6515 (define_insn "load_call<mode>"
6516 [(set (match_operand:P 0 "register_operand" "=d")
6517 (unspec:P [(match_operand:P 1 "register_operand" "d")
6518 (match_operand:P 2 "immediate_operand" "")
6519 (reg:SI GOT_VERSION_REGNUM)] UNSPEC_LOAD_CALL))]
6521 "<load>\t%0,%R2(%1)"
6522 [(set_attr "got" "load")
6523 (set_attr "mode" "<MODE>")])
6525 (define_insn "set_got_version"
6526 [(set (reg:SI GOT_VERSION_REGNUM)
6527 (unspec_volatile:SI [(const_int 0)] UNSPEC_SET_GOT_VERSION))]
6530 [(set_attr "type" "ghost")])
6532 (define_insn "update_got_version"
6533 [(set (reg:SI GOT_VERSION_REGNUM)
6534 (unspec:SI [(reg:SI GOT_VERSION_REGNUM)] UNSPEC_UPDATE_GOT_VERSION))]
6537 [(set_attr "type" "ghost")])
6539 ;; Sibling calls. All these patterns use jump instructions.
6541 ;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
6542 ;; addresses if a direct jump is acceptable. Since the 'S' constraint
6543 ;; is defined in terms of call_insn_operand, the same is true of the
6546 ;; When we use an indirect jump, we need a register that will be
6547 ;; preserved by the epilogue. Since TARGET_USE_PIC_FN_ADDR_REG forces
6548 ;; us to use $25 for this purpose -- and $25 is never clobbered by the
6549 ;; epilogue -- we might as well use it for !TARGET_USE_PIC_FN_ADDR_REG
6552 (define_expand "sibcall"
6553 [(parallel [(call (match_operand 0 "")
6554 (match_operand 1 ""))
6555 (use (match_operand 2 "")) ;; next_arg_reg
6556 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
6559 mips_expand_call (MIPS_CALL_SIBCALL, NULL_RTX, XEXP (operands[0], 0),
6560 operands[1], operands[2], false);
6564 (define_insn "sibcall_internal"
6565 [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
6566 (match_operand 1 "" ""))]
6567 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6569 if (TARGET_MICROMIPS)
6570 return MICROMIPS_J ("j", operands, 0);
6572 return MIPS_CALL ("j", operands, 0, 1);
6574 [(set_attr "jal" "indirect,direct")
6575 (set_attr "jal_macro" "no")])
6577 (define_expand "sibcall_value"
6578 [(parallel [(set (match_operand 0 "")
6579 (call (match_operand 1 "")
6580 (match_operand 2 "")))
6581 (use (match_operand 3 ""))])] ;; next_arg_reg
6584 mips_expand_call (MIPS_CALL_SIBCALL, operands[0], XEXP (operands[1], 0),
6585 operands[2], operands[3], false);
6589 (define_insn "sibcall_value_internal"
6590 [(set (match_operand 0 "register_operand" "")
6591 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
6592 (match_operand 2 "" "")))]
6593 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6595 if (TARGET_MICROMIPS)
6596 return MICROMIPS_J ("j", operands, 1);
6598 return MIPS_CALL ("j", operands, 1, 2);
6600 [(set_attr "jal" "indirect,direct")
6601 (set_attr "jal_macro" "no")])
6603 (define_insn "sibcall_value_multiple_internal"
6604 [(set (match_operand 0 "register_operand" "")
6605 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
6606 (match_operand 2 "" "")))
6607 (set (match_operand 3 "register_operand" "")
6608 (call (mem:SI (match_dup 1))
6610 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6612 if (TARGET_MICROMIPS)
6613 return MICROMIPS_J ("j", operands, 1);
6615 return MIPS_CALL ("j", operands, 1, 2);
6617 [(set_attr "jal" "indirect,direct")
6618 (set_attr "jal_macro" "no")])
6620 (define_expand "call"
6621 [(parallel [(call (match_operand 0 "")
6622 (match_operand 1 ""))
6623 (use (match_operand 2 "")) ;; next_arg_reg
6624 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
6627 mips_expand_call (MIPS_CALL_NORMAL, NULL_RTX, XEXP (operands[0], 0),
6628 operands[1], operands[2], false);
6632 ;; This instruction directly corresponds to an assembly-language "jal".
6633 ;; There are four cases:
6636 ;; Both symbolic and register destinations are OK. The pattern
6637 ;; always expands to a single mips instruction.
6639 ;; - -mabicalls/-mno-explicit-relocs:
6640 ;; Again, both symbolic and register destinations are OK.
6641 ;; The call is treated as a multi-instruction black box.
6643 ;; - -mabicalls/-mexplicit-relocs with n32 or n64:
6644 ;; Only "jal $25" is allowed. This expands to a single "jalr $25"
6647 ;; - -mabicalls/-mexplicit-relocs with o32 or o64:
6648 ;; Only "jal $25" is allowed. The call is actually two instructions:
6649 ;; "jalr $25" followed by an insn to reload $gp.
6651 ;; In the last case, we can generate the individual instructions with
6652 ;; a define_split. There are several things to be wary of:
6654 ;; - We can't expose the load of $gp before reload. If we did,
6655 ;; it might get removed as dead, but reload can introduce new
6656 ;; uses of $gp by rematerializing constants.
6658 ;; - We shouldn't restore $gp after calls that never return.
6659 ;; It isn't valid to insert instructions between a noreturn
6660 ;; call and the following barrier.
6662 ;; - The splitter deliberately changes the liveness of $gp. The unsplit
6663 ;; instruction preserves $gp and so have no effect on its liveness.
6664 ;; But once we generate the separate insns, it becomes obvious that
6665 ;; $gp is not live on entry to the call.
6667 (define_insn_and_split "call_internal"
6668 [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
6669 (match_operand 1 "" ""))
6670 (clobber (reg:SI RETURN_ADDR_REGNUM))]
6672 { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 0, 1); }
6673 "reload_completed && TARGET_SPLIT_CALLS"
6676 mips_split_call (curr_insn, gen_call_split (operands[0], operands[1]));
6679 [(set_attr "jal" "indirect,direct")])
6681 (define_insn "call_split"
6682 [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
6683 (match_operand 1 "" ""))
6684 (clobber (reg:SI RETURN_ADDR_REGNUM))
6685 (clobber (reg:SI 28))]
6686 "TARGET_SPLIT_CALLS"
6687 { return MIPS_CALL ("jal", operands, 0, 1); }
6688 [(set_attr "jal" "indirect,direct")
6689 (set_attr "jal_macro" "no")])
6691 ;; A pattern for calls that must be made directly. It is used for
6692 ;; MIPS16 calls that the linker may need to redirect to a hard-float
6693 ;; stub; the linker relies on the call relocation type to detect when
6694 ;; such redirection is needed.
6695 (define_insn_and_split "call_internal_direct"
6696 [(call (mem:SI (match_operand 0 "const_call_insn_operand"))
6699 (clobber (reg:SI RETURN_ADDR_REGNUM))]
6701 { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 0, -1); }
6702 "reload_completed && TARGET_SPLIT_CALLS"
6705 mips_split_call (curr_insn,
6706 gen_call_direct_split (operands[0], operands[1]));
6709 [(set_attr "jal" "direct")])
6711 (define_insn "call_direct_split"
6712 [(call (mem:SI (match_operand 0 "const_call_insn_operand"))
6715 (clobber (reg:SI RETURN_ADDR_REGNUM))
6716 (clobber (reg:SI 28))]
6717 "TARGET_SPLIT_CALLS"
6718 { return MIPS_CALL ("jal", operands, 0, -1); }
6719 [(set_attr "jal" "direct")
6720 (set_attr "jal_macro" "no")])
6722 (define_expand "call_value"
6723 [(parallel [(set (match_operand 0 "")
6724 (call (match_operand 1 "")
6725 (match_operand 2 "")))
6726 (use (match_operand 3 ""))])] ;; next_arg_reg
6729 mips_expand_call (MIPS_CALL_NORMAL, operands[0], XEXP (operands[1], 0),
6730 operands[2], operands[3], false);
6734 ;; See comment for call_internal.
6735 (define_insn_and_split "call_value_internal"
6736 [(set (match_operand 0 "register_operand" "")
6737 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
6738 (match_operand 2 "" "")))
6739 (clobber (reg:SI RETURN_ADDR_REGNUM))]
6741 { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1, 2); }
6742 "reload_completed && TARGET_SPLIT_CALLS"
6745 mips_split_call (curr_insn,
6746 gen_call_value_split (operands[0], operands[1],
6750 [(set_attr "jal" "indirect,direct")])
6752 (define_insn "call_value_split"
6753 [(set (match_operand 0 "register_operand" "")
6754 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
6755 (match_operand 2 "" "")))
6756 (clobber (reg:SI RETURN_ADDR_REGNUM))
6757 (clobber (reg:SI 28))]
6758 "TARGET_SPLIT_CALLS"
6759 { return MIPS_CALL ("jal", operands, 1, 2); }
6760 [(set_attr "jal" "indirect,direct")
6761 (set_attr "jal_macro" "no")])
6763 ;; See call_internal_direct.
6764 (define_insn_and_split "call_value_internal_direct"
6765 [(set (match_operand 0 "register_operand")
6766 (call (mem:SI (match_operand 1 "const_call_insn_operand"))
6769 (clobber (reg:SI RETURN_ADDR_REGNUM))]
6771 { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1, -1); }
6772 "reload_completed && TARGET_SPLIT_CALLS"
6775 mips_split_call (curr_insn,
6776 gen_call_value_direct_split (operands[0], operands[1],
6780 [(set_attr "jal" "direct")])
6782 (define_insn "call_value_direct_split"
6783 [(set (match_operand 0 "register_operand")
6784 (call (mem:SI (match_operand 1 "const_call_insn_operand"))
6787 (clobber (reg:SI RETURN_ADDR_REGNUM))
6788 (clobber (reg:SI 28))]
6789 "TARGET_SPLIT_CALLS"
6790 { return MIPS_CALL ("jal", operands, 1, -1); }
6791 [(set_attr "jal" "direct")
6792 (set_attr "jal_macro" "no")])
6794 ;; See comment for call_internal.
6795 (define_insn_and_split "call_value_multiple_internal"
6796 [(set (match_operand 0 "register_operand" "")
6797 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
6798 (match_operand 2 "" "")))
6799 (set (match_operand 3 "register_operand" "")
6800 (call (mem:SI (match_dup 1))
6802 (clobber (reg:SI RETURN_ADDR_REGNUM))]
6804 { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1, 2); }
6805 "reload_completed && TARGET_SPLIT_CALLS"
6808 mips_split_call (curr_insn,
6809 gen_call_value_multiple_split (operands[0], operands[1],
6810 operands[2], operands[3]));
6813 [(set_attr "jal" "indirect,direct")])
6815 (define_insn "call_value_multiple_split"
6816 [(set (match_operand 0 "register_operand" "")
6817 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
6818 (match_operand 2 "" "")))
6819 (set (match_operand 3 "register_operand" "")
6820 (call (mem:SI (match_dup 1))
6822 (clobber (reg:SI RETURN_ADDR_REGNUM))
6823 (clobber (reg:SI 28))]
6824 "TARGET_SPLIT_CALLS"
6825 { return MIPS_CALL ("jal", operands, 1, 2); }
6826 [(set_attr "jal" "indirect,direct")
6827 (set_attr "jal_macro" "no")])
6829 ;; Call subroutine returning any type.
6831 (define_expand "untyped_call"
6832 [(parallel [(call (match_operand 0 "")
6834 (match_operand 1 "")
6835 (match_operand 2 "")])]
6840 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
6842 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6844 rtx set = XVECEXP (operands[2], 0, i);
6845 mips_emit_move (SET_DEST (set), SET_SRC (set));
6848 emit_insn (gen_blockage ());
6853 ;; ....................
6857 ;; ....................
6861 (define_insn "prefetch"
6862 [(prefetch (match_operand:QI 0 "address_operand" "ZD")
6863 (match_operand 1 "const_int_operand" "n")
6864 (match_operand 2 "const_int_operand" "n"))]
6865 "ISA_HAS_PREFETCH && TARGET_EXPLICIT_RELOCS"
6867 if (TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A)
6869 /* Loongson 2[ef] and Loongson 3a use load to $0 for prefetching. */
6871 return "ld\t$0,%a0";
6873 return "lw\t$0,%a0";
6875 operands[1] = mips_prefetch_cookie (operands[1], operands[2]);
6876 return "pref\t%1,%a0";
6878 [(set_attr "type" "prefetch")])
6880 (define_insn "*prefetch_indexed_<mode>"
6881 [(prefetch (plus:P (match_operand:P 0 "register_operand" "d")
6882 (match_operand:P 1 "register_operand" "d"))
6883 (match_operand 2 "const_int_operand" "n")
6884 (match_operand 3 "const_int_operand" "n"))]
6885 "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6887 operands[2] = mips_prefetch_cookie (operands[2], operands[3]);
6888 return "prefx\t%2,%1(%0)";
6890 [(set_attr "type" "prefetchx")])
6896 [(set_attr "type" "nop")
6897 (set_attr "mode" "none")])
6899 ;; Like nop, but commented out when outside a .set noreorder block.
6900 (define_insn "hazard_nop"
6904 if (mips_noreorder.nesting_level > 0)
6909 [(set_attr "type" "nop")])
6911 ;; MIPS4 Conditional move instructions.
6913 (define_insn "*mov<GPR:mode>_on_<MOVECC:mode>"
6914 [(set (match_operand:GPR 0 "register_operand" "=d,d")
6916 (match_operator 4 "equality_operator"
6917 [(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>")
6919 (match_operand:GPR 2 "reg_or_0_operand" "dJ,0")
6920 (match_operand:GPR 3 "reg_or_0_operand" "0,dJ")))]
6925 [(set_attr "type" "condmove")
6926 (set_attr "mode" "<GPR:MODE>")])
6928 (define_insn "*mov<GPR:mode>_on_<GPR2:mode>_ne"
6929 [(set (match_operand:GPR 0 "register_operand" "=d,d")
6931 (match_operand:GPR2 1 "register_operand" "<GPR2:reg>,<GPR2:reg>")
6932 (match_operand:GPR 2 "reg_or_0_operand" "dJ,0")
6933 (match_operand:GPR 3 "reg_or_0_operand" "0,dJ")))]
6938 [(set_attr "type" "condmove")
6939 (set_attr "mode" "<GPR:MODE>")])
6941 (define_insn "*mov<SCALARF:mode>_on_<MOVECC:mode>"
6942 [(set (match_operand:SCALARF 0 "register_operand" "=f,f")
6943 (if_then_else:SCALARF
6944 (match_operator 4 "equality_operator"
6945 [(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>")
6947 (match_operand:SCALARF 2 "register_operand" "f,0")
6948 (match_operand:SCALARF 3 "register_operand" "0,f")))]
6949 "ISA_HAS_FP_CONDMOVE"
6951 mov%T4.<fmt>\t%0,%2,%1
6952 mov%t4.<fmt>\t%0,%3,%1"
6953 [(set_attr "type" "condmove")
6954 (set_attr "mode" "<SCALARF:MODE>")])
6956 ;; These are the main define_expand's used to make conditional moves.
6958 (define_expand "mov<mode>cc"
6959 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
6960 (set (match_operand:GPR 0 "register_operand")
6961 (if_then_else:GPR (match_dup 5)
6962 (match_operand:GPR 2 "reg_or_0_operand")
6963 (match_operand:GPR 3 "reg_or_0_operand")))]
6966 mips_expand_conditional_move (operands);
6970 (define_expand "mov<mode>cc"
6971 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
6972 (set (match_operand:SCALARF 0 "register_operand")
6973 (if_then_else:SCALARF (match_dup 5)
6974 (match_operand:SCALARF 2 "register_operand")
6975 (match_operand:SCALARF 3 "register_operand")))]
6976 "ISA_HAS_FP_CONDMOVE"
6978 mips_expand_conditional_move (operands);
6983 ;; ....................
6985 ;; mips16 inline constant tables
6987 ;; ....................
6990 (define_insn "consttable_tls_reloc"
6991 [(unspec_volatile [(match_operand 0 "tls_reloc_operand" "")
6992 (match_operand 1 "const_int_operand" "")]
6993 UNSPEC_CONSTTABLE_INT)]
6994 "TARGET_MIPS16_PCREL_LOADS"
6995 { return mips_output_tls_reloc_directive (&operands[0]); }
6996 [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
6998 (define_insn "consttable_int"
6999 [(unspec_volatile [(match_operand 0 "consttable_operand" "")
7000 (match_operand 1 "const_int_operand" "")]
7001 UNSPEC_CONSTTABLE_INT)]
7004 assemble_integer (mips_strip_unspec_address (operands[0]),
7005 INTVAL (operands[1]),
7006 BITS_PER_UNIT * INTVAL (operands[1]), 1);
7009 [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
7011 (define_insn "consttable_float"
7012 [(unspec_volatile [(match_operand 0 "consttable_operand" "")]
7013 UNSPEC_CONSTTABLE_FLOAT)]
7018 gcc_assert (GET_CODE (operands[0]) == CONST_DOUBLE);
7019 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7020 assemble_real (d, GET_MODE (operands[0]),
7021 GET_MODE_BITSIZE (GET_MODE (operands[0])));
7024 [(set (attr "length")
7025 (symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))])
7027 (define_insn "align"
7028 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)]
7031 [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))])
7034 [(match_operand 0 "small_data_pattern")]
7037 { operands[0] = mips_rewrite_small_data (operands[0]); })
7040 ;; ....................
7042 ;; MIPS16e Save/Restore
7044 ;; ....................
7047 (define_insn "*mips16e_save_restore"
7048 [(match_parallel 0 ""
7049 [(set (match_operand:SI 1 "register_operand")
7050 (plus:SI (match_dup 1)
7051 (match_operand:SI 2 "const_int_operand")))])]
7052 "operands[1] == stack_pointer_rtx
7053 && mips16e_save_restore_pattern_p (operands[0], INTVAL (operands[2]), NULL)"
7054 { return mips16e_output_save_restore (operands[0], INTVAL (operands[2])); }
7055 [(set_attr "type" "arith")
7056 (set_attr "extended_mips16" "yes")])
7058 ;; Thread-Local Storage
7060 ;; The TLS base pointer is accessed via "rdhwr $3, $29". No current
7061 ;; MIPS architecture defines this register, and no current
7062 ;; implementation provides it; instead, any OS which supports TLS is
7063 ;; expected to trap and emulate this instruction. rdhwr is part of the
7064 ;; MIPS 32r2 specification, but we use it on any architecture because
7065 ;; we expect it to be emulated. Use .set to force the assembler to
7068 ;; We do not use a constraint to force the destination to be $3
7069 ;; because $3 can appear explicitly as a function return value.
7070 ;; If we leave the use of $3 implicit in the constraints until
7071 ;; reload, we may end up making a $3 return value live across
7072 ;; the instruction, leading to a spill failure when reloading it.
7073 (define_insn_and_split "tls_get_tp_<mode>"
7074 [(set (match_operand:P 0 "register_operand" "=d")
7075 (unspec:P [(const_int 0)] UNSPEC_TLS_GET_TP))
7076 (clobber (reg:P TLS_GET_TP_REGNUM))]
7077 "HAVE_AS_TLS && !TARGET_MIPS16"
7079 "&& reload_completed"
7080 [(set (reg:P TLS_GET_TP_REGNUM)
7081 (unspec:P [(const_int 0)] UNSPEC_TLS_GET_TP))
7082 (set (match_dup 0) (reg:P TLS_GET_TP_REGNUM))]
7084 [(set_attr "type" "unknown")
7085 (set_attr "mode" "<MODE>")
7086 (set_attr "insn_count" "2")])
7088 (define_insn "*tls_get_tp_<mode>_split"
7089 [(set (reg:P TLS_GET_TP_REGNUM)
7090 (unspec:P [(const_int 0)] UNSPEC_TLS_GET_TP))]
7091 "HAVE_AS_TLS && !TARGET_MIPS16"
7092 ".set\tpush\;.set\tmips32r2\t\;rdhwr\t$3,$29\;.set\tpop"
7093 [(set_attr "type" "unknown")
7094 ; Since rdhwr always generates a trap for now, putting it in a delay
7095 ; slot would make the kernel's emulation of it much slower.
7096 (set_attr "can_delay" "no")
7097 (set_attr "mode" "<MODE>")])
7099 ;; In MIPS16 mode, the TLS base pointer is accessed by a
7100 ;; libgcc helper function __mips16_rdhwr(), as 'rdhwr' is not
7101 ;; accessible in MIPS16.
7103 ;; This is not represented as a call insn, to avoid the
7104 ;; unnecesarry clobbering of caller-save registers by a
7105 ;; function consisting only of: "rdhwr $3,$29; j $31; nop;"
7107 ;; A $25 clobber is added to cater for a $25 load stub added by the
7108 ;; linker to __mips16_rdhwr when the call is made from non-PIC code.
7110 (define_insn_and_split "tls_get_tp_mips16_<mode>"
7111 [(set (match_operand:P 0 "register_operand" "=d")
7112 (unspec:P [(match_operand:P 1 "call_insn_operand" "dS")]
7114 (clobber (reg:P TLS_GET_TP_REGNUM))
7115 (clobber (reg:P PIC_FUNCTION_ADDR_REGNUM))
7116 (clobber (reg:P RETURN_ADDR_REGNUM))]
7117 "HAVE_AS_TLS && TARGET_MIPS16"
7119 "&& reload_completed"
7120 [(parallel [(set (reg:P TLS_GET_TP_REGNUM)
7121 (unspec:P [(match_dup 1)] UNSPEC_TLS_GET_TP))
7122 (clobber (reg:P PIC_FUNCTION_ADDR_REGNUM))
7123 (clobber (reg:P RETURN_ADDR_REGNUM))])
7124 (set (match_dup 0) (reg:P TLS_GET_TP_REGNUM))]
7126 [(set_attr "type" "multi")
7127 (set_attr "insn_count" "4")
7128 (set_attr "mode" "<MODE>")])
7130 (define_insn "*tls_get_tp_mips16_call_<mode>"
7131 [(set (reg:P TLS_GET_TP_REGNUM)
7132 (unspec:P [(match_operand:P 0 "call_insn_operand" "dS")]
7134 (clobber (reg:P PIC_FUNCTION_ADDR_REGNUM))
7135 (clobber (reg:P RETURN_ADDR_REGNUM))]
7136 "HAVE_AS_TLS && TARGET_MIPS16"
7137 { return MIPS_CALL ("jal", operands, 0, -1); }
7138 [(set_attr "type" "call")
7139 (set_attr "insn_count" "3")
7140 (set_attr "mode" "<MODE>")])
7142 ;; Named pattern for expanding thread pointer reference.
7143 (define_expand "get_thread_pointer<mode>"
7144 [(match_operand:P 0 "register_operand" "=d")]
7147 mips_expand_thread_pointer (operands[0]);
7151 ;; __builtin_mips_get_fcsr: move the FCSR into operand 0.
7152 (define_expand "mips_get_fcsr"
7153 [(set (match_operand:SI 0 "register_operand")
7154 (unspec_volatile [(const_int 0)] UNSPEC_GET_FCSR))]
7155 "TARGET_HARD_FLOAT_ABI"
7159 mips16_expand_get_fcsr (operands[0]);
7164 (define_insn "*mips_get_fcsr"
7165 [(set (match_operand:SI 0 "register_operand" "=d")
7166 (unspec_volatile [(const_int 0)] UNSPEC_GET_FCSR))]
7170 ;; See tls_get_tp_mips16_<mode> for why this form is used.
7171 (define_insn "mips_get_fcsr_mips16_<mode>"
7172 [(set (reg:SI GET_FCSR_REGNUM)
7173 (unspec:SI [(match_operand:P 0 "call_insn_operand" "dS")]
7175 (clobber (reg:P PIC_FUNCTION_ADDR_REGNUM))
7176 (clobber (reg:P RETURN_ADDR_REGNUM))]
7177 "TARGET_HARD_FLOAT_ABI && TARGET_MIPS16"
7178 { return MIPS_CALL ("jal", operands, 0, -1); }
7179 [(set_attr "type" "call")
7180 (set_attr "insn_count" "3")])
7182 ;; __builtin_mips_set_fcsr: move operand 0 into the FCSR.
7183 (define_expand "mips_set_fcsr"
7184 [(unspec_volatile [(match_operand:SI 0 "register_operand")]
7186 "TARGET_HARD_FLOAT_ABI"
7190 mips16_expand_set_fcsr (operands[0]);
7195 (define_insn "*mips_set_fcsr"
7196 [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")]
7201 ;; See tls_get_tp_mips16_<mode> for why this form is used.
7202 (define_insn "mips_set_fcsr_mips16_<mode>"
7203 [(unspec_volatile:SI [(match_operand:P 0 "call_insn_operand" "dS")
7204 (reg:SI SET_FCSR_REGNUM)] UNSPEC_SET_FCSR)
7205 (clobber (reg:P PIC_FUNCTION_ADDR_REGNUM))
7206 (clobber (reg:P RETURN_ADDR_REGNUM))]
7207 "TARGET_HARD_FLOAT_ABI && TARGET_MIPS16"
7208 { return MIPS_CALL ("jal", operands, 0, -1); }
7209 [(set_attr "type" "call")
7210 (set_attr "insn_count" "3")])
7212 ;; Synchronization instructions.
7216 ; The MIPS Paired-Single Floating Point and MIPS-3D Instructions.
7218 (include "mips-ps-3d.md")
7220 ; The MIPS DSP Instructions.
7222 (include "mips-dsp.md")
7224 ; The MIPS DSP REV 2 Instructions.
7226 (include "mips-dspr2.md")
7228 ; MIPS fixed-point instructions.
7229 (include "mips-fixed.md")
7231 ; microMIPS patterns.
7232 (include "micromips.md")
7234 ; ST-Microelectronics Loongson-2E/2F-specific patterns.
7235 (include "loongson.md")
7237 (define_c_enum "unspec" [
7238 UNSPEC_ADDRESS_FIRST