2014-12-19 Andrew MacLeod <amacleod@redhat.com>
[official-gcc.git] / gcc / config / mips / mips.md
blob65c0a3f18fed68fd8b9646137e380f09100797ec
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)
13 ;; any later version.
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" [
25   r3000
26   4kc
27   4kp
28   5kc
29   5kf
30   20kc
31   24kc
32   24kf2_1
33   24kf1_1
34   74kc
35   74kf2_1
36   74kf1_1
37   74kf3_2
38   loongson_2e
39   loongson_2f
40   loongson_3a
41   m4k
42   octeon
43   octeon2
44   octeon3
45   r3900
46   r6000
47   r4000
48   r4100
49   r4111
50   r4120
51   r4130
52   r4300
53   r4600
54   r4650
55   r4700
56   r5000
57   r5400
58   r5500
59   r5900
60   r7000
61   r8000
62   r9000
63   r10000
64   sb1
65   sb1a
66   sr71000
67   xlr
68   xlp
69   p5600
72 (define_c_enum "unspec" [
73   ;; Unaligned accesses.
74   UNSPEC_LOAD_LEFT
75   UNSPEC_LOAD_RIGHT
76   UNSPEC_STORE_LEFT
77   UNSPEC_STORE_RIGHT
79   ;; Integer operations that are too cumbersome to describe directly.
80   UNSPEC_WSBH
81   UNSPEC_DSBH
82   UNSPEC_DSHD
84   ;; Floating-point moves.
85   UNSPEC_LOAD_LOW
86   UNSPEC_LOAD_HIGH
87   UNSPEC_STORE_WORD
88   UNSPEC_MFHC1
89   UNSPEC_MTHC1
91   ;; Floating-point environment.
92   UNSPEC_GET_FCSR
93   UNSPEC_SET_FCSR
95   ;; HI/LO moves.
96   UNSPEC_MFHI
97   UNSPEC_MTHI
98   UNSPEC_SET_HILO
100   ;; GP manipulation.
101   UNSPEC_LOADGP
102   UNSPEC_COPYGP
103   UNSPEC_MOVE_GP
104   UNSPEC_POTENTIAL_CPRESTORE
105   UNSPEC_CPRESTORE
106   UNSPEC_RESTORE_GP
107   UNSPEC_EH_RETURN
108   UNSPEC_GP
109   UNSPEC_SET_GOT_VERSION
110   UNSPEC_UPDATE_GOT_VERSION
112   ;; Symbolic accesses.
113   UNSPEC_LOAD_CALL
114   UNSPEC_LOAD_GOT
115   UNSPEC_TLS_LDM
116   UNSPEC_TLS_GET_TP
117   UNSPEC_UNSHIFTED_HIGH
119   ;; MIPS16 constant pools.
120   UNSPEC_ALIGN
121   UNSPEC_CONSTTABLE_INT
122   UNSPEC_CONSTTABLE_FLOAT
124   ;; Blockage and synchronisation.
125   UNSPEC_BLOCKAGE
126   UNSPEC_CLEAR_HAZARD
127   UNSPEC_RDHWR
128   UNSPEC_SYNCI
129   UNSPEC_SYNC
131   ;; Cache manipulation.
132   UNSPEC_MIPS_CACHE
133   UNSPEC_R10K_CACHE_BARRIER
135   ;; Interrupt handling.
136   UNSPEC_ERET
137   UNSPEC_DERET
138   UNSPEC_DI
139   UNSPEC_EHB
140   UNSPEC_RDPGPR
141   UNSPEC_COP0
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.
145   UNSPEC_CALL_ATTR
147   ;; MIPS16 casesi jump table dispatch.
148   UNSPEC_CASESI_DISPATCH
150   ;; Stack checking.
151   UNSPEC_PROBE_STACK_RANGE
154 (define_constants
155   [(TLS_GET_TP_REGNUM           3)
156    (GET_FCSR_REGNUM             2)
157    (SET_FCSR_REGNUM             4)
158    (MIPS16_T_REGNUM             24)
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)
166   ]
169 (include "predicates.md")
170 (include "constraints.md")
172 ;; ....................
174 ;;      Attributes
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
192 ;; into a register.
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
213 ;;              from the pool
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,
223    shift_shift"
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")))
237          (const_string "yes")
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
247 ;;    1: OLDVAL = *MEM
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]
256 ;;       CMP  = 1
257 ;;       if (ACQUIRE_BARRIER == YES) sync
258 ;;    2:
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:
265 ;;    - OLDVAL: $AT
266 ;;    - CMP: NONE
267 ;;    - NEWVAL: $AT
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
357 ;; nop          no operation
358 ;; ghost        an instruction that produces no real code
359 ;; multimem     microMIPS multiword load and store
360 (define_attr "type"
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"))
429                 (const_string "yes")
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"))
442          (const_string "no")
443          (and (eq_attr "compression" "micromips32,micromips")
444               (match_test "!TARGET_MICROMIPS"))
445          (const_string "no")]
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")
453          (const_int 0)
455          ;; Extended instructions count as 2.
456          (and (eq_attr "extended_mips16" "yes")
457               (match_test "TARGET_MIPS16"))
458          (const_int 2)
460          ;; A GOT load followed by an add of $gp.  This is not used for MIPS16.
461          (eq_attr "got" "xgot_high")
462          (const_int 2)
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")
468                        (const_int 4)
469                        (const_int 2))
471          ;; Check for doubleword moves that are decomposed into two
472          ;; instructions.  The individual instructions are unextended
473          ;; MIPS16 ones.
474          (and (eq_attr "move_type" "mtc,mfc,mtlo,mflo,move")
475               (eq_attr "dword_mode" "yes"))
476          (const_int 2)
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:
491          ;;
492          ;;     lui $25,%call_hi(FOO)
493          ;;     addu $25,$25,$28
494          ;;     lw $25,%call_lo(FOO)($25)
495          ;;     nop
496          ;;     jalr $25
497          ;;     nop
498          ;;     lw $gp,X($sp)
499          ;;     nop
500          (eq_attr "jal_macro" "yes")
501          (const_int 8)
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"))
508          (const_int 2)
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"))
516          (const_int 2)
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)")]
523         (const_int 1)))
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"))
534           (const_int 2)
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
539           ;; sequences.
540           ;;
541           ;; For PIC, an out-of-range branch like:
542           ;;
543           ;;    bne     r1,r2,target
544           ;;    dslot
545           ;;
546           ;; becomes the equivalent of:
547           ;;
548           ;;    beq     r1,r2,1f
549           ;;    dslot
550           ;;    la      $at,target
551           ;;    jr      $at
552           ;;    nop
553           ;; 1:
554           ;;
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
561           ;; present.
562           ;;
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:
569           ;;
570           ;;    [-(0x20000 - sizeof (branch)), 0x1fffc - sizeof (slot)]
571           ;; == [-0x1fffc, 0x1fff8]
572           ;;
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)))
579                    (const_int 4)
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))))
585                    (const_int 4)
587                  ;; The non-PIC case: branch, first delay slot, and J.
588                  (match_test "TARGET_ABSOLUTE_JUMPS")
589                    (const_int 12)]
591                  ;; Use MAX_PIC_BRANCH_LENGTH as a (gross) overestimate.
592                  ;; mips_adjust_insn_length substitutes the correct length.
593                  ;;
594                  ;; Note that we can't simply use (symbol_ref ...) here
595                  ;; because genattrtab needs to know the maximum length
596                  ;; of an insn.
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
601           ;; to a range of:
602           ;;
603           ;;    [-(0x100 - sizeof (branch)), 0xfe]
604           ;; == [-0xfe, 0xfe]
605           ;;
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:
609           ;;
610           ;;    [-(0x10000 - sizeof (branch)), 0xfffe]
611           ;; == [-0xfffc, 0xfffe]
612           ;;
613           ;; from the reference address.
614           ;;
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:
617           ;;
618           ;; (1) Absolute addressing with a readable text segment
619           ;;     (32-bit addresses):
620           ;;
621           ;;     b... foo               2 bytes
622           ;;     move $1,$2             2 bytes
623           ;;     lw $2,label            2 bytes
624           ;;     jr $2                  2 bytes
625           ;;     move $2,$1             2 bytes
626           ;;     .align 2               0 or 2 bytes
627           ;; label:
628           ;;     .word target           4 bytes
629           ;; foo:
630           ;;                            (16 bytes in the worst case)
631           ;;
632           ;; (2) Absolute addressing with a readable text segment
633           ;;     (64-bit addresses):
634           ;;
635           ;;     b... foo               2 bytes
636           ;;     move $1,$2             2 bytes
637           ;;     ld $2,label            2 bytes
638           ;;     jr $2                  2 bytes
639           ;;     move $2,$1             2 bytes
640           ;;     .align 3               0 to 6 bytes
641           ;; label:
642           ;;     .dword target          8 bytes
643           ;; foo:
644           ;;                            (24 bytes in the worst case)
645           ;;
646           ;; (3) Absolute addressing without a readable text segment
647           ;;     (which requires 32-bit addresses at present):
648           ;;
649           ;;     b... foo               2 bytes
650           ;;     move $1,$2             2 bytes
651           ;;     lui $2,%hi(target)     4 bytes
652           ;;     sll $2,8               2 bytes
653           ;;     sll $2,8               2 bytes
654           ;;     addiu $2,%lo(target)   4 bytes
655           ;;     jr $2                  2 bytes
656           ;;     move $2,$1             2 bytes
657           ;; foo:
658           ;;                            (20 bytes)
659           ;;
660           ;; (4) PIC addressing (which requires 32-bit addresses at present):
661           ;;
662           ;;     b... foo               2 bytes
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
667           ;;     jr $2                  2 bytes
668           ;;     move $2,$1             2 bytes
669           ;; foo:
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)))
675                  (const_int 2)
676                  (and (le (minus (match_dup 0) (pc)) (const_int 65534))
677                       (le (minus (pc) (match_dup 0)) (const_int 65532)))
678                  (const_int 4)
679                  (and (match_test "TARGET_ABICALLS")
680                       (not (match_test "TARGET_ABSOLUTE_ABICALLS")))
681                  (const_int 20)
682                  (match_test "Pmode == SImode")
683                  (const_int 16)
684                  ] (const_int 24))]
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"))
723                 (const_string "yes")
724                 (const_string "no")))
726 ;; Attribute defining whether or not we can use the branch-likely
727 ;; instructions.
728 (define_attr "branch_likely" "no,yes"
729   (if_then_else (match_test "GENERATE_BRANCHLIKELY")
730                 (const_string "yes")
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")
737                 (const_string "yes")
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
750 ;; modes.
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
773   [SI
774    (V2HI "TARGET_DSP")
775    (V4QI "TARGET_DSP")
776    (V2HQ "TARGET_DSP")
777    (V2UHQ "TARGET_DSP")
778    (V2HA "TARGET_DSP")
779    (V2UHA "TARGET_DSP")
780    (V4QQ "TARGET_DSP")
781    (V4UQQ "TARGET_DSP")])
783 ;; 64-bit modes for which we provide move patterns.
784 (define_mode_iterator MOVE64
785   [DI DF
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
859 ;; a given mode.
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
870 ;; fixed-point mode.
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")
882                             (TF "DI")])
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
896 ;; can be used.
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")
943                      (div "") (udiv "u")
944                      (mod "") (umod "u")
945                      (gt "") (gtu "u")
946                      (ge "") (geu "u")
947                      (lt "") (ltu "u")
948                      (le "") (leu "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")
958                          (ashiftrt "ashr")
959                          (lshiftrt "lshr")
960                          (ior "ior")
961                          (xor "xor")
962                          (and "and")
963                          (plus "add")
964                          (minus "sub")
965                          (return "return")
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")
970                         (ashiftrt "sra")
971                         (lshiftrt "srl")
972                         (ior "or")
973                         (xor "xor")
974                         (and "and")
975                         (plus "addu")
976                         (minus "subu")])
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")
981                                   (xor "xori")
982                                   (and "andi")])
984 (define_code_attr shift_compression [(ashift "micromips32")
985                                      (lshiftrt "micromips32")
986                                      (ashiftrt "none")])
988 ;; <fcond> is the c.cond.fmt condition associated with a particular code.
989 (define_code_attr fcond [(unordered "un")
990                          (uneq "ueq")
991                          (unlt "ult")
992                          (unle "ule")
993                          (eq "eq")
994                          (lt "lt")
995                          (le "le")])
997 ;; Similar, but for swapped conditions.
998 (define_code_attr swapped_fcond [(ge "le")
999                                  (gt "lt")
1000                                  (unge "ule")
1001                                  (ungt "ult")])
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")
1020    (nil)
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")
1028    (nil)
1029    (nil)])
1031 (define_delay (eq_attr "type" "jump")
1032   [(eq_attr "can_delay" "yes")
1033    (nil)
1034    (nil)])
1036 (define_delay (and (eq_attr "type" "call")
1037                    (eq_attr "jal_macro" "no"))
1038   [(eq_attr "can_delay" "yes")
1039    (nil)
1040    (nil)])
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")
1061   "nothing")
1063 (include "p5600.md")
1064 (include "4k.md")
1065 (include "5k.md")
1066 (include "20kc.md")
1067 (include "24k.md")
1068 (include "74k.md")
1069 (include "3000.md")
1070 (include "4000.md")
1071 (include "4100.md")
1072 (include "4130.md")
1073 (include "4300.md")
1074 (include "4600.md")
1075 (include "5000.md")
1076 (include "5400.md")
1077 (include "5500.md")
1078 (include "6000.md")
1079 (include "7000.md")
1080 (include "9000.md")
1081 (include "10000.md")
1082 (include "loongson2ef.md")
1083 (include "loongson3a.md")
1084 (include "octeon.md")
1085 (include "sb1.md")
1086 (include "sr71k.md")
1087 (include "xlr.md")
1088 (include "xlp.md")
1089 (include "generic.md")
1092 ;;  ....................
1094 ;;      CONDITIONAL TRAPS
1096 ;;  ....................
1099 (define_insn "trap"
1100   [(trap_if (const_int 1) (const_int 0))]
1101   ""
1103   if (ISA_HAS_COND_TRAP)
1104     return "teq\t$0,$0";
1105   else if (TARGET_MIPS16)
1106     return "break 0";
1107   else
1108     return "break";
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"))]
1117   "ISA_HAS_COND_TRAP"
1119   mips_expand_conditional_trap (operands[0]);
1120   DONE;
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")])
1127             (const_int 0))]
1128   "ISA_HAS_COND_TRAP"
1129   "t%C0\t%z1,%2"
1130   [(set_attr "type" "trap")])
1133 ;;  ....................
1135 ;;      ADDITION
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")))]
1144   ""
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")))]
1153   "")
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")))]
1159   "!TARGET_MIPS16"
1161   if (which_alternative == 0 
1162       || which_alternative == 1)
1163     return "<d>addu\t%0,%1,%2";
1164   else
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")))]
1175   "TARGET_MIPS16"
1176   "@
1177     <d>addiu\t%0,%2
1178     <d>addiu\t%0,%2
1179     <d>addiu\t%0,%1,%2
1180     <d>addiu\t%0,%1,%2
1181     <d>addiu\t%0,%2
1182     <d>addiu\t%0,%2
1183     <d>addiu\t%0,%1,%2
1184     <d>addiu\t%0,%1,%2
1185     <d>addu\t%0,%1,%2"
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.
1196 (define_split
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]);
1210   if (val >= 0)
1211     {
1212       operands[1] = GEN_INT (0x7f);
1213       operands[2] = GEN_INT (val - 0x7f);
1214     }
1215   else
1216     {
1217       operands[1] = GEN_INT (- 0x80);
1218       operands[2] = GEN_INT (val + 0x80);
1219     }
1222 (define_split
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]);
1237   if (val >= 0)
1238     {
1239       operands[2] = GEN_INT (0x7);
1240       operands[3] = GEN_INT (val - 0x7);
1241     }
1242   else
1243     {
1244       operands[2] = GEN_INT (- 0x8);
1245       operands[3] = GEN_INT (val + 0x8);
1246     }
1249 (define_split
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]);
1263   if (val >= 0)
1264     {
1265       operands[1] = GEN_INT (0xf);
1266       operands[2] = GEN_INT (val - 0xf);
1267     }
1268   else
1269     {
1270       operands[1] = GEN_INT (- 0x10);
1271       operands[2] = GEN_INT (val + 0x10);
1272     }
1275 (define_split
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]);
1290   if (val >= 0)
1291     {
1292       operands[2] = GEN_INT (0x7);
1293       operands[3] = GEN_INT (val - 0x7);
1294     }
1295   else
1296     {
1297       operands[2] = GEN_INT (- 0x8);
1298       operands[3] = GEN_INT (val + 0x8);
1299     }
1302 (define_insn "*addsi3_extended"
1303   [(set (match_operand:DI 0 "register_operand" "=d,d")
1304         (sign_extend:DI
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"
1308   "@
1309     addu\t%0,%1,%2
1310     addiu\t%0,%1,%2"
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")
1318         (sign_extend:DI
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"
1322   "#"
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")
1334         (zero_extend:SI
1335          (subreg:QI
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"
1339   "baddu\\t%0,%1,%2"
1340   [(set_attr "alu_type" "add")])
1342 (define_insn "*baddu_si_el"
1343   [(set (match_operand:SI 0 "register_operand" "=d")
1344         (zero_extend:SI
1345          (subreg:QI
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"
1349   "baddu\\t%0,%1,%2"
1350   [(set_attr "alu_type" "add")])
1352 (define_insn "*baddu_di<mode>"
1353   [(set (match_operand:GPR 0 "register_operand" "=d")
1354         (zero_extend:GPR
1355          (truncate:QI
1356           (plus:DI (match_operand:DI 1 "register_operand" "d")
1357                    (match_operand:DI 2 "register_operand" "d")))))]
1358   "ISA_HAS_BADDU && TARGET_64BIT"
1359   "baddu\\t%0,%1,%2"
1360   [(set_attr "alu_type" "add")])
1363 ;;  ....................
1365 ;;      SUBTRACTION
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")))]
1374   ""
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")))]
1383   ""
1384   "<d>subu\t%0,%1,%2"
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")
1391         (sign_extend:DI
1392             (minus:SI (match_operand:SI 1 "register_operand" "d")
1393                       (match_operand:SI 2 "register_operand" "d"))))]
1394   "TARGET_64BIT"
1395   "subu\t%0,%1,%2"
1396   [(set_attr "alu_type" "sub")
1397    (set_attr "mode" "DI")])
1400 ;;  ....................
1402 ;;      MULTIPLICATION
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")))]
1411   ""
1412   "")
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"
1442   "mul.ps\t%0,%1,%2"
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
1461 ;;      bits.
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."
1469 ;; and:
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.
1479 ;;      Workaround:
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
1485 ;;         is executed.
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,
1490 ;; respectively.
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")))]
1496   "ISA_HAS_<D>MULT"
1498   rtx lo;
1500   if (TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A)
1501     emit_insn (gen_mul<mode>3_mul3_loongson (operands[0], operands[1],
1502                                              operands[2]));
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)
1506     {
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);
1510     }
1511   else if (TARGET_FIX_R4000)
1512     emit_insn (gen_mul<mode>3_r4000 (operands[0], operands[1], operands[2]));
1513   else
1514     emit_insn
1515       (gen_mul<mode>3_internal (operands[0], operands[1], operands[2]));
1516   DONE;
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";
1527   else
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"))]
1538   "ISA_HAS_<D>MUL3"
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.
1553 ;; Operand 0: LO
1554 ;; Operand 1: GPR (1st multiplication operand)
1555 ;; Operand 2: GPR (2nd multiplication operand)
1556 ;; Operand 3: GPR (destination)
1557 (define_peephole2
1558   [(parallel
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")
1564         (match_dup 0))]
1565   "ISA_HAS_MUL3 && peep2_reg_dead_p (2, operands[0])"
1566   [(parallel
1567        [(set (match_dup 3)
1568              (mult:SI (match_dup 1)
1569                       (match_dup 2)))
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"
1577   "<d>mult\t%1,%2"
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.
1596 ;; Operand 0: LO
1597 ;; Operand 1: GPR (1st multiplication operand)
1598 ;; Operand 2: GPR (2nd multiplication operand)
1599 ;; Operand 3: GPR (destination)
1600 (define_peephole2
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")
1605         (match_dup 0))]
1606   "ISA_HAS_MACC && !ISA_HAS_MUL3"
1607   [(set (match_dup 0)
1608         (const_int 0))
1609    (parallel
1610        [(set (match_dup 0)
1611              (plus:SI (mult:SI (match_dup 1)
1612                                (match_dup 2))
1613                       (match_dup 0)))
1614         (set (match_dup 3)
1615              (plus:SI (mult:SI (match_dup 1)
1616                                (match_dup 2))
1617                       (match_dup 0)))])])
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
1629 ;; allocator.
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"
1648   "@
1649     madd\t%1,%2
1650     madd\t%1,%2
1651     #"
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"
1677   "@
1678     madd\t%1,%2
1679     madd\t%1,%2
1680     madd\t%0,%1,%2
1681     #"
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
1698 ;; values are GPRs.
1699 (define_split
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"))]
1706   "reload_completed"
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)))]
1711   "")
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"))]
1719   "ISA_HAS_MACC"
1721   if (which_alternative == 1)
1722     return "macc\t%0,%1,%2";
1723   else if (TARGET_MIPS5500)
1724     return "madd\t%1,%2";
1725   else
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"))]
1741   "ISA_HAS_MSAC"
1743   if (which_alternative == 1)
1744     return "msac\t%0,%2,%3";
1745   else if (TARGET_MIPS5500)
1746     return "msub\t%2,%3";
1747   else
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"
1763   "#"
1764   "&& reload_completed"
1765   [(set (match_dup 5)
1766         (neg:SI (match_dup 3)))
1767    (parallel
1768        [(set (match_dup 0)
1769              (plus:SI (mult:SI (match_dup 2)
1770                                (match_dup 5))
1771                       (match_dup 1)))
1772         (clobber (match_dup 4))])]
1773   ""
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"))
1784                  (match_dup 0)))
1785    (set (match_operand:SI 3 "register_operand" "=d")
1786         (plus:SI (mult:SI (match_dup 1)
1787                           (match_dup 2))
1788                  (match_dup 0)))]
1789   "ISA_HAS_MACC && reload_completed"
1790   "macc\t%3,%1,%2"
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)
1803                            (match_dup 2))))]
1804   "ISA_HAS_MSAC && reload_completed"
1805   "msac\t%3,%1,%2"
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>
1811 ;; Similarly msac.
1813 ;; Operand 0: LO
1814 ;; Operand 1: macc/msac
1815 ;; Operand 2: GPR (destination)
1816 (define_peephole2
1817   [(parallel
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")
1822         (match_dup 0))]
1823   ""
1824   [(parallel [(set (match_dup 0)
1825                    (match_dup 1))
1826               (set (match_dup 2)
1827                    (match_dup 1))])])
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)
1837 ;; Operand 1: LO
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
1843 (define_peephole2
1844   [(match_scratch:SI 0 "d")
1845    (set (match_operand:SI 1 "lo_operand")
1846         (match_operand:SI 2 "d_operand"))
1847    (match_dup 0)
1848    (parallel
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)
1854                    (match_dup 5))
1855               (clobber (match_dup 1))])
1856    (set (match_dup 3)
1857         (match_dup 6))]
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)
1867 ;; Operand 1: LO
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
1873 (define_peephole2
1874   [(match_scratch:SI 0 "d")
1875    (set (match_operand:SI 1 "lo_operand")
1876         (match_operand:SI 2 "d_operand"))
1877    (match_dup 0)
1878    (parallel
1879        [(set (match_dup 1)
1880              (match_operand:SI 3 "macc_msac_operand"))
1881         (clobber (scratch:SI))])
1882    (match_dup 0)
1883    (set (match_operand:SI 4 "d_operand")
1884         (match_dup 1))]
1885   "ISA_HAS_MUL3 && peep2_reg_dead_p (3, operands[1])"
1886   [(parallel [(set (match_dup 0)
1887                    (match_dup 5))
1888               (clobber (match_dup 1))])
1889    (set (match_dup 4)
1890         (match_dup 6))]
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"
1906   "@
1907    msub\t%2,%3
1908    msub\t%2,%3
1909    #"
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
1926 ;; values are GPRs.
1927 (define_split
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"))]
1934   "reload_completed"
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)))]
1939   "")
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"))]
1946   "ISA_HAS_MULS"
1947   "@
1948    muls\t$0,%1,%2
1949    muls\t%0,%1,%2"
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]));
1961   DONE;
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"
1970   rtx hilo;
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);
1975   DONE;
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";
1989   else
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"
2013   "#"
2014   "&& reload_completed"
2015   [(const_int 0)]
2017   emit_insn (gen_<u>mulsidi3_64bit_split (operands[0], operands[1],
2018                                           operands[2], operands[4]));
2019   DONE;
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")
2025                       (const_int 4)
2026                       (const_int 7)))])
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)));
2036   DONE;
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"))]
2044   ""
2046   rtx hilo;
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),
2056                            operands[3]));
2057   else
2058     {
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]);
2068     }
2069   DONE;
2072 (define_insn "<u>mulsidi3_64bit_hilo"
2073   [(set (match_operand:TI 0 "muldiv_target_operand" "=x")
2074         (unspec:TI
2075           [(mult:DI
2076              (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2077              (any_extend:DI (match_operand:SI 2 "register_operand" "d")))]
2078           UNSPEC_SET_HILO))]
2079   "TARGET_64BIT && !TARGET_FIX_R4000"
2080   "mult<u>\t%1,%2"
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"))]
2090   "ISA_HAS_DMUL3"
2091   "dmul\t%0,%1,%2"
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")
2098         (neg:DI
2099          (mult:DI
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"
2103   "muls<u>\t$0,%1,%2"
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")
2116         (minus:DI
2117            (match_operand:DI 3 "muldiv_target_operand" "0")
2118            (mult:DI
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";
2127   else
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")
2138         (truncate:SI
2139          (lshiftrt:DI
2140           (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
2141                    (any_extend:DI (match_operand:SI 2 "register_operand")))
2142           (const_int 32))))]
2143   ""
2145   if (ISA_HAS_MULHI)
2146     emit_insn (gen_<su>mulsi3_highpart_mulhi_internal (operands[0],
2147                                                        operands[1],
2148                                                        operands[2]));
2149   else if (TARGET_MIPS16)
2150     emit_insn (gen_<su>mulsi3_highpart_split (operands[0], operands[1],
2151                                               operands[2]));
2152   else
2153     emit_insn (gen_<su>mulsi3_highpart_internal (operands[0], operands[1],
2154                                                  operands[2]));
2155   DONE;
2158 (define_insn_and_split "<su>mulsi3_highpart_internal"
2159   [(set (match_operand:SI 0 "register_operand" "=d")
2160         (truncate:SI
2161          (lshiftrt:DI
2162           (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2163                    (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
2164           (const_int 32))))
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"
2169   [(const_int 0)]
2171   emit_insn (gen_<su>mulsi3_highpart_split (operands[0], operands[1],
2172                                             operands[2]));
2173   DONE;
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")
2181         (truncate:SI
2182          (lshiftrt:DI
2183           (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
2184                    (any_extend:DI (match_operand:SI 2 "register_operand")))
2185           (const_int 32))))]
2186   ""
2188   rtx hilo;
2190   if (TARGET_64BIT)
2191     {
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));
2195     }
2196   else
2197     {
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));
2201     }
2202   DONE;
2205 (define_insn "<su>mulsi3_highpart_mulhi_internal"
2206   [(set (match_operand:SI 0 "register_operand" "=d")
2207         (truncate:SI
2208          (lshiftrt:DI
2209           (mult:DI
2210            (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2211            (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
2212           (const_int 32))))
2213    (clobber (match_scratch:SI 3 "=l"))]
2214   "ISA_HAS_MULHI"
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")
2221         (truncate:SI
2222          (lshiftrt:DI
2223           (neg:DI
2224            (mult:DI
2225             (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2226             (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
2227           (const_int 32))))
2228    (clobber (match_scratch:SI 3 "=l"))]
2229   "ISA_HAS_MULHI"
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
2236 ;; correct result.
2237 (define_expand "<su>muldi3_highpart"
2238   [(set (match_operand:DI 0 "register_operand")
2239         (truncate:DI
2240          (lshiftrt:TI
2241           (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
2242                    (any_extend:TI (match_operand:DI 2 "register_operand")))
2243           (const_int 64))))]
2244   "ISA_HAS_DMULT && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
2246   if (TARGET_MIPS16)
2247     emit_insn (gen_<su>muldi3_highpart_split (operands[0], operands[1],
2248                                               operands[2]));
2249   else
2250     emit_insn (gen_<su>muldi3_highpart_internal (operands[0], operands[1],
2251                                                  operands[2]));
2252   DONE;
2255 (define_insn_and_split "<su>muldi3_highpart_internal"
2256   [(set (match_operand:DI 0 "register_operand" "=d")
2257         (truncate:DI
2258          (lshiftrt:TI
2259           (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
2260                    (any_extend:TI (match_operand:DI 2 "register_operand" "d")))
2261           (const_int 64))))
2262    (clobber (match_scratch:DI 3 "=l"))]
2263   "ISA_HAS_DMULT
2264    && !TARGET_MIPS16
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"
2268   [(const_int 0)]
2270   emit_insn (gen_<su>muldi3_highpart_split (operands[0], operands[1],
2271                                             operands[2]));
2272   DONE;
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")
2280         (truncate:DI
2281          (lshiftrt:TI
2282           (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
2283                    (any_extend:TI (match_operand:DI 2 "register_operand")))
2284           (const_int 64))))]
2285   ""
2287   rtx hilo;
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));
2292   DONE;
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)"
2301   rtx hilo;
2303   if (TARGET_MIPS16)
2304     {
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);
2308     }
2309   else if (TARGET_FIX_R4000)
2310     emit_insn (gen_<u>mulditi3_r4000 (operands[0], operands[1], operands[2]));
2311   else
2312     emit_insn (gen_<u>mulditi3_internal (operands[0], operands[1],
2313                                          operands[2]));
2314   DONE;
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"))))]
2321   "ISA_HAS_DMULT
2322    && !TARGET_FIX_R4000
2323    && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
2324   "dmult<u>\t%1,%2"
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"))]
2333   "ISA_HAS_DMULT
2334    && TARGET_FIX_R4000
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"))
2348                  (match_dup 0)))]
2349   "TARGET_MAD"
2350   "mad\t%1,%2"
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")
2359         (plus:DI
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)
2364    && !TARGET_64BIT"
2366   if (TARGET_MAD)
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";
2372   else
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")
2458         (minus:ANYF
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")
2473         (minus:ANYF
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")
2518         (minus:ANYF
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")
2533         (minus:ANYF
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>"
2584   if (TARGET_FIX_SB1)
2585     return "div.<fmt>\t%0,%1,%2\;mov.<fmt>\t%0,%0";
2586   else
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")
2593                       (const_int 2)
2594                       (const_int 1)))])
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"
2602   if (TARGET_FIX_SB1)
2603     return "recip.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
2604   else
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")
2611                       (const_int 2)
2612                       (const_int 1)))])
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"
2617   [(parallel
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)
2623                     (match_dup 2)))])]
2624   "ISA_HAS_<D>DIV && !TARGET_FIX_VR4120"
2626   if (TARGET_MIPS16)
2627     {
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));
2631       DONE;
2632     }
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)
2641                  (match_dup 2)))]
2642   "ISA_HAS_<D>DIV && !TARGET_FIX_VR4120 && !TARGET_MIPS16"
2643   "#"
2644   "&& reload_completed"
2645   [(const_int 0)]
2647   emit_insn (gen_divmod<mode>4_split (operands[3], operands[1], operands[2]));
2648   DONE;
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)
2666                  (match_dup 2)))
2667    (clobber (match_operand:GPR 4 "lo_operand" "=l"))]
2668   "ISA_HAS_<D>DIV && !TARGET_FIX_VR4120 && TARGET_MIPS16"
2669   "#"
2670   "&& cse_not_expected"
2671   [(const_int 0)]
2673   emit_insn (gen_divmod<mode>4_split (operands[3], operands[1], operands[2]));
2674   emit_move_insn (operands[0], operands[4]);
2675   DONE;
2677  [(set_attr "type" "idiv")
2678   (set_attr "mode" "<MODE>")
2679   (set_attr "insn_count" "3")])
2681 (define_expand "udivmod<mode>4"
2682   [(parallel
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)
2688                      (match_dup 2)))])]
2689   "ISA_HAS_<D>DIV && !TARGET_FIX_VR4120"
2691   if (TARGET_MIPS16)
2692     {
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));
2696       DONE;
2697     }
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)
2706                   (match_dup 2)))]
2707   "ISA_HAS_<D>DIV && !TARGET_MIPS16"
2708   "#"
2709   "reload_completed"
2710   [(const_int 0)]
2712   emit_insn (gen_udivmod<mode>4_split (operands[3], operands[1], operands[2]));
2713   DONE;
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)
2726                   (match_dup 2)))
2727    (clobber (match_operand:GPR 4 "lo_operand" "=l"))]
2728   "ISA_HAS_<D>DIV && TARGET_MIPS16"
2729   "#"
2730   "cse_not_expected"
2731   [(const_int 0)]
2733   emit_insn (gen_udivmod<mode>4_split (operands[3], operands[1], operands[2]));
2734   emit_move_insn (operands[0], operands[4]);
2735   DONE;
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")))]
2745   ""
2747   rtx hilo;
2749   if (TARGET_64BIT)
2750     {
2751       hilo = gen_rtx_REG (TImode, MD_REG_FIRST);
2752       emit_insn (gen_<u>divmod<mode>4_hilo_ti (hilo, operands[1],
2753                                                operands[2]));
2754       emit_insn (gen_mfhi<mode>_ti (operands[0], hilo));
2755     }
2756   else
2757     {
2758       hilo = gen_rtx_REG (DImode, MD_REG_FIRST);
2759       emit_insn (gen_<u>divmod<mode>4_hilo_di (hilo, operands[1],
2760                                                operands[2]));
2761       emit_insn (gen_mfhi<mode>_di (operands[0], hilo));
2762     }
2763   DONE;
2766 (define_insn "<u>divmod<GPR:mode>4_hilo_<HILO:mode>"
2767   [(set (match_operand:HILO 0 "muldiv_target_operand" "=x")
2768         (unspec:HILO
2769           [(any_div:GPR (match_operand:GPR 1 "register_operand" "d")
2770                         (match_operand:GPR 2 "register_operand" "d"))]
2771           UNSPEC_SET_HILO))]
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 ;;  ....................
2780 ;;      SQUARE ROOT
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")))]
2790   "<sqrt_condition>"
2792   if (TARGET_FIX_SB1)
2793     return "sqrt.<fmt>\t%0,%1\;mov.<fmt>\t%0,%0";
2794   else
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")
2801                       (const_int 2)
2802                       (const_int 1)))])
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"
2810   if (TARGET_FIX_SB1)
2811     return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
2812   else
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")
2819                       (const_int 2)
2820                       (const_int 1)))])
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"
2828   if (TARGET_FIX_SB1)
2829     return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
2830   else
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")
2837                       (const_int 2)
2838                       (const_int 1)))])
2841 ;;  ....................
2843 ;;      ABSOLUTE VALUE
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
2853 ;; NaNs matter.
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)"
2859   "abs.<fmt>\t%0,%1"
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")))]
2874   "ISA_HAS_CLZ_CLO"
2875   "<d>clz\t%0,%1"
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")))]
2890   "ISA_HAS_POP"
2891   "<d>pop\t%0,%1"
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"
2901   "pop\t%0,%1"
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")))]
2915   ""
2917   if (TARGET_MIPS16)
2918     return "neg\t%0,%1";
2919   else
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"
2929   "dsubu\t%0,%.,%1"
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
2936 ;; NaNs matter.
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)"
2942   "neg.<fmt>\t%0,%1"
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")))]
2949   ""
2951   if (TARGET_MIPS16)
2952     return "not\t%0,%1";
2953   else
2954     return "nor\t%0,%.,%1";
2956   [(set_attr "alu_type" "not")
2957    (set_attr "compression" "micromips,*")
2958    (set_attr "mode" "<MODE>")])
2961 ;;  ....................
2963 ;;      LOGICAL
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
2987 ;;  op2
2989 ;;  andi           x     x
2990 ;;  0xff           x     x       x             x
2991 ;;  0xffff         x     x       x             x
2992 ;;  0xffff_ffff    x     S       x     S       x
2993 ;;  low-bitmask    x
2994 ;;  register       x     x
2995 ;;  register =op1                      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])"
3003   int len;
3005   switch (which_alternative)
3006     {
3007     case 0:
3008       operands[1] = gen_lowpart (QImode, operands[1]);
3009       return "lbu\t%0,%1";
3010     case 1:
3011       operands[1] = gen_lowpart (HImode, operands[1]);
3012       return "lhu\t%0,%1";
3013     case 2:
3014       operands[1] = gen_lowpart (SImode, operands[1]);
3015       return "lwu\t%0,%1";
3016     case 3:
3017     case 4:
3018       return "andi\t%0,%1,%x2";
3019     case 5:
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";
3023     case 6:
3024       return "#";
3025     case 7:
3026     case 8:
3027       return "and\t%0,%1,%2";
3028     default:
3029       gcc_unreachable ();
3030     }
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)
3043     {
3044     case 0:
3045       operands[1] = gen_lowpart (QImode, operands[1]);
3046       return "lbu\t%0,%1";
3047     case 1:
3048       operands[1] = gen_lowpart (HImode, operands[1]);
3049       return "lhu\t%0,%1";
3050     case 2:
3051       operands[1] = gen_lowpart (SImode, operands[1]);
3052       return "lwu\t%0,%1";
3053     case 3:
3054       return "#";
3055     case 4:
3056       return "and\t%0,%2";
3057     default:
3058       gcc_unreachable ();
3059     }
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")))]
3068   ""
3070   if (TARGET_MIPS16)
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")))]
3078   "!TARGET_MIPS16"
3079   "@
3080    or\t%0,%1,%2
3081    or\t%0,%1,%2
3082    ori\t%0,%1,%x2"
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")))]
3091   "TARGET_MIPS16"
3092   "or\t%0,%2"
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")))]
3100   ""
3101   "")
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")))]
3107   "!TARGET_MIPS16"
3108   "@
3109    xor\t%0,%1,%2
3110    xor\t%0,%1,%2
3111    xori\t%0,%1,%x2"
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")))]
3120   "TARGET_MIPS16"
3121   "@
3122    xor\t%0,%2
3123    cmpi\t%1,%2
3124    cmpi\t%1,%2
3125    cmp\t%1,%2"
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"))))]
3134   "!TARGET_MIPS16"
3135   "nor\t%0,%1,%2"
3136   [(set_attr "alu_type" "nor")
3137    (set_attr "mode" "<MODE>")])
3140 ;;  ....................
3142 ;;      TRUNCATION
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"
3152   "cvt.s.d\t%0,%1"
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:
3164 ;;                        A       B
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")))]
3173   "TARGET_64BIT"
3174   "@
3175     sll\t%0,%1,0
3176     <store>\t%1,%0"
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")
3184         (truncate:SUBDI
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)"
3188   "dsra\t%0,%1,%2"
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")
3194         (truncate:SUBDI
3195           (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
3196                        (const_int 32))))]
3197   "TARGET_64BIT && !TARGET_MIPS16"
3198   "dsra\t%0,%1,32"
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")
3207         (truncate:SUBDI
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"
3211   "exts\t%0,%1,%2,31"
3212   [(set_attr "type" "arith")
3213    (set_attr "mode" "<MODE>")])
3216 ;;  ....................
3218 ;;      ZERO EXTENSION
3220 ;;  ....................
3222 ;; Extension insns.
3224 (define_expand "zero_extendsidi2"
3225   [(set (match_operand:DI 0 "register_operand")
3226         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3227   "TARGET_64BIT")
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"
3233   "@
3234    #
3235    lwu\t%0,%1"
3236   "&& reload_completed && REG_P (operands[1])"
3237   [(set (match_dup 0)
3238         (ashift:DI (match_dup 1) (const_int 32)))
3239    (set (match_dup 0)
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"
3249   "@
3250    dext\t%0,%1,0,32
3251    lwu\t%0,%1"
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
3256 ;; combine.
3258 (define_split
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"
3263   [(set (match_dup 0)
3264         (ashift:DI (match_dup 1) (const_int 32)))
3265    (set (match_dup 0)
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")))]
3271   ""
3273   if (TARGET_MIPS16 && !GENERATE_MIPS16E
3274       && !memory_operand (operands[1], <SHORT:MODE>mode))
3275     {
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>))));
3280       DONE;
3281     }
3284 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2"
3285   [(set (match_operand:GPR 0 "register_operand" "=!u,d,d")
3286         (zero_extend:GPR
3287              (match_operand:SHORT 1 "nonimmediate_operand" "!u,d,m")))]
3288   "!TARGET_MIPS16"
3289   "@
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")))]
3300   "GENERATE_MIPS16E"
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")))]
3309   "TARGET_MIPS16"
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")))]
3317   ""
3319   if (TARGET_MIPS16 && !memory_operand (operands[1], QImode))
3320     {
3321       emit_insn (gen_zero_extendqisi2 (gen_lowpart (SImode, operands[0]),
3322                                        operands[1]));
3323       DONE;
3324     }
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")))]
3330   "!TARGET_MIPS16"
3331   "@
3332    andi\t%0,%1,0x00ff
3333    lbu\t%0,%1"
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")))]
3340   "TARGET_MIPS16"
3341   "lbu\t%0,%1"
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")
3349         (zero_extend:GPR
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")
3361         (zero_extend:HI
3362             (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
3363   "TARGET_64BIT && !TARGET_MIPS16"
3364   "andi\t%0,%1,0xff"
3365   [(set_attr "alu_type" "and")
3366    (set_attr "mode" "HI")])
3369 ;;  ....................
3371 ;;      SIGN EXTENSION
3373 ;;  ....................
3375 ;; Extension insns.
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
3382 ;; the destination.
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")))]
3394   "TARGET_64BIT"
3395   "@
3396    #
3397    #
3398    lw\t%0,%1"
3399   "&& reload_completed && register_operand (operands[1], VOIDmode)"
3400   [(const_int 0)]
3402   emit_note (NOTE_INSN_DELETED);
3403   DONE;
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")))]
3411   "")
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")))]
3416   "GENERATE_MIPS16E"
3417   "@
3418    se<SHORT:size>\t%0
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")
3425         (sign_extend:GPR
3426              (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
3427   "!ISA_HAS_SEB_SEH && !GENERATE_MIPS16E"
3428   "@
3429    #
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")
3444         (sign_extend:GPR
3445              (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
3446   "ISA_HAS_SEB_SEH"
3447   "@
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")))]
3456   "")
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")))]
3461   "GENERATE_MIPS16E"
3462   "@
3463    seb\t%0
3464    lb\t%0,%1"
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")
3470         (sign_extend:HI
3471              (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3472   "!ISA_HAS_SEB_SEH && !GENERATE_MIPS16E"
3473   "@
3474    #
3475    lb\t%0,%1"
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")
3490         (sign_extend:HI
3491              (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3492   "ISA_HAS_SEB_SEH"
3493   "@
3494    seb\t%0,%1
3495    lb\t%0,%1"
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")
3504         (sign_extend:DI
3505             (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
3506   "TARGET_64BIT && !TARGET_MIPS16 && !ISA_HAS_EXTS"
3507   "#"
3508   "&& reload_completed"
3509   [(set (match_dup 2)
3510         (ashift:DI (match_dup 1)
3511                    (match_dup 3)))
3512    (set (match_dup 0)
3513         (ashiftrt:DI (match_dup 2)
3514                      (match_dup 3)))]
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")
3524         (sign_extend:SI
3525             (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
3526   "TARGET_64BIT && !TARGET_MIPS16 && !ISA_HAS_EXTS"
3527   "#"
3528   "&& reload_completed"
3529   [(set (match_dup 2)
3530         (ashift:DI (match_dup 1)
3531                    (match_dup 3)))
3532    (set (match_dup 0)
3533         (truncate:SI (ashiftrt:DI (match_dup 2)
3534                                   (match_dup 3))))]
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")
3544         (sign_extend:HI
3545             (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
3546   "TARGET_64BIT && !TARGET_MIPS16 && !ISA_HAS_EXTS"
3547   "#"
3548   "&& reload_completed"
3549   [(set (match_dup 2)
3550         (ashift:DI (match_dup 1)
3551                    (const_int 56)))
3552    (set (match_dup 0)
3553         (truncate:HI (ashiftrt:DI (match_dup 2)
3554                                   (const_int 56))))]
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")
3563         (sign_extend:GPR
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")
3575         (sign_extend:HI
3576             (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
3577   "TARGET_64BIT && !TARGET_MIPS16 && ISA_HAS_EXTS"
3578   "exts\t%0,%1,0,7"
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"
3586   "cvt.d.s\t%0,%1"
3587   [(set_attr "type"     "fcvt")
3588    (set_attr "cnv_mode" "S2D")   
3589    (set_attr "mode"     "DF")])
3592 ;;  ....................
3594 ;;      CONVERSIONS
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)
3604     {
3605       emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
3606       DONE;
3607     }
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"
3614   "trunc.w.d %0,%1"
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";
3627   else
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")))]
3638   "TARGET_HARD_FLOAT"
3640   if (!ISA_HAS_TRUNC_W)
3641     {
3642       emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
3643       DONE;
3644     }
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"
3651   "trunc.w.s %0,%1"
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";
3664   else
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"
3677   "trunc.l.d %0,%1"
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"
3687   "trunc.l.s %0,%1"
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"
3697   "cvt.d.w\t%0,%1"
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"
3707   "cvt.d.l\t%0,%1"
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")))]
3716   "TARGET_HARD_FLOAT"
3717   "cvt.s.w\t%0,%1"
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"
3727   "cvt.s.l\t%0,%1"
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 ();
3743   rtx test;
3744   REAL_VALUE_TYPE offset;
3746   real_2expN (&offset, 31, DFmode);
3748   if (reg1)                     /* Turn off complaints about unreached code.  */
3749     {
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)));
3759       emit_barrier ();
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);
3774       DONE;
3775     }
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 ();
3789   rtx test;
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)));
3803   emit_barrier ();
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);
3818   DONE;
3822 (define_expand "fixuns_truncsfsi2"
3823   [(set (match_operand:SI 0 "register_operand")
3824         (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
3825   "TARGET_HARD_FLOAT"
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 ();
3832   rtx test;
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)));
3846   emit_barrier ();
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);
3861   DONE;
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 ();
3875   rtx test;
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)));
3889   emit_barrier ();
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);
3904   DONE;
3908 ;;  ....................
3910 ;;      DATA MOVEMENT
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")))]
3921   "!TARGET_MIPS16"
3923   if (mips_expand_ext_as_unaligned_load (operands[0], operands[1],
3924                                          INTVAL (operands[2]),
3925                                          INTVAL (operands[3]),
3926                                          /*unsigned=*/ false))
3927     DONE;
3928   else
3929     FAIL;
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")))]
3937   "ISA_HAS_EXTS"
3939   if (UINTVAL (operands[2]) > 32)
3940     FAIL;
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")))]
3958   "!TARGET_MIPS16"
3960   if (mips_expand_ext_as_unaligned_load (operands[0], operands[1],
3961                                          INTVAL (operands[2]),
3962                                          INTVAL (operands[3]),
3963                                          /*unsigned=*/ true))
3964     DONE;
3965   else
3966     FAIL;
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")))]
3974   ""
3976   if (!mips_use_ins_ext_p (operands[1], INTVAL (operands[2]),
3977                            INTVAL (operands[3])))
3978     FAIL;
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")
3994         (truncate:SI
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)"
3999   "exts\t%0,%1,%3,31"
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"))]
4009   "!TARGET_MIPS16"
4011   if (mips_expand_ins_as_unaligned_store (operands[0], operands[3],
4012                                           INTVAL (operands[1]),
4013                                           INTVAL (operands[2])))
4014     DONE;
4015   else
4016     FAIL;
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"))]
4024   ""
4026   if (!mips_use_ins_ext_p (operands[0], INTVAL (operands[1]),
4027                            INTVAL (operands[2])))
4028     FAIL;
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")
4050         (and:GPR
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" "")))]
4054   "ISA_HAS_CINS
4055    && mask_low_and_shift_p (<MODE>mode, operands[3], operands[2], 32)"
4057   operands[3] =
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")]
4080                     UNSPEC_LOAD_LEFT))]
4081   "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
4082   "<load>l\t%0,%2"
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])"
4093   "<load>r\t%0,%2"
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])"
4103   "<store>l\t%z1,%2"
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")
4111                      (match_dup 0)]
4112                     UNSPEC_STORE_RIGHT))]
4113   "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
4114   "<store>r\t%z1,%2"
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)
4127 ;;      dsll    op0,op0,16
4128 ;;      daddiu  op0,op0,%hi(op1)
4129 ;;      dsll    op0,op0,16
4131 ;; The split is deferred until after flow2 to allow the peephole2 below
4132 ;; to take effect.
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"
4137   "#"
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)
4154 ;;      lui     op0,%hi(op2)
4155 ;;      daddiu  op1,op1,%higher(op2)
4156 ;;      dsll32  op1,op1,0
4157 ;;      daddu   op1,op1,op0
4158 (define_peephole2
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)
4179 ;;      lui     op2,%hi(op1)
4180 ;;      daddiu  op0,op0,%higher(op1)
4181 ;;      daddiu  op2,op2,%lo(op1)
4182 ;;      dsll32  op0,op0,0
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"))]
4190   "!TARGET_MIPS16
4191    && TARGET_EXPLICIT_RELOCS
4192    && ABI_HAS_64BIT_SYMBOLS
4193    && cse_not_expected"
4194   "#"
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:
4210 ;;      li op0,%hi(sym)
4211 ;;      sll op0,16
4213 ;; on MIPS16 targets.
4214 (define_split
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))]
4225   ""
4226   "li\t%0,%h1"
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"
4235   "#"
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"
4251   "#"
4252   "&& reload_completed"
4253   [(set (match_dup 0)
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]"
4265   "#"
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]"
4278   "#"
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
4292 ;; opportunities.
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" "")]
4298                   UNSPEC_LOAD_GOT))]
4299   ""
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" "")))]
4312   "!TARGET_MIPS16"
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" "")))]
4321   "TARGET_MIPS16"
4322   "<d>addiu\t%0,%R2"
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.
4329 (define_split
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.
4338 (define_split
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"))]
4342   ""
4343   [(const_int 0)]
4345   mips_move_integer (operands[2], operands[0], INTVAL (operands[1]));
4346   DONE;
4349 ;; Likewise, for symbolic operands.
4350 (define_split
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 ""))]
4370   ""
4372   if (mips_legitimize_move (DImode, operands[0], operands[1]))
4373     DONE;
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))]
4383   "TARGET_MIPS16"
4384   "<store>\t$31,%0"
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")
4396    (set (attr "mode")
4397         (if_then_else (eq_attr "move_type" "imul")
4398                       (const_string "SI")
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.
4435 (define_split
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]);
4453   if (val < 0)
4454     operands[2] = const0_rtx;
4455   else if (val >= 32 * 8)
4456     {
4457       int off = val & 7;
4459       operands[1] = GEN_INT (0x8 + off);
4460       operands[2] = GEN_INT (val - off - 0x8);
4461     }
4462   else
4463     {
4464       int off = val & 7;
4466       operands[1] = GEN_INT (off);
4467       operands[2] = GEN_INT (val - off);
4468     }
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 ""))]
4480   ""
4482   if (mips_legitimize_move (<MODE>mode, operands[0], operands[1]))
4483     DONE;
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"))]
4492   "!TARGET_MIPS16
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"))]
4503   "TARGET_MIPS16
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.
4514 (define_split
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]);
4531   if (val < 0)
4532     operands[2] = const0_rtx;
4533   else if (val >= 32 * 4)
4534     {
4535       int off = val & 3;
4537       operands[1] = GEN_INT (0x7c + off);
4538       operands[2] = GEN_INT (val - off - 0x7c);
4539     }
4540   else
4541     {
4542       int off = val & 3;
4544       operands[1] = GEN_INT (off);
4545       operands[2] = GEN_INT (val - off);
4546     }
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
4551 ;; instructions.
4553 (define_split
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"))))]
4585   "ISA_HAS_LXC1_SXC1"
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"))]
4594   "ISA_HAS_LXC1_SXC1"
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")
4605         (mem:IMOVE32
4606           (plus:P (mult:P (match_operand:P 1 "register_operand" "d")
4607                           (const_int 4))
4608                   (match_operand:P 2 "register_operand" "d"))))]
4609   "ISA_HAS_LWXS"
4610   "lwxs\t%0,%1(%2)"
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 ""))]
4624   ""
4626   if (mips_legitimize_move (HImode, operands[0], operands[1]))
4627     DONE;
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"))]
4633   "!TARGET_MIPS16
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"))]
4644   "TARGET_MIPS16
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.
4655 (define_split
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]);
4672   if (val < 0)
4673     operands[2] = const0_rtx;
4674   else if (val >= 32 * 2)
4675     {
4676       int off = val & 1;
4678       operands[1] = GEN_INT (0x7e + off);
4679       operands[2] = GEN_INT (val - off - 0x7e);
4680     }
4681   else
4682     {
4683       int off = val & 1;
4685       operands[1] = GEN_INT (off);
4686       operands[2] = GEN_INT (val - off);
4687     }
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 ""))]
4700   ""
4702   if (mips_legitimize_move (QImode, operands[0], operands[1]))
4703     DONE;
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"))]
4709   "!TARGET_MIPS16
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"))]
4720   "TARGET_MIPS16
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.
4731 (define_split
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]);
4745   if (val < 0)
4746     operands[2] = const0_rtx;
4747   else
4748     {
4749       operands[1] = GEN_INT (0x7f);
4750       operands[2] = GEN_INT (val - 0x7f);
4751     }
4754 ;; 32-bit floating point moves
4756 (define_expand "movsf"
4757   [(set (match_operand:SF 0 "")
4758         (match_operand:SF 1 ""))]
4759   ""
4761   if (mips_legitimize_move (SFmode, operands[0], operands[1]))
4762     DONE;
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"))]
4768   "TARGET_HARD_FLOAT
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"))]
4788   "TARGET_MIPS16
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 ""))]
4800   ""
4802   if (mips_legitimize_move (DFmode, operands[0], operands[1]))
4803     DONE;
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"))]
4829   "TARGET_MIPS16
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))]
4841   "TARGET_64BIT"
4843   if (mips_legitimize_move (TImode, operands[0], operands[1]))
4844     DONE;
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"))]
4850   "TARGET_64BIT
4851    && !TARGET_MIPS16
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")
4856    (set (attr "mode")
4857         (if_then_else (eq_attr "move_type" "imul")
4858                       (const_string "SI")
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"))]
4864   "TARGET_64BIT
4865    && TARGET_MIPS16
4866    && (register_operand (operands[0], TImode)
4867        || register_operand (operands[1], TImode))"
4868   "#"
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))]
4877   "TARGET_64BIT"
4879   if (mips_legitimize_move (TFmode, operands[0], operands[1]))
4880     DONE;
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"))]
4887   "TARGET_64BIT
4888    && !TARGET_MIPS16
4889    && (register_operand (operands[0], TFmode)
4890        || reg_or_0_operand (operands[1], TFmode))"
4891   "#"
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"))]
4898   "TARGET_64BIT
4899    && TARGET_MIPS16
4900    && (register_operand (operands[0], TFmode)
4901        || register_operand (operands[1], TFmode))"
4902   "#"
4903   [(set_attr "move_type" "move,move,move,load,store")
4904    (set_attr "mode" "TF")])
4906 (define_split
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)"
4910   [(const_int 0)]
4912   mips_split_move_insn (operands[0], operands[1], curr_insn);
4913   DONE;
4916 (define_split
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)"
4920   [(const_int 0)]
4922   mips_split_move_insn (operands[0], operands[1], curr_insn);
4923   DONE;
4926 ;; When generating mips16 code, split moves of negative constants into
4927 ;; a positive "li" followed by a negation.
4928 (define_split
4929   [(set (match_operand 0 "d_operand")
4930         (match_operand 1 "const_int_operand"))]
4931   "TARGET_MIPS16 && reload_completed && INTVAL (operands[1]) < 0"
4932   [(set (match_dup 2)
4933         (match_dup 3))
4934    (set (match_dup 2)
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]))
4949     DONE;
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"))]
4955   "TARGET_HARD_FLOAT
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")]
4972                     UNSPEC_MFHI))]
4973   ""
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")]
4985                      UNSPEC_MTHI))]
4986   ""
4987   "mthi\t%z1"
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))]
5001   ""
5003   if (FP_REG_RTX_P (operands[0]))
5004     {
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]));
5010       else
5011         emit_insn (gen_load_high<mode> (operands[0], high, operands[0]));
5012     }
5013   else
5014     {
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]));
5020       else
5021         emit_insn (gen_store_word<mode> (high, operands[1], const1_rtx));
5022     }
5023   DONE;
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")]
5030                        UNSPEC_LOAD_LOW))]
5031   "TARGET_HARD_FLOAT"
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
5040 ;; in the low word.
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")]
5045                        UNSPEC_LOAD_HIGH))]
5046   "TARGET_HARD_FLOAT"
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))]
5061   "TARGET_HARD_FLOAT"
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")]
5075                        UNSPEC_MTHC1))]
5076   "TARGET_HARD_FLOAT && ISA_HAS_MXHC1"
5077   "mthc1\t%z1,%0"
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")]
5085                             UNSPEC_MFHC1))]
5086   "TARGET_HARD_FLOAT && ISA_HAS_MXHC1"
5087   "mfhc1\t%0,%1"
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")]
5103                   UNSPEC_LOADGP))]
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 ()"
5124   [(const_int 0)]
5126   mips_emit_move (operands[0], operands[1]);
5127   DONE;
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)]
5136   ""
5137   ""
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")]
5146                   UNSPEC_LOADGP))]
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")]
5167                   UNSPEC_COPYGP))]
5168   "TARGET_MIPS16"
5169   { return mips_must_initialize_gp_p () ? "#" : ""; }
5170   "&& mips_must_initialize_gp_p ()"
5171   [(set (match_dup 0) (match_dup 1))]
5172   ""
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 ()"
5190   [(const_int 0)]
5192   mips_save_gp_to_cprestore_slot (operands[0], operands[1],
5193                                   operands[2], operands[3]);
5194   DONE;
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")
5206                    (reg:P 28)]
5207                   UNSPEC_CPRESTORE))]
5208   "TARGET_CPRESTORE_DIRECTIVE"
5210   if (mips_nomacro.nesting_level > 0 && which_alternative == 1)
5211     return ".set\tmacro\;.cprestore\t%1\;.set\tnomacro";
5212   else
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"))]
5221   ""
5222   ""
5223   [(set_attr "type" "ghost")])
5225 ;; Expand in-line code to clear the instruction cache between operand[0] and
5226 ;; operand[1].
5227 (define_expand "clear_cache"
5228   [(match_operand 0 "pmode_register_operand")
5229    (match_operand 1 "pmode_register_operand")]
5230   ""
5231   "
5233   if (TARGET_SYNCI)
5234     {
5235       mips_expand_synci_loop (operands[0], operands[1]);
5236       emit_insn (gen_sync ());
5237       emit_insn (PMODE_INSN (gen_clear_hazard, ()));
5238     }
5239   else if (mips_cache_flush_func && mips_cache_flush_func[0])
5240     {
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);
5244     }
5245   DONE;
5248 (define_insn "sync"
5249   [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)]
5250   "GENERATE_SYNC"
5251   { return mips_output_sync (); })
5253 (define_insn "synci"
5254   [(unspec_volatile [(match_operand 0 "pmode_register_operand" "d")]
5255                     UNSPEC_SYNCI)]
5256   "TARGET_SYNCI"
5257   "synci\t0(%0)")
5259 (define_insn "rdhwr_synci_step_<mode>"
5260   [(set (match_operand:P 0 "register_operand" "=d")
5261         (unspec_volatile [(const_int 1)]
5262         UNSPEC_RDHWR))]
5263   "ISA_HAS_SYNCI"
5264   "rdhwr\t%0,$1")
5266 (define_insn "clear_hazard_<mode>"
5267   [(unspec_volatile [(const_int 0)] UNSPEC_CLEAR_HAZARD)
5268    (clobber (reg:P RETURN_ADDR_REGNUM))]
5269   "ISA_HAS_SYNCI"
5271   return "%(%<bal\t1f\n"
5272          "\tnop\n"
5273          "1:\t<d>addiu\t$31,$31,12\n"
5274          "\tjr.hb\t$31\n"
5275          "\tnop%>%)";
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))]
5285   "ISA_HAS_CACHE"
5286   "cache\t%X0,%a1")
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))]
5295   "ISA_HAS_CACHE"
5296   "cache\t0x14,0(%$)"
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]))
5313     DONE;
5314   else
5315     FAIL;
5319 ;;  ....................
5321 ;;      SHIFTS
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")))]
5329   ""
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
5337      reload pass.  */
5338   if (TARGET_MIPS16
5339       && optimize
5340       && CONST_INT_P (operands[2])
5341       && INTVAL (operands[2]) > 8
5342       && INTVAL (operands[2]) <= 16
5343       && !reload_in_progress
5344       && !reload_completed)
5345     {
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)));
5351       DONE;
5352     }
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")))]
5359   "!TARGET_MIPS16"
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")
5373         (sign_extend:DI
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")))]
5390   "TARGET_MIPS16"
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
5403 ;; of right shifts.
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.
5452 (define_split
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")))]
5475   "TARGET_MIPS16"
5476   "#"
5477   ""
5478   [(set (match_dup 0) (match_dup 1))
5479    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
5480   ""
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")))]
5490   "ISA_HAS_ROR"
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")))]
5504   "ISA_HAS_WSBH"
5505   "wsbh\t%0,%1"
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"
5512   "#"
5513   ""
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)))]
5516   ""
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"
5523   "#"
5524   ""
5525   [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_DSBH))
5526    (set (match_dup 0) (unspec:DI [(match_dup 0)] UNSPEC_DSHD))]
5527   ""
5528   [(set_attr "insn_count" "2")])
5530 (define_insn "wsbh"
5531   [(set (match_operand:SI 0 "register_operand" "=d")
5532         (unspec:SI [(match_operand:SI 1 "register_operand" "d")] UNSPEC_WSBH))]
5533   "ISA_HAS_WSBH"
5534   "wsbh\t%0,%1"
5535   [(set_attr "type" "shift")])
5537 (define_insn "dsbh"
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"
5541   "dsbh\t%0,%1"
5542   [(set_attr "type" "shift")])
5544 (define_insn "dshd"
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"
5548   "dshd\t%0,%1"
5549   [(set_attr "type" "shift")])
5552 ;;  ....................
5554 ;;      CONDITIONAL BRANCHES
5556 ;;  ....................
5558 ;; Conditional branches on floating-point equality tests.
5560 (define_insn "*branch_fp"
5561   [(set (pc)
5562         (if_then_else
5563          (match_operator 1 "equality_operator"
5564                          [(match_operand:CC 2 "register_operand" "z")
5565                           (const_int 0)])
5566          (label_ref (match_operand 0 "" ""))
5567          (pc)))]
5568   "TARGET_HARD_FLOAT"
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"
5577   [(set (pc)
5578         (if_then_else
5579          (match_operator 1 "equality_operator"
5580                          [(match_operand:CC 2 "register_operand" "z")
5581                           (const_int 0)])
5582          (pc)
5583          (label_ref (match_operand 0 "" ""))))]
5584   "TARGET_HARD_FLOAT"
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>"
5595   [(set (pc)
5596         (if_then_else
5597          (match_operator 1 "order_operator"
5598                          [(match_operand:GPR 2 "register_operand" "d")
5599                           (const_int 0)])
5600          (label_ref (match_operand 0 "" ""))
5601          (pc)))]
5602   "!TARGET_MIPS16"
5603   { return mips_output_order_conditional_branch (insn, operands, false); }
5604   [(set_attr "type" "branch")])
5606 (define_insn "*branch_order<mode>_inverted"
5607   [(set (pc)
5608         (if_then_else
5609          (match_operator 1 "order_operator"
5610                          [(match_operand:GPR 2 "register_operand" "d")
5611                           (const_int 0)])
5612          (pc)
5613          (label_ref (match_operand 0 "" ""))))]
5614   "!TARGET_MIPS16"
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>"
5621   [(set (pc)
5622         (if_then_else
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 "" ""))
5627          (pc)))]
5628   "!TARGET_MIPS16"
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,
5635                                            "%*b%C1z%:\t%2,%0",
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"
5645   [(set (pc)
5646         (if_then_else
5647          (match_operator 1 "equality_operator"
5648                          [(match_operand:GPR 2 "register_operand" "d")
5649                           (match_operand:GPR 3 "reg_or_0_operand" "dJ")])
5650          (pc)
5651          (label_ref (match_operand 0 "" ""))))]
5652   "!TARGET_MIPS16"
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,
5659                                            "%*b%N0z%:\t%2,%1",
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")])
5668 ;; MIPS16 branches
5670 (define_insn "*branch_equality<mode>_mips16"
5671   [(set (pc)
5672         (if_then_else
5673          (match_operator 1 "equality_operator"
5674                          [(match_operand:GPR 2 "register_operand" "d,t")
5675                           (const_int 0)])
5676          (label_ref (match_operand 0 "" ""))
5677          (pc)))]
5678   "TARGET_MIPS16"
5679   "@
5680    b%C1z\t%2,%0
5681    bt%C1z\t%0"
5682   [(set_attr "type" "branch")])
5684 (define_insn "*branch_equality<mode>_mips16_inverted"
5685   [(set (pc)
5686         (if_then_else
5687          (match_operator 1 "equality_operator"
5688                          [(match_operand:GPR 2 "register_operand" "d,t")
5689                           (const_int 0)])
5690          (pc)
5691          (label_ref (match_operand 0 "" ""))))]
5692   "TARGET_MIPS16"
5693   "@
5694    b%N1z\t%2,%0
5695    bt%N1z\t%0"
5696   [(set_attr "type" "branch")])
5698 (define_expand "cbranch<mode>4"
5699   [(set (pc)
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 ""))
5704                       (pc)))]
5705   ""
5707   mips_expand_conditional_branch (operands);
5708   DONE;
5711 (define_expand "cbranch<mode>4"
5712   [(set (pc)
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 ""))
5717                       (pc)))]
5718   ""
5720   mips_expand_conditional_branch (operands);
5721   DONE;
5724 ;; Used to implement built-in functions.
5725 (define_expand "condjump"
5726   [(set (pc)
5727         (if_then_else (match_operand 0)
5728                       (label_ref (match_operand 1))
5729                       (pc)))])
5731 ;; Branch if bit is set/clear.
5733 (define_insn "*branch_bit<bbv><mode>"
5734   [(set (pc)
5735         (if_then_else
5736          (equality_op (zero_extract:GPR
5737                        (match_operand:GPR 1 "register_operand" "d")
5738                        (const_int 1)
5739                        (match_operand 2 "const_int_operand" ""))
5740                       (const_int 0))
5741          (label_ref (match_operand 0 ""))
5742          (pc)))]
5743   "ISA_HAS_BBIT && UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
5745   return
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"
5754   [(set (pc)
5755         (if_then_else
5756          (equality_op (zero_extract:GPR
5757                        (match_operand:GPR 1 "register_operand" "d")
5758                        (const_int 1)
5759                        (match_operand 2 "const_int_operand" ""))
5760                       (const_int 0))
5761          (pc)
5762          (label_ref (match_operand 0 ""))))]
5763   "ISA_HAS_BBIT && UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
5765   return
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")]))]
5787   ""
5789   mips_expand_scc (operands);
5790   DONE;
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")
5796                  (const_int 0)))]
5797   "!TARGET_MIPS16 && !ISA_HAS_SEQ_SNE"
5798   "sltu\t%0,%1,1"
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")
5805                  (const_int 0)))]
5806   "TARGET_MIPS16 && !ISA_HAS_SEQ_SNE"
5807   "sltu\t%1,1"
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")))]
5816   "ISA_HAS_SEQ_SNE"
5817   "@
5818    seq\t%0,%1,%2
5819    sltiu\t%0,%1,1
5820    seqi\t%0,%1,%2"
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")
5827                  (const_int 0)))]
5828   "!TARGET_MIPS16 && !ISA_HAS_SEQ_SNE"
5829   "sltu\t%0,%.,%1"
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")))]
5838   "ISA_HAS_SEQ_SNE"
5839   "@
5840    sne\t%0,%1,%2
5841    sltu\t%0,%.,%1
5842    snei\t%0,%1,%2"
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")))]
5850   "!TARGET_MIPS16"
5851   "slt<u>\t%0,%z2,%1"
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")))]
5859   "TARGET_MIPS16"
5860   "slt<u>\t%2,%1"
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")
5867                      (const_int 1)))]
5868   "!TARGET_MIPS16"
5869   "slt<u>\t%0,%.,%1"
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")))]
5877   "!TARGET_MIPS16"
5878   "slt<u>\t%0,%1,%2"
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")))]
5886   "TARGET_MIPS16"
5887   "slt<u>\t%1,%2"
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" "")))]
5896   "!TARGET_MIPS16"
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")))]
5908   "TARGET_MIPS16"
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")))]
5928   ""
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")))]
5937   ""
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"
5952   [(set (pc)
5953         (label_ref (match_operand 0)))])
5955 (define_insn "*jump_absolute"
5956   [(set (pc)
5957         (label_ref (match_operand 0)))]
5958   "!TARGET_MIPS16 && TARGET_ABSOLUTE_JUMPS"
5960   if (get_attr_length (insn) <= 8)
5961     return "%*b\t%l0%/";
5962   else
5963     return MIPS_ABSOLUTE_JUMP ("%*j\t%l0%/");
5965   [(set_attr "type" "branch")])
5967 (define_insn "*jump_pic"
5968   [(set (pc)
5969         (label_ref (match_operand 0)))]
5970   "!TARGET_MIPS16 && !TARGET_ABSOLUTE_JUMPS"
5972   if (get_attr_length (insn) <= 8)
5973     return "%*b\t%l0%/";
5974   else
5975     {
5976       mips_output_load_label (operands[0]);
5977       return "%*jr\t%@%/%]";
5978     }
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"
5986   [(set (pc)
5987         (label_ref (match_operand 0 "" "")))]
5988   "TARGET_MIPS16"
5989   "b\t%l0"
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:
5995         ;;
5996         ;;    [-(0x800 - sizeof (branch)), 0x7fe]
5997         ;; == [-0x7fe, 0x7fe]
5998         ;;
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)))
6004                (const_int 2)
6005                (and (le (minus (match_dup 0) (pc)) (const_int 65534))
6006                     (le (minus (pc) (match_dup 0)) (const_int 65532)))
6007                (const_int 4)
6008                (and (match_test "TARGET_ABICALLS")
6009                     (not (match_test "TARGET_ABSOLUTE_ABICALLS")))
6010                (const_int 18)
6011                (match_test "Pmode == SImode")
6012                (const_int 14)
6013                ] (const_int 22)))])
6015 (define_expand "indirect_jump"
6016   [(set (pc) (match_operand 0 "register_operand"))]
6017   ""
6019   operands[0] = force_reg (Pmode, operands[0]);
6020   emit_jump_insn (PMODE_INSN (gen_indirect_jump, (operands[0])));
6021   DONE;
6024 (define_insn "indirect_jump_<mode>"
6025   [(set (pc) (match_operand:P 0 "register_operand" "d"))]
6026   ""
6028   if (TARGET_MICROMIPS)
6029     return "%*jr%:\t%0";
6030   else
6031     return "%*j\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"))]
6043   ""
6044   "%(%<jr\t%1\;move\t%0,%2%>%)"
6045   [(set_attr "type" "multi")
6046    (set_attr "extended_mips16" "yes")])
6048 (define_expand "tablejump"
6049   [(set (pc)
6050         (match_operand 0 "register_operand"))
6051    (use (label_ref (match_operand 1 "")))]
6052   "!TARGET_MIPS16_SHORT_JUMP_TABLES"
6054   if (TARGET_GPWORD)
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)
6058     {
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
6061          value we loaded.  */
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);
6065     }
6067   emit_jump_insn (PMODE_INSN (gen_tablejump, (operands[0], operands[1])));
6068   DONE;
6071 (define_insn "tablejump_<mode>"
6072   [(set (pc)
6073         (match_operand:P 0 "register_operand" "d"))
6074    (use (label_ref (match_operand 1 "" "")))]
6075   ""
6077   if (TARGET_MICROMIPS)
6078     return "%*jr%:\t%0";
6079   else
6080     return "%*j\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)
6102     {
6103       rtx reg = gen_reg_rtx (SImode);
6104       rtx offset = gen_int_mode (-INTVAL (operands[1]), SImode);
6105       
6106       if (!arith_operand (offset, SImode))
6107         offset = force_reg (SImode, offset);
6108       
6109       emit_insn (gen_addsi3 (reg, operands[0], offset));
6110       operands[0] = reg;
6111     }
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])));
6122   DONE;
6125 (define_insn "casesi_internal_mips16_<mode>"
6126   [(set (pc)
6127      (if_then_else
6128        (leu (match_operand:SI 0 "register_operand" "d")
6129             (match_operand:SI 1 "arith_operand" "dI"))
6130        (unspec:P
6131         [(match_dup 0)
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);
6143   
6144   output_asm_insn ("sltu\t%0, %1", operands);
6145   output_asm_insn ("bteqz\t%3", operands);
6146   
6147   switch (GET_MODE (diff_vec))
6148     {
6149     case HImode:
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);
6154       break;
6155     
6156     case SImode:
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);
6161       break;
6163     default:
6164       gcc_unreachable ();
6165     }
6166   
6167   output_asm_insn ("addu\t%4, %4, %5", operands);
6168   
6169   return "j\t%4";
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"))]
6180   "TARGET_USE_GOT"
6182   rtx addr;
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);
6186   DONE;
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"))]
6195   "TARGET_USE_GOT"
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);
6217   emit_use (gp);
6218   emit_indirect_jump (pv);
6219   DONE;
6223 ;;  ....................
6225 ;;      Function prologue/epilogue
6227 ;;  ....................
6230 (define_expand "prologue"
6231   [(const_int 1)]
6232   ""
6234   mips_expand_prologue ();
6235   DONE;
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)]
6244   ""
6245   ""
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))]
6254   ""
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"
6261   [(const_int 2)]
6262   ""
6264   mips_expand_epilogue (false);
6265   DONE;
6268 (define_expand "sibcall_epilogue"
6269   [(const_int 2)]
6270   ""
6272   mips_expand_epilogue (true);
6273   DONE;
6276 ;; Trivial return.  Make it look like a normal return insn as that
6277 ;; allows jump optimizations to work better.
6279 (define_expand "return"
6280   [(simple_return)]
6281   "mips_can_use_return_insn ()"
6282   { mips_expand_before_return (); })
6284 (define_expand "simple_return"
6285   [(simple_return)]
6286   ""
6287   { mips_expand_before_return (); })
6289 (define_insn "*<optab>"
6290   [(any_return)]
6291   ""
6292   {
6293     if (TARGET_MICROMIPS)
6294       return "%*jr%:\t$31";
6295     else
6296       return "%*j\t$31%/";
6297   }
6298   [(set_attr "type"     "jump")
6299    (set_attr "mode"     "none")])
6301 ;; Normal return.
6303 (define_insn "<optab>_internal"
6304   [(any_return)
6305    (use (match_operand 0 "pmode_register_operand" ""))]
6306   ""
6308   if (TARGET_MICROMIPS)
6309     return "%*jr%:\t%0";
6310   else
6311     return "%*j\t%0%/";
6313   [(set_attr "type"     "jump")
6314    (set_attr "mode"     "none")])
6316 ;; Exception return.
6317 (define_insn "mips_eret"
6318   [(return)
6319    (unspec_volatile [(const_int 0)] UNSPEC_ERET)]
6320   ""
6321   "eret"
6322   [(set_attr "type"     "trap")
6323    (set_attr "mode"     "none")])
6325 ;; Debug exception return.
6326 (define_insn "mips_deret"
6327   [(return)
6328    (unspec_volatile [(const_int 0)] UNSPEC_DERET)]
6329   ""
6330   "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)]
6337   ""
6338   "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)]
6345   ""
6346   "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")]
6354                             UNSPEC_RDPGPR))]
6355   ""
6356   "rdpgpr\t%0,%1"
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")]
6364                             UNSPEC_COP0))]
6365   ""
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"))]
6373   ""
6375   if (GET_MODE (operands[0]) != word_mode)
6376     operands[0] = convert_to_mode (word_mode, operands[0], 0);
6377   if (TARGET_64BIT)
6378     emit_insn (gen_eh_set_lr_di (operands[0]));
6379   else
6380     emit_insn (gen_eh_set_lr_si (operands[0]));
6381   DONE;
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"))]
6390   "! TARGET_64BIT"
6391   "#")
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"))]
6396   "TARGET_64BIT"
6397   "#")
6399 (define_split
6400   [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
6401    (clobber (match_scratch 1))]
6402   "reload_completed"
6403   [(const_int 0)]
6405   mips_set_return_address (operands[0], operands[1]);
6406   DONE;
6409 (define_expand "exception_receiver"
6410   [(const_int 0)]
6411   "TARGET_USE_GOT"
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 ());
6421   DONE;
6424 (define_expand "nonlocal_goto_receiver"
6425   [(const_int 0)]
6426   "TARGET_USE_GOT"
6428   /* See the comment above load_call<mode> for details.  */
6429   emit_insn (gen_set_got_version ());
6430   DONE;
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>"
6436   [(set (reg:P 28)
6437         (unspec_volatile:P [(const_int 0)] UNSPEC_RESTORE_GP))
6438    (clobber (match_scratch:P 0 "=&d"))]
6439   "TARGET_CALL_CLOBBERED_GP"
6440   "#"
6441   "&& epilogue_completed"
6442   [(const_int 0)]
6444   mips_restore_gp_from_cprestore_slot (operands[0]);
6445   DONE;
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")]
6453                     UNSPEC_MOVE_GP))]
6454   ""
6455   { return mips_must_initialize_gp_p () ? "#" : ""; }
6456   "mips_must_initialize_gp_p ()"
6457   [(const_int 0)]
6459   mips_emit_move (operands[0], operands[1]);
6460   DONE;
6462   [(set_attr "type" "ghost")])
6465 ;;  ....................
6467 ;;      FUNCTION CALLS
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
6475 ;; address.
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))]
6520   "TARGET_USE_GOT"
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))]
6528   "TARGET_USE_GOT"
6529   ""
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))]
6535   "TARGET_USE_GOT"
6536   ""
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
6544 ;; constraints.
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
6550 ;; as well.
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
6557   "TARGET_SIBCALLS"
6559   mips_expand_call (MIPS_CALL_SIBCALL, NULL_RTX, XEXP (operands[0], 0),
6560                     operands[1], operands[2], false);
6561   DONE;
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);
6571   else
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
6582   "TARGET_SIBCALLS"
6584   mips_expand_call (MIPS_CALL_SIBCALL, operands[0], XEXP (operands[1], 0),
6585                     operands[2], operands[3], false);
6586   DONE;
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);
6597   else
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))
6609               (match_dup 2)))]
6610   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6612   if (TARGET_MICROMIPS)
6613     return MICROMIPS_J ("j", operands, 1);
6614   else
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
6625   ""
6627   mips_expand_call (MIPS_CALL_NORMAL, NULL_RTX, XEXP (operands[0], 0),
6628                     operands[1], operands[2], false);
6629   DONE;
6632 ;; This instruction directly corresponds to an assembly-language "jal".
6633 ;; There are four cases:
6635 ;;    - -mno-abicalls:
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"
6645 ;;        instruction.
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))]
6671   ""
6672   { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 0, 1); }
6673   "reload_completed && TARGET_SPLIT_CALLS"
6674   [(const_int 0)]
6676   mips_split_call (curr_insn, gen_call_split (operands[0], operands[1]));
6677   DONE;
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"))
6697          (match_operand 1))
6698    (const_int 1)
6699    (clobber (reg:SI RETURN_ADDR_REGNUM))]
6700   ""
6701   { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 0, -1); }
6702   "reload_completed && TARGET_SPLIT_CALLS"
6703   [(const_int 0)]
6705   mips_split_call (curr_insn,
6706                    gen_call_direct_split (operands[0], operands[1]));
6707   DONE;
6709   [(set_attr "jal" "direct")])
6711 (define_insn "call_direct_split"
6712   [(call (mem:SI (match_operand 0 "const_call_insn_operand"))
6713          (match_operand 1))
6714    (const_int 1)
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
6727   ""
6729   mips_expand_call (MIPS_CALL_NORMAL, operands[0], XEXP (operands[1], 0),
6730                     operands[2], operands[3], false);
6731   DONE;
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))]
6740   ""
6741   { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1, 2); }
6742   "reload_completed && TARGET_SPLIT_CALLS"
6743   [(const_int 0)]
6745   mips_split_call (curr_insn,
6746                    gen_call_value_split (operands[0], operands[1],
6747                                          operands[2]));
6748   DONE;
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"))
6767               (match_operand 2)))
6768    (const_int 1)
6769    (clobber (reg:SI RETURN_ADDR_REGNUM))]
6770   ""
6771   { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1, -1); }
6772   "reload_completed && TARGET_SPLIT_CALLS"
6773   [(const_int 0)]
6775   mips_split_call (curr_insn,
6776                    gen_call_value_direct_split (operands[0], operands[1],
6777                                                 operands[2]));
6778   DONE;
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"))
6785               (match_operand 2)))
6786    (const_int 1)
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))
6801               (match_dup 2)))
6802    (clobber (reg:SI RETURN_ADDR_REGNUM))]
6803   ""
6804   { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1, 2); }
6805   "reload_completed && TARGET_SPLIT_CALLS"
6806   [(const_int 0)]
6808   mips_split_call (curr_insn,
6809                    gen_call_value_multiple_split (operands[0], operands[1],
6810                                                   operands[2], operands[3]));
6811   DONE;
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))
6821               (match_dup 2)))
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 "")
6833                     (const_int 0))
6834               (match_operand 1 "")
6835               (match_operand 2 "")])]
6836   ""
6838   int i;
6840   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
6842   for (i = 0; i < XVECLEN (operands[2], 0); i++)
6843     {
6844       rtx set = XVECEXP (operands[2], 0, i);
6845       mips_emit_move (SET_DEST (set), SET_SRC (set));
6846     }
6848   emit_insn (gen_blockage ());
6849   DONE;
6853 ;;  ....................
6855 ;;      MISC.
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)
6868     {
6869       /* Loongson 2[ef] and Loongson 3a use load to $0 for prefetching.  */
6870       if (TARGET_64BIT)
6871         return "ld\t$0,%a0";
6872       else
6873         return "lw\t$0,%a0";
6874     }
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")])
6892 (define_insn "nop"
6893   [(const_int 0)]
6894   ""
6895   "%(nop%)"
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"
6901   [(const_int 1)]
6902   ""
6903   {
6904     if (mips_noreorder.nesting_level > 0)
6905       return "nop";
6906     else
6907       return "#nop";
6908   }
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")
6915         (if_then_else:GPR
6916          (match_operator 4 "equality_operator"
6917                 [(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>")
6918                  (const_int 0)])
6919          (match_operand:GPR 2 "reg_or_0_operand" "dJ,0")
6920          (match_operand:GPR 3 "reg_or_0_operand" "0,dJ")))]
6921   "ISA_HAS_CONDMOVE"
6922   "@
6923     mov%T4\t%0,%z2,%1
6924     mov%t4\t%0,%z3,%1"
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")
6930        (if_then_else:GPR
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")))]
6934   "ISA_HAS_CONDMOVE"
6935   "@
6936     movn\t%0,%z2,%1
6937     movz\t%0,%z3,%1"
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>")
6946                  (const_int 0)])
6947          (match_operand:SCALARF 2 "register_operand" "f,0")
6948          (match_operand:SCALARF 3 "register_operand" "0,f")))]
6949   "ISA_HAS_FP_CONDMOVE"
6950   "@
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")))]
6964   "ISA_HAS_CONDMOVE"
6966   mips_expand_conditional_move (operands);
6967   DONE;
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);
6979   DONE;
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)]
7002   "TARGET_MIPS16"
7004   assemble_integer (mips_strip_unspec_address (operands[0]),
7005                     INTVAL (operands[1]),
7006                     BITS_PER_UNIT * INTVAL (operands[1]), 1);
7007   return "";
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)]
7014   "TARGET_MIPS16"
7016   REAL_VALUE_TYPE d;
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])));
7022   return "";
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)]
7029   ""
7030   ".align\t%0"
7031   [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))])
7033 (define_split
7034   [(match_operand 0 "small_data_pattern")]
7035   "reload_completed"
7036   [(match_dup 0)]
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
7066 ;; accept it.
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"
7078   "#"
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))]
7083   ""
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")]
7113                   UNSPEC_TLS_GET_TP))
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"
7118   "#"
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))]
7125   ""
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")]
7133                   UNSPEC_TLS_GET_TP))
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")]
7145   "HAVE_AS_TLS"
7147   mips_expand_thread_pointer (operands[0]);
7148   DONE;
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"
7157   if (TARGET_MIPS16)
7158     {
7159       mips16_expand_get_fcsr (operands[0]);
7160       DONE;
7161     }
7164 (define_insn "*mips_get_fcsr"
7165   [(set (match_operand:SI 0 "register_operand" "=d")
7166         (unspec_volatile [(const_int 0)] UNSPEC_GET_FCSR))]
7167   "TARGET_HARD_FLOAT"
7168   "cfc1\t%0,$31")
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")]
7174                    UNSPEC_GET_FCSR))
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")]
7185                     UNSPEC_SET_FCSR)]
7186   "TARGET_HARD_FLOAT_ABI"
7188   if (TARGET_MIPS16)
7189     {
7190       mips16_expand_set_fcsr (operands[0]);
7191       DONE;
7192     }
7195 (define_insn "*mips_set_fcsr"
7196   [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")]
7197                     UNSPEC_SET_FCSR)]
7198   "TARGET_HARD_FLOAT"
7199   "ctc1\t%0,$31")
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.
7214 (include "sync.md")
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