2014-04-16 Catherine Moore <clm@codesourcery.com>
[official-gcc.git] / gcc / config / mips / mips.md
blobf914ab67d8aac60bb6504321ce24c7bc7e7c4459
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   r3900
45   r6000
46   r4000
47   r4100
48   r4111
49   r4120
50   r4130
51   r4300
52   r4600
53   r4650
54   r4700
55   r5000
56   r5400
57   r5500
58   r5900
59   r7000
60   r8000
61   r9000
62   r10000
63   sb1
64   sb1a
65   sr71000
66   xlr
67   xlp
70 (define_c_enum "unspec" [
71   ;; Unaligned accesses.
72   UNSPEC_LOAD_LEFT
73   UNSPEC_LOAD_RIGHT
74   UNSPEC_STORE_LEFT
75   UNSPEC_STORE_RIGHT
77   ;; Integer operations that are too cumbersome to describe directly.
78   UNSPEC_WSBH
79   UNSPEC_DSBH
80   UNSPEC_DSHD
82   ;; Floating-point moves.
83   UNSPEC_LOAD_LOW
84   UNSPEC_LOAD_HIGH
85   UNSPEC_STORE_WORD
86   UNSPEC_MFHC1
87   UNSPEC_MTHC1
89   ;; Floating-point environment.
90   UNSPEC_GET_FCSR
91   UNSPEC_SET_FCSR
93   ;; HI/LO moves.
94   UNSPEC_MFHI
95   UNSPEC_MTHI
96   UNSPEC_SET_HILO
98   ;; GP manipulation.
99   UNSPEC_LOADGP
100   UNSPEC_COPYGP
101   UNSPEC_MOVE_GP
102   UNSPEC_POTENTIAL_CPRESTORE
103   UNSPEC_CPRESTORE
104   UNSPEC_RESTORE_GP
105   UNSPEC_EH_RETURN
106   UNSPEC_GP
107   UNSPEC_SET_GOT_VERSION
108   UNSPEC_UPDATE_GOT_VERSION
110   ;; Symbolic accesses.
111   UNSPEC_LOAD_CALL
112   UNSPEC_LOAD_GOT
113   UNSPEC_TLS_LDM
114   UNSPEC_TLS_GET_TP
115   UNSPEC_UNSHIFTED_HIGH
117   ;; MIPS16 constant pools.
118   UNSPEC_ALIGN
119   UNSPEC_CONSTTABLE_INT
120   UNSPEC_CONSTTABLE_FLOAT
122   ;; Blockage and synchronisation.
123   UNSPEC_BLOCKAGE
124   UNSPEC_CLEAR_HAZARD
125   UNSPEC_RDHWR
126   UNSPEC_SYNCI
127   UNSPEC_SYNC
129   ;; Cache manipulation.
130   UNSPEC_MIPS_CACHE
131   UNSPEC_R10K_CACHE_BARRIER
133   ;; Interrupt handling.
134   UNSPEC_ERET
135   UNSPEC_DERET
136   UNSPEC_DI
137   UNSPEC_EHB
138   UNSPEC_RDPGPR
139   UNSPEC_COP0
141   ;; Used in a call expression in place of args_size.  It's present for PIC
142   ;; indirect calls where it contains args_size and the function symbol.
143   UNSPEC_CALL_ATTR
145   ;; MIPS16 casesi jump table dispatch.
146   UNSPEC_CASESI_DISPATCH
148   ;; Stack checking.
149   UNSPEC_PROBE_STACK_RANGE
152 (define_constants
153   [(TLS_GET_TP_REGNUM           3)
154    (GET_FCSR_REGNUM             2)
155    (SET_FCSR_REGNUM             4)
156    (MIPS16_T_REGNUM             24)
157    (PIC_FUNCTION_ADDR_REGNUM    25)
158    (RETURN_ADDR_REGNUM          31)
159    (CPRESTORE_SLOT_REGNUM       76)
160    (GOT_VERSION_REGNUM          79)
162    ;; PIC long branch sequences are never longer than 100 bytes.
163    (MAX_PIC_BRANCH_LENGTH       100)
164   ]
167 (include "predicates.md")
168 (include "constraints.md")
170 ;; ....................
172 ;;      Attributes
174 ;; ....................
176 (define_attr "got" "unset,xgot_high,load"
177   (const_string "unset"))
179 ;; For jal instructions, this attribute is DIRECT when the target address
180 ;; is symbolic and INDIRECT when it is a register.
181 (define_attr "jal" "unset,direct,indirect"
182   (const_string "unset"))
184 ;; This attribute is YES if the instruction is a jal macro (not a
185 ;; real jal instruction).
187 ;; jal is always a macro for TARGET_CALL_CLOBBERED_GP because it includes
188 ;; an instruction to restore $gp.  Direct jals are also macros for
189 ;; !TARGET_ABSOLUTE_JUMPS because they first load the target address
190 ;; into a register.
191 (define_attr "jal_macro" "no,yes"
192   (cond [(eq_attr "jal" "direct")
193          (symbol_ref "(TARGET_CALL_CLOBBERED_GP || !TARGET_ABSOLUTE_JUMPS
194                        ? JAL_MACRO_YES : JAL_MACRO_NO)")
195          (eq_attr "jal" "indirect")
196          (symbol_ref "(TARGET_CALL_CLOBBERED_GP
197                        ? JAL_MACRO_YES : JAL_MACRO_NO)")]
198         (const_string "no")))
200 ;; Classification of moves, extensions and truncations.  Most values
201 ;; are as for "type" (see below) but there are also the following
202 ;; move-specific values:
204 ;; constN       move an N-constraint integer into a MIPS16 register
205 ;; sll0         "sll DEST,SRC,0", which on 64-bit targets is guaranteed
206 ;;              to produce a sign-extended DEST, even if SRC is not
207 ;;              properly sign-extended
208 ;; ext_ins      EXT, DEXT, INS or DINS instruction
209 ;; andi         a single ANDI instruction
210 ;; loadpool     move a constant into a MIPS16 register by loading it
211 ;;              from the pool
212 ;; shift_shift  a shift left followed by a shift right
214 ;; This attribute is used to determine the instruction's length and
215 ;; scheduling type.  For doubleword moves, the attribute always describes
216 ;; the split instructions; in some cases, it is more appropriate for the
217 ;; scheduling type to be "multi" instead.
218 (define_attr "move_type"
219   "unknown,load,fpload,store,fpstore,mtc,mfc,mtlo,mflo,imul,move,fmove,
220    const,constN,signext,ext_ins,logical,arith,sll0,andi,loadpool,
221    shift_shift"
222   (const_string "unknown"))
224 (define_attr "alu_type" "unknown,add,sub,not,nor,and,or,xor"
225   (const_string "unknown"))
227 ;; Main data type used by the insn
228 (define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF,FPSW"
229   (const_string "unknown"))
231 ;; True if the main data type is twice the size of a word.
232 (define_attr "dword_mode" "no,yes"
233   (cond [(and (eq_attr "mode" "DI,DF")
234               (not (match_test "TARGET_64BIT")))
235          (const_string "yes")
237          (and (eq_attr "mode" "TI,TF")
238               (match_test "TARGET_64BIT"))
239          (const_string "yes")]
240         (const_string "no")))
242 ;; Attributes describing a sync loop.  These loops have the form:
244 ;;       if (RELEASE_BARRIER == YES) sync
245 ;;    1: OLDVAL = *MEM
246 ;;       if ((OLDVAL & INCLUSIVE_MASK) != REQUIRED_OLDVAL) goto 2
247 ;;         CMP  = 0 [delay slot]
248 ;;       $TMP1 = OLDVAL & EXCLUSIVE_MASK
249 ;;       $TMP2 = INSN1 (OLDVAL, INSN1_OP2)
250 ;;       $TMP3 = INSN2 ($TMP2, INCLUSIVE_MASK)
251 ;;       $AT |= $TMP1 | $TMP3
252 ;;       if (!commit (*MEM = $AT)) goto 1.
253 ;;         if (INSN1 != MOVE && INSN1 != LI) NEWVAL = $TMP3 [delay slot]
254 ;;       CMP  = 1
255 ;;       if (ACQUIRE_BARRIER == YES) sync
256 ;;    2:
258 ;; where "$" values are temporaries and where the other values are
259 ;; specified by the attributes below.  Values are specified as operand
260 ;; numbers and insns are specified as enums.  If no operand number is
261 ;; specified, the following values are used instead:
263 ;;    - OLDVAL: $AT
264 ;;    - CMP: NONE
265 ;;    - NEWVAL: $AT
266 ;;    - INCLUSIVE_MASK: -1
267 ;;    - REQUIRED_OLDVAL: OLDVAL & INCLUSIVE_MASK
268 ;;    - EXCLUSIVE_MASK: 0
270 ;; MEM and INSN1_OP2 are required.
272 ;; Ideally, the operand attributes would be integers, with -1 meaning "none",
273 ;; but the gen* programs don't yet support that.
274 (define_attr "sync_mem" "none,0,1,2,3,4,5" (const_string "none"))
275 (define_attr "sync_oldval" "none,0,1,2,3,4,5" (const_string "none"))
276 (define_attr "sync_cmp" "none,0,1,2,3,4,5" (const_string "none"))
277 (define_attr "sync_newval" "none,0,1,2,3,4,5" (const_string "none"))
278 (define_attr "sync_inclusive_mask" "none,0,1,2,3,4,5" (const_string "none"))
279 (define_attr "sync_exclusive_mask" "none,0,1,2,3,4,5" (const_string "none"))
280 (define_attr "sync_required_oldval" "none,0,1,2,3,4,5" (const_string "none"))
281 (define_attr "sync_insn1_op2" "none,0,1,2,3,4,5" (const_string "none"))
282 (define_attr "sync_insn1" "move,li,addu,addiu,subu,and,andi,or,ori,xor,xori"
283   (const_string "move"))
284 (define_attr "sync_insn2" "nop,and,xor,not"
285   (const_string "nop"))
286 ;; Memory model specifier.
287 ;; "0"-"9" values specify the operand that stores the memory model value.
288 ;; "10" specifies MEMMODEL_ACQ_REL,
289 ;; "11" specifies MEMMODEL_ACQUIRE.
290 (define_attr "sync_memmodel" "" (const_int 10))
292 ;; Accumulator operand for madd patterns.
293 (define_attr "accum_in" "none,0,1,2,3,4,5" (const_string "none"))
295 ;; Classification of each insn.
296 ;; branch       conditional branch
297 ;; jump         unconditional jump
298 ;; call         unconditional call
299 ;; load         load instruction(s)
300 ;; fpload       floating point load
301 ;; fpidxload    floating point indexed load
302 ;; store        store instruction(s)
303 ;; fpstore      floating point store
304 ;; fpidxstore   floating point indexed store
305 ;; prefetch     memory prefetch (register + offset)
306 ;; prefetchx    memory indexed prefetch (register + register)
307 ;; condmove     conditional moves
308 ;; mtc          transfer to coprocessor
309 ;; mfc          transfer from coprocessor
310 ;; mthi         transfer to a hi register
311 ;; mtlo         transfer to a lo register
312 ;; mfhi         transfer from a hi register
313 ;; mflo         transfer from a lo register
314 ;; const        load constant
315 ;; arith        integer arithmetic instructions
316 ;; logical      integer logical instructions
317 ;; shift        integer shift instructions
318 ;; slt          set less than instructions
319 ;; signext      sign extend instructions
320 ;; clz          the clz and clo instructions
321 ;; pop          the pop instruction
322 ;; trap         trap if instructions
323 ;; imul         integer multiply 2 operands
324 ;; imul3        integer multiply 3 operands
325 ;; imul3nc      integer multiply 3 operands without clobbering HI/LO
326 ;; imadd        integer multiply-add
327 ;; idiv         integer divide 2 operands
328 ;; idiv3        integer divide 3 operands
329 ;; move         integer register move ({,D}ADD{,U} with rt = 0)
330 ;; fmove        floating point register move
331 ;; fadd         floating point add/subtract
332 ;; fmul         floating point multiply
333 ;; fmadd        floating point multiply-add
334 ;; fdiv         floating point divide
335 ;; frdiv        floating point reciprocal divide
336 ;; frdiv1       floating point reciprocal divide step 1
337 ;; frdiv2       floating point reciprocal divide step 2
338 ;; fabs         floating point absolute value
339 ;; fneg         floating point negation
340 ;; fcmp         floating point compare
341 ;; fcvt         floating point convert
342 ;; fsqrt        floating point square root
343 ;; frsqrt       floating point reciprocal square root
344 ;; frsqrt1      floating point reciprocal square root step1
345 ;; frsqrt2      floating point reciprocal square root step2
346 ;; dspmac       DSP MAC instructions not saturating the accumulator
347 ;; dspmacsat    DSP MAC instructions that saturate the accumulator
348 ;; accext       DSP accumulator extract instructions
349 ;; accmod       DSP accumulator modify instructions
350 ;; dspalu       DSP ALU instructions not saturating the result
351 ;; dspalusat    DSP ALU instructions that saturate the result
352 ;; multi        multiword sequence (or user asm statements)
353 ;; atomic       atomic memory update instruction
354 ;; syncloop     memory atomic operation implemented as a sync loop
355 ;; nop          no operation
356 ;; ghost        an instruction that produces no real code
357 ;; multimem     microMIPS multiword load and store
358 (define_attr "type"
359   "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,
360    prefetch,prefetchx,condmove,mtc,mfc,mthi,mtlo,mfhi,mflo,const,arith,logical,
361    shift,slt,signext,clz,pop,trap,imul,imul3,imul3nc,imadd,idiv,idiv3,move,
362    fmove,fadd,fmul,fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt,
363    frsqrt,frsqrt1,frsqrt2,dspmac,dspmacsat,accext,accmod,dspalu,dspalusat,
364    multi,atomic,syncloop,nop,ghost,multimem"
365   (cond [(eq_attr "jal" "!unset") (const_string "call")
366          (eq_attr "got" "load") (const_string "load")
368          (eq_attr "alu_type" "add,sub") (const_string "arith")
370          (eq_attr "alu_type" "not,nor,and,or,xor") (const_string "logical")
372          ;; If a doubleword move uses these expensive instructions,
373          ;; it is usually better to schedule them in the same way
374          ;; as the singleword form, rather than as "multi".
375          (eq_attr "move_type" "load") (const_string "load")
376          (eq_attr "move_type" "fpload") (const_string "fpload")
377          (eq_attr "move_type" "store") (const_string "store")
378          (eq_attr "move_type" "fpstore") (const_string "fpstore")
379          (eq_attr "move_type" "mtc") (const_string "mtc")
380          (eq_attr "move_type" "mfc") (const_string "mfc")
381          (eq_attr "move_type" "mtlo") (const_string "mtlo")
382          (eq_attr "move_type" "mflo") (const_string "mflo")
384          ;; These types of move are always single insns.
385          (eq_attr "move_type" "imul") (const_string "imul")
386          (eq_attr "move_type" "fmove") (const_string "fmove")
387          (eq_attr "move_type" "loadpool") (const_string "load")
388          (eq_attr "move_type" "signext") (const_string "signext")
389          (eq_attr "move_type" "ext_ins") (const_string "arith")
390          (eq_attr "move_type" "arith") (const_string "arith")
391          (eq_attr "move_type" "logical") (const_string "logical")
392          (eq_attr "move_type" "sll0") (const_string "shift")
393          (eq_attr "move_type" "andi") (const_string "logical")
395          ;; These types of move are always split.
396          (eq_attr "move_type" "constN,shift_shift")
397            (const_string "multi")
399          ;; These types of move are split for doubleword modes only.
400          (and (eq_attr "move_type" "move,const")
401               (eq_attr "dword_mode" "yes"))
402            (const_string "multi")
403          (eq_attr "move_type" "move") (const_string "move")
404          (eq_attr "move_type" "const") (const_string "const")
405          (eq_attr "sync_mem" "!none") (const_string "syncloop")]
406         (const_string "unknown")))
408 ;; Mode for conversion types (fcvt)
409 ;; I2S          integer to float single (SI/DI to SF)
410 ;; I2D          integer to float double (SI/DI to DF)
411 ;; S2I          float to integer (SF to SI/DI)
412 ;; D2I          float to integer (DF to SI/DI)
413 ;; D2S          double to float single
414 ;; S2D          float single to double
416 (define_attr "cnv_mode" "unknown,I2S,I2D,S2I,D2I,D2S,S2D" 
417   (const_string "unknown"))
419 ;; Is this an extended instruction in mips16 mode?
420 (define_attr "extended_mips16" "no,yes"
421   (if_then_else (ior ;; In general, constant-pool loads are extended
422                      ;; instructions.  We don't yet optimize for 16-bit
423                      ;; PC-relative references.
424                      (eq_attr "move_type" "sll0,loadpool")
425                      (eq_attr "jal" "direct")
426                      (eq_attr "got" "load"))
427                 (const_string "yes")
428                 (const_string "no")))
430 (define_attr "compression" "none,all,micromips"
431   (const_string "none"))
433 (define_attr "enabled" "no,yes"
434   (if_then_else (ior (eq_attr "compression" "all,none")
435                      (and (eq_attr "compression" "micromips")
436                           (match_test "TARGET_MICROMIPS")))
437                 (const_string "yes")
438                 (const_string "no")))
440 ;; The number of individual instructions that a non-branch pattern generates,
441 ;; using units of BASE_INSN_LENGTH.
442 (define_attr "insn_count" ""
443   (cond [;; "Ghost" instructions occupy no space.
444          (eq_attr "type" "ghost")
445          (const_int 0)
447          ;; Extended instructions count as 2.
448          (and (eq_attr "extended_mips16" "yes")
449               (match_test "TARGET_MIPS16"))
450          (const_int 2)
452          ;; A GOT load followed by an add of $gp.  This is not used for MIPS16.
453          (eq_attr "got" "xgot_high")
454          (const_int 2)
456          ;; SHIFT_SHIFTs are decomposed into two separate instructions.
457          ;; They are extended instructions on MIPS16 targets.
458          (eq_attr "move_type" "shift_shift")
459          (if_then_else (match_test "TARGET_MIPS16")
460                        (const_int 4)
461                        (const_int 2))
463          ;; Check for doubleword moves that are decomposed into two
464          ;; instructions.  The individual instructions are unextended
465          ;; MIPS16 ones.
466          (and (eq_attr "move_type" "mtc,mfc,mtlo,mflo,move")
467               (eq_attr "dword_mode" "yes"))
468          (const_int 2)
470          ;; Constants, loads and stores are handled by external routines.
471          (and (eq_attr "move_type" "const,constN")
472               (eq_attr "dword_mode" "yes"))
473          (symbol_ref "mips_split_const_insns (operands[1])")
474          (eq_attr "move_type" "const,constN")
475          (symbol_ref "mips_const_insns (operands[1])")
476          (eq_attr "move_type" "load,fpload")
477          (symbol_ref "mips_load_store_insns (operands[1], insn)")
478          (eq_attr "move_type" "store,fpstore")
479          (symbol_ref "mips_load_store_insns (operands[0], insn)
480                       + (TARGET_FIX_24K ? 1 : 0)")
482          ;; In the worst case, a call macro will take 8 instructions:
483          ;;
484          ;;     lui $25,%call_hi(FOO)
485          ;;     addu $25,$25,$28
486          ;;     lw $25,%call_lo(FOO)($25)
487          ;;     nop
488          ;;     jalr $25
489          ;;     nop
490          ;;     lw $gp,X($sp)
491          ;;     nop
492          (eq_attr "jal_macro" "yes")
493          (const_int 8)
495          ;; Various VR4120 errata require a nop to be inserted after a macc
496          ;; instruction.  The assembler does this for us, so account for
497          ;; the worst-case length here.
498          (and (eq_attr "type" "imadd")
499               (match_test "TARGET_FIX_VR4120"))
500          (const_int 2)
502          ;; VR4120 errata MD(4): if there are consecutive dmult instructions,
503          ;; the result of the second one is missed.  The assembler should work
504          ;; around this by inserting a nop after the first dmult.
505          (and (eq_attr "type" "imul,imul3")
506               (eq_attr "mode" "DI")
507               (match_test "TARGET_FIX_VR4120"))
508          (const_int 2)
510          (eq_attr "type" "idiv,idiv3")
511          (symbol_ref "mips_idiv_insns ()")
513          (not (eq_attr "sync_mem" "none"))
514          (symbol_ref "mips_sync_loop_insns (insn, operands)")]
515         (const_int 1)))
517 ;; Length of instruction in bytes.  The default is derived from "insn_count",
518 ;; but there are special cases for branches (which must be handled here)
519 ;; and for compressed single instructions.
520 (define_attr "length" ""
521    (cond [(and (eq_attr "compression" "micromips,all")
522                (eq_attr "dword_mode" "no")
523                (match_test "TARGET_MICROMIPS"))
524           (const_int 2)
526           ;; Direct microMIPS branch instructions have a range of
527           ;; [-0x10000,0xfffe], otherwise the range is [-0x20000,0x1fffc].
528           ;; If a branch is outside this range, we have a choice of two
529           ;; sequences.
530           ;;
531           ;; For PIC, an out-of-range branch like:
532           ;;
533           ;;    bne     r1,r2,target
534           ;;    dslot
535           ;;
536           ;; becomes the equivalent of:
537           ;;
538           ;;    beq     r1,r2,1f
539           ;;    dslot
540           ;;    la      $at,target
541           ;;    jr      $at
542           ;;    nop
543           ;; 1:
544           ;;
545           ;; The non-PIC case is similar except that we use a direct
546           ;; jump instead of an la/jr pair.  Since the target of this
547           ;; jump is an absolute 28-bit bit address (the other bits
548           ;; coming from the address of the delay slot) this form cannot
549           ;; cross a 256MB boundary.  We could provide the option of
550           ;; using la/jr in this case too, but we do not do so at
551           ;; present.
552           ;;
553           ;; The value we specify here does not account for the delay slot
554           ;; instruction, whose length is added separately.  If the RTL
555           ;; pattern has no explicit delay slot, mips_adjust_insn_length
556           ;; will add the length of the implicit nop.  The range of
557           ;; [-0x20000, 0x1fffc] from the address of the delay slot
558           ;; therefore translates to a range of:
559           ;;
560           ;;    [-(0x20000 - sizeof (branch)), 0x1fffc - sizeof (slot)]
561           ;; == [-0x1fffc, 0x1fff8]
562           ;;
563           ;; from the shorten_branches reference address.
564           (and (eq_attr "type" "branch")
565                (not (match_test "TARGET_MIPS16")))
566           (cond [;; Any variant can handle the 17-bit range.
567                  (and (le (minus (match_dup 0) (pc)) (const_int 65532))
568                       (le (minus (pc) (match_dup 0)) (const_int 65534)))
569                    (const_int 4)
571                  ;; The 18-bit range is OK other than for microMIPS.
572                  (and (not (match_test "TARGET_MICROMIPS"))
573                       (and (le (minus (match_dup 0) (pc)) (const_int 131064))
574                            (le (minus (pc) (match_dup 0)) (const_int 131068))))
575                    (const_int 4)
577                  ;; The non-PIC case: branch, first delay slot, and J.
578                  (match_test "TARGET_ABSOLUTE_JUMPS")
579                    (const_int 12)]
581                  ;; Use MAX_PIC_BRANCH_LENGTH as a (gross) overestimate.
582                  ;; mips_adjust_insn_length substitutes the correct length.
583                  ;;
584                  ;; Note that we can't simply use (symbol_ref ...) here
585                  ;; because genattrtab needs to know the maximum length
586                  ;; of an insn.
587                  (const_int MAX_PIC_BRANCH_LENGTH))
589           ;; An unextended MIPS16 branch has a range of [-0x100, 0xfe]
590           ;; from the address of the following instruction, which leads
591           ;; to a range of:
592           ;;
593           ;;    [-(0x100 - sizeof (branch)), 0xfe]
594           ;; == [-0xfe, 0xfe]
595           ;;
596           ;; from the shorten_branches reference address.  Extended branches
597           ;; likewise have a range of [-0x10000, 0xfffe] from the address
598           ;; of the following instruction, which leads to a range of:
599           ;;
600           ;;    [-(0x10000 - sizeof (branch)), 0xfffe]
601           ;; == [-0xfffc, 0xfffe]
602           ;;
603           ;; from the reference address.
604           ;;
605           ;; When a branch is out of range, mips_reorg splits it into a form
606           ;; that uses in-range branches.  There are four basic sequences:
607           ;;
608           ;; (1) Absolute addressing with a readable text segment
609           ;;     (32-bit addresses):
610           ;;
611           ;;     b... foo               2 bytes
612           ;;     move $1,$2             2 bytes
613           ;;     lw $2,label            2 bytes
614           ;;     jr $2                  2 bytes
615           ;;     move $2,$1             2 bytes
616           ;;     .align 2               0 or 2 bytes
617           ;; label:
618           ;;     .word target           4 bytes
619           ;; foo:
620           ;;                            (16 bytes in the worst case)
621           ;;
622           ;; (2) Absolute addressing with a readable text segment
623           ;;     (64-bit addresses):
624           ;;
625           ;;     b... foo               2 bytes
626           ;;     move $1,$2             2 bytes
627           ;;     ld $2,label            2 bytes
628           ;;     jr $2                  2 bytes
629           ;;     move $2,$1             2 bytes
630           ;;     .align 3               0 to 6 bytes
631           ;; label:
632           ;;     .dword target          8 bytes
633           ;; foo:
634           ;;                            (24 bytes in the worst case)
635           ;;
636           ;; (3) Absolute addressing without a readable text segment
637           ;;     (which requires 32-bit addresses at present):
638           ;;
639           ;;     b... foo               2 bytes
640           ;;     move $1,$2             2 bytes
641           ;;     lui $2,%hi(target)     4 bytes
642           ;;     sll $2,8               2 bytes
643           ;;     sll $2,8               2 bytes
644           ;;     addiu $2,%lo(target)   4 bytes
645           ;;     jr $2                  2 bytes
646           ;;     move $2,$1             2 bytes
647           ;; foo:
648           ;;                            (20 bytes)
649           ;;
650           ;; (4) PIC addressing (which requires 32-bit addresses at present):
651           ;;
652           ;;     b... foo               2 bytes
653           ;;     move $1,$2             2 bytes
654           ;;     lw $2,cprestore        0, 2 or 4 bytes
655           ;;     lw $2,%got(target)($2) 4 bytes
656           ;;     addiu $2,%lo(target)   4 bytes
657           ;;     jr $2                  2 bytes
658           ;;     move $2,$1             2 bytes
659           ;; foo:
660           ;;                            (20 bytes in the worst case)
661           (and (eq_attr "type" "branch")
662                (match_test "TARGET_MIPS16"))
663           (cond [(and (le (minus (match_dup 0) (pc)) (const_int 254))
664                       (le (minus (pc) (match_dup 0)) (const_int 254)))
665                  (const_int 2)
666                  (and (le (minus (match_dup 0) (pc)) (const_int 65534))
667                       (le (minus (pc) (match_dup 0)) (const_int 65532)))
668                  (const_int 4)
669                  (and (match_test "TARGET_ABICALLS")
670                       (not (match_test "TARGET_ABSOLUTE_ABICALLS")))
671                  (const_int 20)
672                  (match_test "Pmode == SImode")
673                  (const_int 16)
674                  ] (const_int 24))]
675          (symbol_ref "get_attr_insn_count (insn) * BASE_INSN_LENGTH")))
677 ;; Attribute describing the processor.
678 (define_enum_attr "cpu" "processor"
679   (const (symbol_ref "mips_tune")))
681 ;; The type of hardware hazard associated with this instruction.
682 ;; DELAY means that the next instruction cannot read the result
683 ;; of this one.  HILO means that the next two instructions cannot
684 ;; write to HI or LO.
685 (define_attr "hazard" "none,delay,hilo"
686   (cond [(and (eq_attr "type" "load,fpload,fpidxload")
687               (match_test "ISA_HAS_LOAD_DELAY"))
688          (const_string "delay")
690          (and (eq_attr "type" "mfc,mtc")
691               (match_test "ISA_HAS_XFER_DELAY"))
692          (const_string "delay")
694          (and (eq_attr "type" "fcmp")
695               (match_test "ISA_HAS_FCMP_DELAY"))
696          (const_string "delay")
698          ;; The r4000 multiplication patterns include an mflo instruction.
699          (and (eq_attr "type" "imul")
700               (match_test "TARGET_FIX_R4000"))
701          (const_string "hilo")
703          (and (eq_attr "type" "mfhi,mflo")
704               (not (match_test "ISA_HAS_HILO_INTERLOCKS")))
705          (const_string "hilo")]
706         (const_string "none")))
708 ;; Can the instruction be put into a delay slot?
709 (define_attr "can_delay" "no,yes"
710   (if_then_else (and (eq_attr "type" "!branch,call,jump")
711                      (eq_attr "hazard" "none")
712                      (match_test "get_attr_insn_count (insn) == 1"))
713                 (const_string "yes")
714                 (const_string "no")))
716 ;; Attribute defining whether or not we can use the branch-likely
717 ;; instructions.
718 (define_attr "branch_likely" "no,yes"
719   (if_then_else (match_test "GENERATE_BRANCHLIKELY")
720                 (const_string "yes")
721                 (const_string "no")))
723 ;; True if an instruction might assign to hi or lo when reloaded.
724 ;; This is used by the TUNE_MACC_CHAINS code.
725 (define_attr "may_clobber_hilo" "no,yes"
726   (if_then_else (eq_attr "type" "imul,imul3,imadd,idiv,mthi,mtlo")
727                 (const_string "yes")
728                 (const_string "no")))
730 ;; Describe a user's asm statement.
731 (define_asm_attributes
732   [(set_attr "type" "multi")
733    (set_attr "can_delay" "no")])
735 ;; This mode iterator allows 32-bit and 64-bit GPR patterns to be generated
736 ;; from the same template.
737 (define_mode_iterator GPR [SI (DI "TARGET_64BIT")])
739 ;; A copy of GPR that can be used when a pattern has two independent
740 ;; modes.
741 (define_mode_iterator GPR2 [SI (DI "TARGET_64BIT")])
743 (define_mode_iterator MOVEP1 [SI SF])
744 (define_mode_iterator MOVEP2 [SI SF])
746 ;; This mode iterator allows :HILO to be used as the mode of the
747 ;; concatenated HI and LO registers.
748 (define_mode_iterator HILO [(DI "!TARGET_64BIT") (TI "TARGET_64BIT")])
750 ;; This mode iterator allows :P to be used for patterns that operate on
751 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
752 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
754 ;; This mode iterator allows :MOVECC to be used anywhere that a
755 ;; conditional-move-type condition is needed.
756 (define_mode_iterator MOVECC [SI (DI "TARGET_64BIT")
757                               (CC "TARGET_HARD_FLOAT
758                                    && !TARGET_LOONGSON_2EF
759                                    && !TARGET_MIPS5900")])
761 ;; 32-bit integer moves for which we provide move patterns.
762 (define_mode_iterator IMOVE32
763   [SI
764    (V2HI "TARGET_DSP")
765    (V4QI "TARGET_DSP")
766    (V2HQ "TARGET_DSP")
767    (V2UHQ "TARGET_DSP")
768    (V2HA "TARGET_DSP")
769    (V2UHA "TARGET_DSP")
770    (V4QQ "TARGET_DSP")
771    (V4UQQ "TARGET_DSP")])
773 ;; 64-bit modes for which we provide move patterns.
774 (define_mode_iterator MOVE64
775   [DI DF
776    (V2SF "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT")
777    (V2SI "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS")
778    (V4HI "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS")
779    (V8QI "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS")])
781 ;; 128-bit modes for which we provide move patterns on 64-bit targets.
782 (define_mode_iterator MOVE128 [TI TF])
784 ;; This mode iterator allows the QI and HI extension patterns to be
785 ;; defined from the same template.
786 (define_mode_iterator SHORT [QI HI])
788 ;; Likewise the 64-bit truncate-and-shift patterns.
789 (define_mode_iterator SUBDI [QI HI SI])
791 ;; This mode iterator allows :ANYF to be used wherever a scalar or vector
792 ;; floating-point mode is allowed.
793 (define_mode_iterator ANYF [(SF "TARGET_HARD_FLOAT")
794                             (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
795                             (V2SF "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT")])
797 ;; Like ANYF, but only applies to scalar modes.
798 (define_mode_iterator SCALARF [(SF "TARGET_HARD_FLOAT")
799                                (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")])
801 ;; A floating-point mode for which moves involving FPRs may need to be split.
802 (define_mode_iterator SPLITF
803   [(DF "!TARGET_64BIT && TARGET_DOUBLE_FLOAT")
804    (DI "!TARGET_64BIT && TARGET_DOUBLE_FLOAT")
805    (V2SF "!TARGET_64BIT && TARGET_PAIRED_SINGLE_FLOAT")
806    (V2SI "!TARGET_64BIT && TARGET_LOONGSON_VECTORS")
807    (V4HI "!TARGET_64BIT && TARGET_LOONGSON_VECTORS")
808    (V8QI "!TARGET_64BIT && TARGET_LOONGSON_VECTORS")
809    (TF "TARGET_64BIT && TARGET_FLOAT64")])
811 ;; In GPR templates, a string like "<d>subu" will expand to "subu" in the
812 ;; 32-bit version and "dsubu" in the 64-bit version.
813 (define_mode_attr d [(SI "") (DI "d")
814                      (QQ "") (HQ "") (SQ "") (DQ "d")
815                      (UQQ "") (UHQ "") (USQ "") (UDQ "d")
816                      (HA "") (SA "") (DA "d")
817                      (UHA "") (USA "") (UDA "d")])
819 ;; Same as d but upper-case.
820 (define_mode_attr D [(SI "") (DI "D")
821                      (QQ "") (HQ "") (SQ "") (DQ "D")
822                      (UQQ "") (UHQ "") (USQ "") (UDQ "D")
823                      (HA "") (SA "") (DA "D")
824                      (UHA "") (USA "") (UDA "D")])
826 ;; This attribute gives the length suffix for a load or store instruction.
827 ;; The same suffixes work for zero and sign extensions.
828 (define_mode_attr size [(QI "b") (HI "h") (SI "w") (DI "d")])
829 (define_mode_attr SIZE [(QI "B") (HI "H") (SI "W") (DI "D")])
831 ;; This attributes gives the mode mask of a SHORT.
832 (define_mode_attr mask [(QI "0x00ff") (HI "0xffff")])
834 ;; Mode attributes for GPR loads.
835 (define_mode_attr load [(SI "lw") (DI "ld")])
836 ;; Instruction names for stores.
837 (define_mode_attr store [(QI "sb") (HI "sh") (SI "sw") (DI "sd")])
839 ;; Similarly for MIPS IV indexed FPR loads and stores.
840 (define_mode_attr loadx [(SF "lwxc1") (DF "ldxc1") (V2SF "ldxc1")])
841 (define_mode_attr storex [(SF "swxc1") (DF "sdxc1") (V2SF "sdxc1")])
843 ;; The unextended ranges of the MIPS16 addiu and daddiu instructions
844 ;; are different.  Some forms of unextended addiu have an 8-bit immediate
845 ;; field but the equivalent daddiu has only a 5-bit field.
846 (define_mode_attr si8_di5 [(SI "8") (DI "5")])
848 ;; This attribute gives the best constraint to use for registers of
849 ;; a given mode.
850 (define_mode_attr reg [(SI "d") (DI "d") (CC "z")])
852 ;; This attribute gives the format suffix for floating-point operations.
853 (define_mode_attr fmt [(SF "s") (DF "d") (V2SF "ps")])
855 ;; This attribute gives the upper-case mode name for one unit of a
856 ;; floating-point mode.
857 (define_mode_attr UNITMODE [(SF "SF") (DF "DF") (V2SF "SF")])
859 ;; This attribute gives the integer mode that has the same size as a
860 ;; fixed-point mode.
861 (define_mode_attr IMODE [(QQ "QI") (HQ "HI") (SQ "SI") (DQ "DI")
862                          (UQQ "QI") (UHQ "HI") (USQ "SI") (UDQ "DI")
863                          (HA "HI") (SA "SI") (DA "DI")
864                          (UHA "HI") (USA "SI") (UDA "DI")
865                          (V4UQQ "SI") (V2UHQ "SI") (V2UHA "SI")
866                          (V2HQ "SI") (V2HA "SI")])
868 ;; This attribute gives the integer mode that has half the size of
869 ;; the controlling mode.
870 (define_mode_attr HALFMODE [(DF "SI") (DI "SI") (V2SF "SI")
871                             (V2SI "SI") (V4HI "SI") (V8QI "SI")
872                             (TF "DI")])
874 ;; This attribute works around the early SB-1 rev2 core "F2" erratum:
876 ;; In certain cases, div.s and div.ps may have a rounding error
877 ;; and/or wrong inexact flag.
879 ;; Therefore, we only allow div.s if not working around SB-1 rev2
880 ;; errata or if a slight loss of precision is OK.
881 (define_mode_attr divide_condition
882   [DF (SF "!TARGET_FIX_SB1 || flag_unsafe_math_optimizations")
883    (V2SF "TARGET_SB1 && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)")])
885 ;; This attribute gives the conditions under which SQRT.fmt instructions
886 ;; can be used.
887 (define_mode_attr sqrt_condition
888   [(SF "!ISA_MIPS1") (DF "!ISA_MIPS1") (V2SF "TARGET_SB1")])
890 ;; This code iterator allows signed and unsigned widening multiplications
891 ;; to use the same template.
892 (define_code_iterator any_extend [sign_extend zero_extend])
894 ;; This code iterator allows the two right shift instructions to be
895 ;; generated from the same template.
896 (define_code_iterator any_shiftrt [ashiftrt lshiftrt])
898 ;; This code iterator allows the three shift instructions to be generated
899 ;; from the same template.
900 (define_code_iterator any_shift [ashift ashiftrt lshiftrt])
902 ;; This code iterator allows unsigned and signed division to be generated
903 ;; from the same template.
904 (define_code_iterator any_div [div udiv])
906 ;; This code iterator allows unsigned and signed modulus to be generated
907 ;; from the same template.
908 (define_code_iterator any_mod [mod umod])
910 ;; This code iterator allows all native floating-point comparisons to be
911 ;; generated from the same template.
912 (define_code_iterator fcond [unordered uneq unlt unle eq lt le])
914 ;; This code iterator is used for comparisons that can be implemented
915 ;; by swapping the operands.
916 (define_code_iterator swapped_fcond [ge gt unge ungt])
918 ;; Equality operators.
919 (define_code_iterator equality_op [eq ne])
921 ;; These code iterators allow the signed and unsigned scc operations to use
922 ;; the same template.
923 (define_code_iterator any_gt [gt gtu])
924 (define_code_iterator any_ge [ge geu])
925 (define_code_iterator any_lt [lt ltu])
926 (define_code_iterator any_le [le leu])
928 (define_code_iterator any_return [return simple_return])
930 ;; <u> expands to an empty string when doing a signed operation and
931 ;; "u" when doing an unsigned operation.
932 (define_code_attr u [(sign_extend "") (zero_extend "u")
933                      (div "") (udiv "u")
934                      (mod "") (umod "u")
935                      (gt "") (gtu "u")
936                      (ge "") (geu "u")
937                      (lt "") (ltu "u")
938                      (le "") (leu "u")])
940 ;; <U> is like <u> except uppercase.
941 (define_code_attr U [(sign_extend "") (zero_extend "U")])
943 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
944 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
946 ;; <optab> expands to the name of the optab for a particular code.
947 (define_code_attr optab [(ashift "ashl")
948                          (ashiftrt "ashr")
949                          (lshiftrt "lshr")
950                          (ior "ior")
951                          (xor "xor")
952                          (and "and")
953                          (plus "add")
954                          (minus "sub")
955                          (return "return")
956                          (simple_return "simple_return")])
958 ;; <insn> expands to the name of the insn that implements a particular code.
959 (define_code_attr insn [(ashift "sll")
960                         (ashiftrt "sra")
961                         (lshiftrt "srl")
962                         (ior "or")
963                         (xor "xor")
964                         (and "and")
965                         (plus "addu")
966                         (minus "subu")])
968 ;; <immediate_insn> expands to the name of the insn that implements
969 ;; a particular code to operate on immediate values.
970 (define_code_attr immediate_insn [(ior "ori")
971                                   (xor "xori")
972                                   (and "andi")])
974 (define_code_attr shift_compression [(ashift "micromips")
975                                      (lshiftrt "micromips")
976                                      (ashiftrt "none")])
978 ;; <fcond> is the c.cond.fmt condition associated with a particular code.
979 (define_code_attr fcond [(unordered "un")
980                          (uneq "ueq")
981                          (unlt "ult")
982                          (unle "ule")
983                          (eq "eq")
984                          (lt "lt")
985                          (le "le")])
987 ;; Similar, but for swapped conditions.
988 (define_code_attr swapped_fcond [(ge "le")
989                                  (gt "lt")
990                                  (unge "ule")
991                                  (ungt "ult")])
993 ;; The value of the bit when the branch is taken for branch_bit patterns.
994 ;; Comparison is always against zero so this depends on the operator.
995 (define_code_attr bbv [(eq "0") (ne "1")])
997 ;; This is the inverse value of bbv.
998 (define_code_attr bbinv [(eq "1") (ne "0")])
1000 ;; .........................
1002 ;;      Branch, call and jump delay slots
1004 ;; .........................
1006 (define_delay (and (eq_attr "type" "branch")
1007                    (not (match_test "TARGET_MIPS16"))
1008                    (eq_attr "branch_likely" "yes"))
1009   [(eq_attr "can_delay" "yes")
1010    (nil)
1011    (eq_attr "can_delay" "yes")])
1013 ;; Branches that don't have likely variants do not annul on false.
1014 (define_delay (and (eq_attr "type" "branch")
1015                    (not (match_test "TARGET_MIPS16"))
1016                    (eq_attr "branch_likely" "no"))
1017   [(eq_attr "can_delay" "yes")
1018    (nil)
1019    (nil)])
1021 (define_delay (eq_attr "type" "jump")
1022   [(eq_attr "can_delay" "yes")
1023    (nil)
1024    (nil)])
1026 (define_delay (and (eq_attr "type" "call")
1027                    (eq_attr "jal_macro" "no"))
1028   [(eq_attr "can_delay" "yes")
1029    (nil)
1030    (nil)])
1032 ;; Pipeline descriptions.
1034 ;; generic.md provides a fallback for processors without a specific
1035 ;; pipeline description.  It is derived from the old define_function_unit
1036 ;; version and uses the "alu" and "imuldiv" units declared below.
1038 ;; Some of the processor-specific files are also derived from old
1039 ;; define_function_unit descriptions and simply override the parts of
1040 ;; generic.md that don't apply.  The other processor-specific files
1041 ;; are self-contained.
1042 (define_automaton "alu,imuldiv")
1044 (define_cpu_unit "alu" "alu")
1045 (define_cpu_unit "imuldiv" "imuldiv")
1047 ;; Ghost instructions produce no real code and introduce no hazards.
1048 ;; They exist purely to express an effect on dataflow.
1049 (define_insn_reservation "ghost" 0
1050   (eq_attr "type" "ghost")
1051   "nothing")
1053 (include "4k.md")
1054 (include "5k.md")
1055 (include "20kc.md")
1056 (include "24k.md")
1057 (include "74k.md")
1058 (include "3000.md")
1059 (include "4000.md")
1060 (include "4100.md")
1061 (include "4130.md")
1062 (include "4300.md")
1063 (include "4600.md")
1064 (include "5000.md")
1065 (include "5400.md")
1066 (include "5500.md")
1067 (include "6000.md")
1068 (include "7000.md")
1069 (include "9000.md")
1070 (include "10000.md")
1071 (include "loongson2ef.md")
1072 (include "loongson3a.md")
1073 (include "octeon.md")
1074 (include "sb1.md")
1075 (include "sr71k.md")
1076 (include "xlr.md")
1077 (include "xlp.md")
1078 (include "generic.md")
1081 ;;  ....................
1083 ;;      CONDITIONAL TRAPS
1085 ;;  ....................
1088 (define_insn "trap"
1089   [(trap_if (const_int 1) (const_int 0))]
1090   ""
1092   if (ISA_HAS_COND_TRAP)
1093     return "teq\t$0,$0";
1094   else if (TARGET_MIPS16)
1095     return "break 0";
1096   else
1097     return "break";
1099   [(set_attr "type" "trap")])
1101 (define_expand "ctrap<mode>4"
1102   [(trap_if (match_operator 0 "comparison_operator"
1103                             [(match_operand:GPR 1 "reg_or_0_operand")
1104                              (match_operand:GPR 2 "arith_operand")])
1105             (match_operand 3 "const_0_operand"))]
1106   "ISA_HAS_COND_TRAP"
1108   mips_expand_conditional_trap (operands[0]);
1109   DONE;
1112 (define_insn "*conditional_trap<mode>"
1113   [(trap_if (match_operator:GPR 0 "trap_comparison_operator"
1114                                 [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
1115                                  (match_operand:GPR 2 "arith_operand" "dI")])
1116             (const_int 0))]
1117   "ISA_HAS_COND_TRAP"
1118   "t%C0\t%z1,%2"
1119   [(set_attr "type" "trap")])
1122 ;;  ....................
1124 ;;      ADDITION
1126 ;;  ....................
1129 (define_insn "add<mode>3"
1130   [(set (match_operand:ANYF 0 "register_operand" "=f")
1131         (plus:ANYF (match_operand:ANYF 1 "register_operand" "f")
1132                    (match_operand:ANYF 2 "register_operand" "f")))]
1133   ""
1134   "add.<fmt>\t%0,%1,%2"
1135   [(set_attr "type" "fadd")
1136    (set_attr "mode" "<UNITMODE>")])
1138 (define_expand "add<mode>3"
1139   [(set (match_operand:GPR 0 "register_operand")
1140         (plus:GPR (match_operand:GPR 1 "register_operand")
1141                   (match_operand:GPR 2 "arith_operand")))]
1142   "")
1144 (define_insn "*add<mode>3"
1145   [(set (match_operand:GPR 0 "register_operand" "=!u,d,!u,!u,!ks,!d,d")
1146         (plus:GPR (match_operand:GPR 1 "register_operand" "!u,d,!u,!ks,!ks,0,d")
1147                   (match_operand:GPR 2 "arith_operand" "!u,d,Uead,Uuw6,Uesp,Usb4,Q")))]
1148   "!TARGET_MIPS16"
1150   if (which_alternative == 0 
1151       || which_alternative == 1)
1152     return "<d>addu\t%0,%1,%2";
1153   else
1154     return "<d>addiu\t%0,%1,%2";
1156   [(set_attr "alu_type" "add")
1157    (set_attr "compression" "micromips,*,micromips,micromips,micromips,micromips,*")
1158    (set_attr "mode" "<MODE>")])
1160 (define_insn "*add<mode>3_mips16"
1161   [(set (match_operand:GPR 0 "register_operand" "=ks,ks,d,d,d,d,d,d,d")
1162         (plus:GPR (match_operand:GPR 1 "register_operand" "ks,ks,ks,ks,0,0,d,d,d")
1163                   (match_operand:GPR 2 "arith_operand" "Usd8,Q,Uuw<si8_di5>,Q,Usb<si8_di5>,Q,Usb4,O,d")))]
1164   "TARGET_MIPS16"
1165   "@
1166     <d>addiu\t%0,%2
1167     <d>addiu\t%0,%2
1168     <d>addiu\t%0,%1,%2
1169     <d>addiu\t%0,%1,%2
1170     <d>addiu\t%0,%2
1171     <d>addiu\t%0,%2
1172     <d>addiu\t%0,%1,%2
1173     <d>addiu\t%0,%1,%2
1174     <d>addu\t%0,%1,%2"
1175   [(set_attr "alu_type" "add")
1176    (set_attr "mode" "<MODE>")
1177    (set_attr "extended_mips16" "no,yes,no,yes,no,yes,no,yes,no")])
1179 ;; On the mips16, we can sometimes split an add of a constant which is
1180 ;; a 4 byte instruction into two adds which are both 2 byte
1181 ;; instructions.  There are two cases: one where we are adding a
1182 ;; constant plus a register to another register, and one where we are
1183 ;; simply adding a constant to a register.
1185 (define_split
1186   [(set (match_operand:SI 0 "d_operand")
1187         (plus:SI (match_dup 0)
1188                  (match_operand:SI 1 "const_int_operand")))]
1189   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
1190    && ((INTVAL (operands[1]) > 0x7f
1191         && INTVAL (operands[1]) <= 0x7f + 0x7f)
1192        || (INTVAL (operands[1]) < - 0x80
1193            && INTVAL (operands[1]) >= - 0x80 - 0x80))"
1194   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
1195    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
1197   HOST_WIDE_INT val = INTVAL (operands[1]);
1199   if (val >= 0)
1200     {
1201       operands[1] = GEN_INT (0x7f);
1202       operands[2] = GEN_INT (val - 0x7f);
1203     }
1204   else
1205     {
1206       operands[1] = GEN_INT (- 0x80);
1207       operands[2] = GEN_INT (val + 0x80);
1208     }
1211 (define_split
1212   [(set (match_operand:SI 0 "d_operand")
1213         (plus:SI (match_operand:SI 1 "d_operand")
1214                  (match_operand:SI 2 "const_int_operand")))]
1215   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
1216    && REGNO (operands[0]) != REGNO (operands[1])
1217    && ((INTVAL (operands[2]) > 0x7
1218         && INTVAL (operands[2]) <= 0x7 + 0x7f)
1219        || (INTVAL (operands[2]) < - 0x8
1220            && INTVAL (operands[2]) >= - 0x8 - 0x80))"
1221   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
1222    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
1224   HOST_WIDE_INT val = INTVAL (operands[2]);
1226   if (val >= 0)
1227     {
1228       operands[2] = GEN_INT (0x7);
1229       operands[3] = GEN_INT (val - 0x7);
1230     }
1231   else
1232     {
1233       operands[2] = GEN_INT (- 0x8);
1234       operands[3] = GEN_INT (val + 0x8);
1235     }
1238 (define_split
1239   [(set (match_operand:DI 0 "d_operand")
1240         (plus:DI (match_dup 0)
1241                  (match_operand:DI 1 "const_int_operand")))]
1242   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1243    && ((INTVAL (operands[1]) > 0xf
1244         && INTVAL (operands[1]) <= 0xf + 0xf)
1245        || (INTVAL (operands[1]) < - 0x10
1246            && INTVAL (operands[1]) >= - 0x10 - 0x10))"
1247   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
1248    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
1250   HOST_WIDE_INT val = INTVAL (operands[1]);
1252   if (val >= 0)
1253     {
1254       operands[1] = GEN_INT (0xf);
1255       operands[2] = GEN_INT (val - 0xf);
1256     }
1257   else
1258     {
1259       operands[1] = GEN_INT (- 0x10);
1260       operands[2] = GEN_INT (val + 0x10);
1261     }
1264 (define_split
1265   [(set (match_operand:DI 0 "d_operand")
1266         (plus:DI (match_operand:DI 1 "d_operand")
1267                  (match_operand:DI 2 "const_int_operand")))]
1268   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1269    && REGNO (operands[0]) != REGNO (operands[1])
1270    && ((INTVAL (operands[2]) > 0x7
1271         && INTVAL (operands[2]) <= 0x7 + 0xf)
1272        || (INTVAL (operands[2]) < - 0x8
1273            && INTVAL (operands[2]) >= - 0x8 - 0x10))"
1274   [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
1275    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
1277   HOST_WIDE_INT val = INTVAL (operands[2]);
1279   if (val >= 0)
1280     {
1281       operands[2] = GEN_INT (0x7);
1282       operands[3] = GEN_INT (val - 0x7);
1283     }
1284   else
1285     {
1286       operands[2] = GEN_INT (- 0x8);
1287       operands[3] = GEN_INT (val + 0x8);
1288     }
1291 (define_insn "*addsi3_extended"
1292   [(set (match_operand:DI 0 "register_operand" "=d,d")
1293         (sign_extend:DI
1294              (plus:SI (match_operand:SI 1 "register_operand" "d,d")
1295                       (match_operand:SI 2 "arith_operand" "d,Q"))))]
1296   "TARGET_64BIT && !TARGET_MIPS16"
1297   "@
1298     addu\t%0,%1,%2
1299     addiu\t%0,%1,%2"
1300   [(set_attr "alu_type" "add")
1301    (set_attr "mode" "SI")])
1303 ;; Split this insn so that the addiu splitters can have a crack at it.
1304 ;; Use a conservative length estimate until the split.
1305 (define_insn_and_split "*addsi3_extended_mips16"
1306   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1307         (sign_extend:DI
1308              (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1309                       (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
1310   "TARGET_64BIT && TARGET_MIPS16"
1311   "#"
1312   "&& reload_completed"
1313   [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))]
1314   { operands[3] = gen_lowpart (SImode, operands[0]); }
1315   [(set_attr "alu_type" "add")
1316    (set_attr "mode" "SI")
1317    (set_attr "extended_mips16" "yes")])
1319 ;; Combiner patterns for unsigned byte-add.
1321 (define_insn "*baddu_si_eb"
1322   [(set (match_operand:SI 0 "register_operand" "=d")
1323         (zero_extend:SI
1324          (subreg:QI
1325           (plus:SI (match_operand:SI 1 "register_operand" "d")
1326                    (match_operand:SI 2 "register_operand" "d")) 3)))]
1327   "ISA_HAS_BADDU && BYTES_BIG_ENDIAN"
1328   "baddu\\t%0,%1,%2"
1329   [(set_attr "alu_type" "add")])
1331 (define_insn "*baddu_si_el"
1332   [(set (match_operand:SI 0 "register_operand" "=d")
1333         (zero_extend:SI
1334          (subreg:QI
1335           (plus:SI (match_operand:SI 1 "register_operand" "d")
1336                    (match_operand:SI 2 "register_operand" "d")) 0)))]
1337   "ISA_HAS_BADDU && !BYTES_BIG_ENDIAN"
1338   "baddu\\t%0,%1,%2"
1339   [(set_attr "alu_type" "add")])
1341 (define_insn "*baddu_di<mode>"
1342   [(set (match_operand:GPR 0 "register_operand" "=d")
1343         (zero_extend:GPR
1344          (truncate:QI
1345           (plus:DI (match_operand:DI 1 "register_operand" "d")
1346                    (match_operand:DI 2 "register_operand" "d")))))]
1347   "ISA_HAS_BADDU && TARGET_64BIT"
1348   "baddu\\t%0,%1,%2"
1349   [(set_attr "alu_type" "add")])
1352 ;;  ....................
1354 ;;      SUBTRACTION
1356 ;;  ....................
1359 (define_insn "sub<mode>3"
1360   [(set (match_operand:ANYF 0 "register_operand" "=f")
1361         (minus:ANYF (match_operand:ANYF 1 "register_operand" "f")
1362                     (match_operand:ANYF 2 "register_operand" "f")))]
1363   ""
1364   "sub.<fmt>\t%0,%1,%2"
1365   [(set_attr "type" "fadd")
1366    (set_attr "mode" "<UNITMODE>")])
1368 (define_insn "sub<mode>3"
1369   [(set (match_operand:GPR 0 "register_operand" "=!u,d")
1370         (minus:GPR (match_operand:GPR 1 "register_operand" "!u,d")
1371                    (match_operand:GPR 2 "register_operand" "!u,d")))]
1372   ""
1373   "<d>subu\t%0,%1,%2"
1374   [(set_attr "alu_type" "sub")
1375    (set_attr "compression" "micromips,*")
1376    (set_attr "mode" "<MODE>")])
1378 (define_insn "*subsi3_extended"
1379   [(set (match_operand:DI 0 "register_operand" "=d")
1380         (sign_extend:DI
1381             (minus:SI (match_operand:SI 1 "register_operand" "d")
1382                       (match_operand:SI 2 "register_operand" "d"))))]
1383   "TARGET_64BIT"
1384   "subu\t%0,%1,%2"
1385   [(set_attr "alu_type" "sub")
1386    (set_attr "mode" "DI")])
1389 ;;  ....................
1391 ;;      MULTIPLICATION
1393 ;;  ....................
1396 (define_expand "mul<mode>3"
1397   [(set (match_operand:SCALARF 0 "register_operand")
1398         (mult:SCALARF (match_operand:SCALARF 1 "register_operand")
1399                       (match_operand:SCALARF 2 "register_operand")))]
1400   ""
1401   "")
1403 (define_insn "*mul<mode>3"
1404   [(set (match_operand:SCALARF 0 "register_operand" "=f")
1405         (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
1406                       (match_operand:SCALARF 2 "register_operand" "f")))]
1407   "!TARGET_4300_MUL_FIX"
1408   "mul.<fmt>\t%0,%1,%2"
1409   [(set_attr "type" "fmul")
1410    (set_attr "mode" "<MODE>")])
1412 ;; Early VR4300 silicon has a CPU bug where multiplies with certain
1413 ;; operands may corrupt immediately following multiplies. This is a
1414 ;; simple fix to insert NOPs.
1416 (define_insn "*mul<mode>3_r4300"
1417   [(set (match_operand:SCALARF 0 "register_operand" "=f")
1418         (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
1419                       (match_operand:SCALARF 2 "register_operand" "f")))]
1420   "TARGET_4300_MUL_FIX"
1421   "mul.<fmt>\t%0,%1,%2\;nop"
1422   [(set_attr "type" "fmul")
1423    (set_attr "mode" "<MODE>")
1424    (set_attr "insn_count" "2")])
1426 (define_insn "mulv2sf3"
1427   [(set (match_operand:V2SF 0 "register_operand" "=f")
1428         (mult:V2SF (match_operand:V2SF 1 "register_operand" "f")
1429                    (match_operand:V2SF 2 "register_operand" "f")))]
1430   "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
1431   "mul.ps\t%0,%1,%2"
1432   [(set_attr "type" "fmul")
1433    (set_attr "mode" "SF")])
1435 ;; The original R4000 has a cpu bug.  If a double-word or a variable
1436 ;; shift executes while an integer multiplication is in progress, the
1437 ;; shift may give an incorrect result.  Avoid this by keeping the mflo
1438 ;; with the mult on the R4000.
1440 ;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
1441 ;; (also valid for MIPS R4000MC processors):
1443 ;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
1444 ;;      this errata description.
1445 ;;      The following code sequence causes the R4000 to incorrectly
1446 ;;      execute the Double Shift Right Arithmetic 32 (dsra32)
1447 ;;      instruction.  If the dsra32 instruction is executed during an
1448 ;;      integer multiply, the dsra32 will only shift by the amount in
1449 ;;      specified in the instruction rather than the amount plus 32
1450 ;;      bits.
1451 ;;      instruction 1:          mult    rs,rt           integer multiply
1452 ;;      instruction 2-12:       dsra32  rd,rt,rs        doubleword shift
1453 ;;                                                      right arithmetic + 32
1454 ;;      Workaround: A dsra32 instruction placed after an integer
1455 ;;      multiply should not be one of the 11 instructions after the
1456 ;;      multiply instruction."
1458 ;; and:
1460 ;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
1461 ;;      the following description.
1462 ;;      All extended shifts (shift by n+32) and variable shifts (32 and
1463 ;;      64-bit versions) may produce incorrect results under the
1464 ;;      following conditions:
1465 ;;      1) An integer multiply is currently executing
1466 ;;      2) These types of shift instructions are executed immediately
1467 ;;         following an integer divide instruction.
1468 ;;      Workaround:
1469 ;;      1) Make sure no integer multiply is running wihen these
1470 ;;         instruction are executed.  If this cannot be predicted at
1471 ;;         compile time, then insert a "mfhi" to R0 instruction
1472 ;;         immediately after the integer multiply instruction.  This
1473 ;;         will cause the integer multiply to complete before the shift
1474 ;;         is executed.
1475 ;;      2) Separate integer divide and these two classes of shift
1476 ;;         instructions by another instruction or a noop."
1478 ;; These processors have PRId values of 0x00004220 and 0x00004300,
1479 ;; respectively.
1481 (define_expand "mul<mode>3"
1482   [(set (match_operand:GPR 0 "register_operand")
1483         (mult:GPR (match_operand:GPR 1 "register_operand")
1484                   (match_operand:GPR 2 "register_operand")))]
1485   "ISA_HAS_<D>MULT"
1487   rtx lo;
1489   if (TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A)
1490     emit_insn (gen_mul<mode>3_mul3_loongson (operands[0], operands[1],
1491                                              operands[2]));
1492   else if (ISA_HAS_<D>MUL3)
1493     emit_insn (gen_mul<mode>3_mul3 (operands[0], operands[1], operands[2]));
1494   else if (TARGET_MIPS16)
1495     {
1496       lo = gen_rtx_REG (<MODE>mode, LO_REGNUM);
1497       emit_insn (gen_mul<mode>3_internal (lo, operands[1], operands[2]));
1498       emit_move_insn (operands[0], lo);
1499     }
1500   else if (TARGET_FIX_R4000)
1501     emit_insn (gen_mul<mode>3_r4000 (operands[0], operands[1], operands[2]));
1502   else
1503     emit_insn
1504       (gen_mul<mode>3_internal (operands[0], operands[1], operands[2]));
1505   DONE;
1508 (define_insn "mul<mode>3_mul3_loongson"
1509   [(set (match_operand:GPR 0 "register_operand" "=d")
1510         (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1511                   (match_operand:GPR 2 "register_operand" "d")))]
1512   "TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A"
1514   if (TARGET_LOONGSON_2EF)
1515     return "<d>multu.g\t%0,%1,%2";
1516   else
1517     return "gs<d>multu\t%0,%1,%2";
1519   [(set_attr "type" "imul3nc")
1520    (set_attr "mode" "<MODE>")])
1522 (define_insn "mul<mode>3_mul3"
1523   [(set (match_operand:GPR 0 "register_operand" "=d,l")
1524         (mult:GPR (match_operand:GPR 1 "register_operand" "d,d")
1525                   (match_operand:GPR 2 "register_operand" "d,d")))
1526    (clobber (match_scratch:GPR 3 "=l,X"))]
1527   "ISA_HAS_<D>MUL3"
1529   if (which_alternative == 1)
1530     return "<d>mult\t%1,%2";
1531   if (<MODE>mode == SImode && (TARGET_MIPS3900 || TARGET_MIPS5900))
1532     return "mult\t%0,%1,%2";
1533   return "<d>mul\t%0,%1,%2";
1535   [(set_attr "type" "imul3,imul")
1536    (set_attr "mode" "<MODE>")])
1538 ;; If a register gets allocated to LO, and we spill to memory, the reload
1539 ;; will include a move from LO to a GPR.  Merge it into the multiplication
1540 ;; if it can set the GPR directly.
1542 ;; Operand 0: LO
1543 ;; Operand 1: GPR (1st multiplication operand)
1544 ;; Operand 2: GPR (2nd multiplication operand)
1545 ;; Operand 3: GPR (destination)
1546 (define_peephole2
1547   [(parallel
1548        [(set (match_operand:SI 0 "lo_operand")
1549              (mult:SI (match_operand:SI 1 "d_operand")
1550                       (match_operand:SI 2 "d_operand")))
1551         (clobber (scratch:SI))])
1552    (set (match_operand:SI 3 "d_operand")
1553         (match_dup 0))]
1554   "ISA_HAS_MUL3 && peep2_reg_dead_p (2, operands[0])"
1555   [(parallel
1556        [(set (match_dup 3)
1557              (mult:SI (match_dup 1)
1558                       (match_dup 2)))
1559         (clobber (match_dup 0))])])
1561 (define_insn "mul<mode>3_internal"
1562   [(set (match_operand:GPR 0 "muldiv_target_operand" "=l")
1563         (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1564                   (match_operand:GPR 2 "register_operand" "d")))]
1565   "ISA_HAS_<D>MULT && !TARGET_FIX_R4000"
1566   "<d>mult\t%1,%2"
1567   [(set_attr "type" "imul")
1568    (set_attr "mode" "<MODE>")])
1570 (define_insn "mul<mode>3_r4000"
1571   [(set (match_operand:GPR 0 "register_operand" "=d")
1572         (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1573                   (match_operand:GPR 2 "register_operand" "d")))
1574    (clobber (match_scratch:GPR 3 "=l"))]
1575   "ISA_HAS_<D>MULT && TARGET_FIX_R4000"
1576   "<d>mult\t%1,%2\;mflo\t%0"
1577   [(set_attr "type" "imul")
1578    (set_attr "mode" "<MODE>")
1579    (set_attr "insn_count" "2")])
1581 ;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
1582 ;; of "mult; mflo".  They have the same latency, but the first form gives
1583 ;; us an extra cycle to compute the operands.
1585 ;; Operand 0: LO
1586 ;; Operand 1: GPR (1st multiplication operand)
1587 ;; Operand 2: GPR (2nd multiplication operand)
1588 ;; Operand 3: GPR (destination)
1589 (define_peephole2
1590   [(set (match_operand:SI 0 "lo_operand")
1591         (mult:SI (match_operand:SI 1 "d_operand")
1592                  (match_operand:SI 2 "d_operand")))
1593    (set (match_operand:SI 3 "d_operand")
1594         (match_dup 0))]
1595   "ISA_HAS_MACC && !ISA_HAS_MUL3"
1596   [(set (match_dup 0)
1597         (const_int 0))
1598    (parallel
1599        [(set (match_dup 0)
1600              (plus:SI (mult:SI (match_dup 1)
1601                                (match_dup 2))
1602                       (match_dup 0)))
1603         (set (match_dup 3)
1604              (plus:SI (mult:SI (match_dup 1)
1605                                (match_dup 2))
1606                       (match_dup 0)))])])
1608 ;; Multiply-accumulate patterns
1610 ;; This pattern is first matched by combine, which tries to use the
1611 ;; pattern wherever it can.  We don't know until later whether it
1612 ;; is actually profitable to use MADD over a "MUL; ADDIU" sequence,
1613 ;; so we need to keep both options open.
1615 ;; The second alternative has a "?" marker because it is generally
1616 ;; one instruction more costly than the first alternative.  This "?"
1617 ;; marker is enough to convey the relative costs to the register
1618 ;; allocator.
1620 ;; However, reload counts reloads of operands 4 and 5 in the same way as
1621 ;; reloads of the other operands, even though operands 4 and 5 need no
1622 ;; copy instructions.  Reload therefore thinks that the second alternative
1623 ;; is two reloads more costly than the first.  We add "*?*?" to the first
1624 ;; alternative as a counterweight.
1625 (define_insn "*mul_acc_si"
1626   [(set (match_operand:SI 0 "register_operand" "=l*?*?,d?")
1627         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1628                           (match_operand:SI 2 "register_operand" "d,d"))
1629                  (match_operand:SI 3 "register_operand" "0,d")))
1630    (clobber (match_scratch:SI 4 "=X,l"))
1631    (clobber (match_scratch:SI 5 "=X,&d"))]
1632   "GENERATE_MADD_MSUB && !TARGET_MIPS16"
1633   "@
1634     madd\t%1,%2
1635     #"
1636   [(set_attr "type"     "imadd")
1637    (set_attr "accum_in" "3")
1638    (set_attr "mode"     "SI")
1639    (set_attr "insn_count" "1,2")])
1641 ;; The same idea applies here.  The middle alternative needs one less
1642 ;; clobber than the final alternative, so we add "*?" as a counterweight.
1643 (define_insn "*mul_acc_si_r3900"
1644   [(set (match_operand:SI 0 "register_operand" "=l*?*?,d*?,d?")
1645         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1646                           (match_operand:SI 2 "register_operand" "d,d,d"))
1647                  (match_operand:SI 3 "register_operand" "0,l,d")))
1648    (clobber (match_scratch:SI 4 "=X,3,l"))
1649    (clobber (match_scratch:SI 5 "=X,X,&d"))]
1650   "TARGET_MIPS3900 && !TARGET_MIPS16"
1651   "@
1652     madd\t%1,%2
1653     madd\t%0,%1,%2
1654     #"
1655   [(set_attr "type"     "imadd")
1656    (set_attr "accum_in" "3")
1657    (set_attr "mode"     "SI")
1658    (set_attr "insn_count" "1,1,2")])
1660 ;; Split *mul_acc_si if both the source and destination accumulator
1661 ;; values are GPRs.
1662 (define_split
1663   [(set (match_operand:SI 0 "d_operand")
1664         (plus:SI (mult:SI (match_operand:SI 1 "d_operand")
1665                           (match_operand:SI 2 "d_operand"))
1666                  (match_operand:SI 3 "d_operand")))
1667    (clobber (match_operand:SI 4 "lo_operand"))
1668    (clobber (match_operand:SI 5 "d_operand"))]
1669   "reload_completed"
1670   [(parallel [(set (match_dup 5)
1671                    (mult:SI (match_dup 1) (match_dup 2)))
1672               (clobber (match_dup 4))])
1673    (set (match_dup 0) (plus:SI (match_dup 5) (match_dup 3)))]
1674   "")
1676 (define_insn "*macc"
1677   [(set (match_operand:SI 0 "register_operand" "=l,d")
1678         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1679                           (match_operand:SI 2 "register_operand" "d,d"))
1680                  (match_operand:SI 3 "register_operand" "0,l")))
1681    (clobber (match_scratch:SI 4 "=X,3"))]
1682   "ISA_HAS_MACC"
1684   if (which_alternative == 1)
1685     return "macc\t%0,%1,%2";
1686   else if (TARGET_MIPS5500)
1687     return "madd\t%1,%2";
1688   else
1689     /* The VR4130 assumes that there is a two-cycle latency between a macc
1690        that "writes" to $0 and an instruction that reads from it.  We avoid
1691        this by assigning to $1 instead.  */
1692     return "%[macc\t%@,%1,%2%]";
1694   [(set_attr "type" "imadd")
1695    (set_attr "accum_in" "3")
1696    (set_attr "mode" "SI")])
1698 (define_insn "*msac"
1699   [(set (match_operand:SI 0 "register_operand" "=l,d")
1700         (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1701                   (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1702                            (match_operand:SI 3 "register_operand" "d,d"))))
1703    (clobber (match_scratch:SI 4 "=X,1"))]
1704   "ISA_HAS_MSAC"
1706   if (which_alternative == 1)
1707     return "msac\t%0,%2,%3";
1708   else if (TARGET_MIPS5500)
1709     return "msub\t%2,%3";
1710   else
1711     return "msac\t$0,%2,%3";
1713   [(set_attr "type"     "imadd")
1714    (set_attr "accum_in" "1")
1715    (set_attr "mode"     "SI")])
1717 ;; An msac-like instruction implemented using negation and a macc.
1718 (define_insn_and_split "*msac_using_macc"
1719   [(set (match_operand:SI 0 "register_operand" "=l,d")
1720         (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1721                   (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1722                            (match_operand:SI 3 "register_operand" "d,d"))))
1723    (clobber (match_scratch:SI 4 "=X,1"))
1724    (clobber (match_scratch:SI 5 "=d,d"))]
1725   "ISA_HAS_MACC && !ISA_HAS_MSAC"
1726   "#"
1727   "&& reload_completed"
1728   [(set (match_dup 5)
1729         (neg:SI (match_dup 3)))
1730    (parallel
1731        [(set (match_dup 0)
1732              (plus:SI (mult:SI (match_dup 2)
1733                                (match_dup 5))
1734                       (match_dup 1)))
1735         (clobber (match_dup 4))])]
1736   ""
1737   [(set_attr "type"     "imadd")
1738    (set_attr "accum_in" "1")
1739    (set_attr "insn_count" "2")])
1741 ;; Patterns generated by the define_peephole2 below.
1743 (define_insn "*macc2"
1744   [(set (match_operand:SI 0 "muldiv_target_operand" "=l")
1745         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1746                           (match_operand:SI 2 "register_operand" "d"))
1747                  (match_dup 0)))
1748    (set (match_operand:SI 3 "register_operand" "=d")
1749         (plus:SI (mult:SI (match_dup 1)
1750                           (match_dup 2))
1751                  (match_dup 0)))]
1752   "ISA_HAS_MACC && reload_completed"
1753   "macc\t%3,%1,%2"
1754   [(set_attr "type"     "imadd")
1755    (set_attr "accum_in" "0")
1756    (set_attr "mode"     "SI")])
1758 (define_insn "*msac2"
1759   [(set (match_operand:SI 0 "muldiv_target_operand" "=l")
1760         (minus:SI (match_dup 0)
1761                   (mult:SI (match_operand:SI 1 "register_operand" "d")
1762                            (match_operand:SI 2 "register_operand" "d"))))
1763    (set (match_operand:SI 3 "register_operand" "=d")
1764         (minus:SI (match_dup 0)
1765                   (mult:SI (match_dup 1)
1766                            (match_dup 2))))]
1767   "ISA_HAS_MSAC && reload_completed"
1768   "msac\t%3,%1,%2"
1769   [(set_attr "type"     "imadd")
1770    (set_attr "accum_in" "0")
1771    (set_attr "mode"     "SI")])
1773 ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1774 ;; Similarly msac.
1776 ;; Operand 0: LO
1777 ;; Operand 1: macc/msac
1778 ;; Operand 2: GPR (destination)
1779 (define_peephole2
1780   [(parallel
1781        [(set (match_operand:SI 0 "lo_operand")
1782              (match_operand:SI 1 "macc_msac_operand"))
1783         (clobber (scratch:SI))])
1784    (set (match_operand:SI 2 "d_operand")
1785         (match_dup 0))]
1786   ""
1787   [(parallel [(set (match_dup 0)
1788                    (match_dup 1))
1789               (set (match_dup 2)
1790                    (match_dup 1))])])
1792 ;; When we have a three-address multiplication instruction, it should
1793 ;; be faster to do a separate multiply and add, rather than moving
1794 ;; something into LO in order to use a macc instruction.
1796 ;; This peephole needs a scratch register to cater for the case when one
1797 ;; of the multiplication operands is the same as the destination.
1799 ;; Operand 0: GPR (scratch)
1800 ;; Operand 1: LO
1801 ;; Operand 2: GPR (addend)
1802 ;; Operand 3: GPR (destination)
1803 ;; Operand 4: macc/msac
1804 ;; Operand 5: new multiplication
1805 ;; Operand 6: new addition/subtraction
1806 (define_peephole2
1807   [(match_scratch:SI 0 "d")
1808    (set (match_operand:SI 1 "lo_operand")
1809         (match_operand:SI 2 "d_operand"))
1810    (match_dup 0)
1811    (parallel
1812        [(set (match_operand:SI 3 "d_operand")
1813              (match_operand:SI 4 "macc_msac_operand"))
1814         (clobber (match_dup 1))])]
1815   "ISA_HAS_MUL3 && peep2_reg_dead_p (2, operands[1])"
1816   [(parallel [(set (match_dup 0)
1817                    (match_dup 5))
1818               (clobber (match_dup 1))])
1819    (set (match_dup 3)
1820         (match_dup 6))]
1822   operands[5] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1823   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1824                                 operands[2], operands[0]);
1827 ;; Same as above, except LO is the initial target of the macc.
1829 ;; Operand 0: GPR (scratch)
1830 ;; Operand 1: LO
1831 ;; Operand 2: GPR (addend)
1832 ;; Operand 3: macc/msac
1833 ;; Operand 4: GPR (destination)
1834 ;; Operand 5: new multiplication
1835 ;; Operand 6: new addition/subtraction
1836 (define_peephole2
1837   [(match_scratch:SI 0 "d")
1838    (set (match_operand:SI 1 "lo_operand")
1839         (match_operand:SI 2 "d_operand"))
1840    (match_dup 0)
1841    (parallel
1842        [(set (match_dup 1)
1843              (match_operand:SI 3 "macc_msac_operand"))
1844         (clobber (scratch:SI))])
1845    (match_dup 0)
1846    (set (match_operand:SI 4 "d_operand")
1847         (match_dup 1))]
1848   "ISA_HAS_MUL3 && peep2_reg_dead_p (3, operands[1])"
1849   [(parallel [(set (match_dup 0)
1850                    (match_dup 5))
1851               (clobber (match_dup 1))])
1852    (set (match_dup 4)
1853         (match_dup 6))]
1855   operands[5] = XEXP (operands[3], GET_CODE (operands[3]) == PLUS ? 0 : 1);
1856   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
1857                                 operands[2], operands[0]);
1860 ;; See the comment above *mul_add_si for details.
1861 (define_insn "*mul_sub_si"
1862   [(set (match_operand:SI 0 "register_operand" "=l*?*?,d?")
1863         (minus:SI (match_operand:SI 1 "register_operand" "0,d")
1864                   (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1865                            (match_operand:SI 3 "register_operand" "d,d"))))
1866    (clobber (match_scratch:SI 4 "=X,l"))
1867    (clobber (match_scratch:SI 5 "=X,&d"))]
1868   "GENERATE_MADD_MSUB"
1869   "@
1870    msub\t%2,%3
1871    #"
1872   [(set_attr "type"     "imadd")
1873    (set_attr "accum_in" "1")
1874    (set_attr "mode"     "SI")
1875    (set_attr "insn_count" "1,2")])
1877 ;; Split *mul_sub_si if both the source and destination accumulator
1878 ;; values are GPRs.
1879 (define_split
1880   [(set (match_operand:SI 0 "d_operand")
1881         (minus:SI (match_operand:SI 1 "d_operand")
1882                   (mult:SI (match_operand:SI 2 "d_operand")
1883                            (match_operand:SI 3 "d_operand"))))
1884    (clobber (match_operand:SI 4 "lo_operand"))
1885    (clobber (match_operand:SI 5 "d_operand"))]
1886   "reload_completed"
1887   [(parallel [(set (match_dup 5)
1888                    (mult:SI (match_dup 2) (match_dup 3)))
1889               (clobber (match_dup 4))])
1890    (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 5)))]
1891   "")
1893 (define_insn "*muls"
1894   [(set (match_operand:SI 0 "register_operand" "=l,d")
1895         (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1896                          (match_operand:SI 2 "register_operand" "d,d"))))
1897    (clobber (match_scratch:SI 3 "=X,l"))]
1898   "ISA_HAS_MULS"
1899   "@
1900    muls\t$0,%1,%2
1901    muls\t%0,%1,%2"
1902   [(set_attr "type"     "imul,imul3")
1903    (set_attr "mode"     "SI")])
1905 (define_expand "<u>mulsidi3"
1906   [(set (match_operand:DI 0 "register_operand")
1907         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1908                  (any_extend:DI (match_operand:SI 2 "register_operand"))))]
1909   "mips_mulsidi3_gen_fn (<CODE>) != NULL"
1911   mulsidi3_gen_fn fn = mips_mulsidi3_gen_fn (<CODE>);
1912   emit_insn (fn (operands[0], operands[1], operands[2]));
1913   DONE;
1916 (define_expand "<u>mulsidi3_32bit_mips16"
1917   [(set (match_operand:DI 0 "register_operand")
1918         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1919                  (any_extend:DI (match_operand:SI 2 "register_operand"))))]
1920   "!TARGET_64BIT && TARGET_MIPS16"
1922   rtx hilo;
1924   hilo = gen_rtx_REG (DImode, MD_REG_FIRST);
1925   emit_insn (gen_<u>mulsidi3_32bit (hilo, operands[1], operands[2]));
1926   emit_move_insn (operands[0], hilo);
1927   DONE;
1930 ;; As well as being named patterns, these instructions are used by the
1931 ;; __builtin_mips_mult<u>() functions.  We must always make those functions
1932 ;; available if !TARGET_64BIT && ISA_HAS_DSP.
1933 (define_insn "<u>mulsidi3_32bit"
1934   [(set (match_operand:DI 0 "muldiv_target_operand" "=ka")
1935         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1936                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1937   "!TARGET_64BIT && (!TARGET_FIX_R4000 || ISA_HAS_DSP)"
1939   if (ISA_HAS_DSP_MULT)
1940     return "mult<u>\t%q0,%1,%2";
1941   else
1942     return "mult<u>\t%1,%2";
1944   [(set_attr "type" "imul")
1945    (set_attr "mode" "SI")])
1947 (define_insn "<u>mulsidi3_32bit_r4000"
1948   [(set (match_operand:DI 0 "register_operand" "=d")
1949         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1950                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1951    (clobber (match_scratch:DI 3 "=x"))]
1952   "!TARGET_64BIT && TARGET_FIX_R4000 && !ISA_HAS_DSP"
1953   "mult<u>\t%1,%2\;mflo\t%L0\;mfhi\t%M0"
1954   [(set_attr "type" "imul")
1955    (set_attr "mode" "SI")
1956    (set_attr "insn_count" "3")])
1958 (define_insn_and_split "<u>mulsidi3_64bit"
1959   [(set (match_operand:DI 0 "register_operand" "=d")
1960         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1961                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1962    (clobber (match_scratch:TI 3 "=x"))
1963    (clobber (match_scratch:DI 4 "=d"))]
1964   "TARGET_64BIT && !TARGET_FIX_R4000 && !ISA_HAS_DMUL3 && !TARGET_MIPS16"
1965   "#"
1966   "&& reload_completed"
1967   [(const_int 0)]
1969   emit_insn (gen_<u>mulsidi3_64bit_split (operands[0], operands[1],
1970                                           operands[2], operands[4]));
1971   DONE;
1973   [(set_attr "type" "imul")
1974    (set_attr "mode" "SI")
1975    (set (attr "insn_count")
1976         (if_then_else (match_test "ISA_HAS_EXT_INS")
1977                       (const_int 4)
1978                       (const_int 7)))])
1980 (define_expand "<u>mulsidi3_64bit_mips16"
1981   [(set (match_operand:DI 0 "register_operand")
1982         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1983                  (any_extend:DI (match_operand:SI 2 "register_operand"))))]
1984   "TARGET_64BIT && TARGET_MIPS16"
1986   emit_insn (gen_<u>mulsidi3_64bit_split (operands[0], operands[1],
1987                                           operands[2], gen_reg_rtx (DImode)));
1988   DONE;
1991 (define_expand "<u>mulsidi3_64bit_split"
1992   [(set (match_operand:DI 0 "register_operand")
1993         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1994                  (any_extend:DI (match_operand:SI 2 "register_operand"))))
1995    (clobber (match_operand:DI 3 "register_operand"))]
1996   ""
1998   rtx hilo;
2000   hilo = gen_rtx_REG (TImode, MD_REG_FIRST);
2001   emit_insn (gen_<u>mulsidi3_64bit_hilo (hilo, operands[1], operands[2]));
2003   emit_move_insn (operands[0], gen_rtx_REG (DImode, LO_REGNUM));
2004   emit_insn (gen_mfhidi_ti (operands[3], hilo));
2006   if (ISA_HAS_EXT_INS)
2007     emit_insn (gen_insvdi (operands[0], GEN_INT (32), GEN_INT (32),
2008                            operands[3]));
2009   else
2010     {
2011       /* Zero-extend the low part.  */
2012       mips_emit_binary (ASHIFT, operands[0], operands[0], GEN_INT (32));
2013       mips_emit_binary (LSHIFTRT, operands[0], operands[0], GEN_INT (32));
2015       /* Shift the high part into place.  */
2016       mips_emit_binary (ASHIFT, operands[3], operands[3], GEN_INT (32));
2018       /* OR the two halves together.  */
2019       mips_emit_binary (IOR, operands[0], operands[0], operands[3]);
2020     }
2021   DONE;
2024 (define_insn "<u>mulsidi3_64bit_hilo"
2025   [(set (match_operand:TI 0 "muldiv_target_operand" "=x")
2026         (unspec:TI
2027           [(mult:DI
2028              (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2029              (any_extend:DI (match_operand:SI 2 "register_operand" "d")))]
2030           UNSPEC_SET_HILO))]
2031   "TARGET_64BIT && !TARGET_FIX_R4000"
2032   "mult<u>\t%1,%2"
2033   [(set_attr "type" "imul")
2034    (set_attr "mode" "SI")])
2036 ;; See comment before the ISA_HAS_DMUL3 case in mips_mulsidi3_gen_fn.
2037 (define_insn "mulsidi3_64bit_dmul"
2038   [(set (match_operand:DI 0 "register_operand" "=d")
2039         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2040                  (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
2041    (clobber (match_scratch:DI 3 "=l"))]
2042   "ISA_HAS_DMUL3"
2043   "dmul\t%0,%1,%2"
2044   [(set_attr "type" "imul3")
2045    (set_attr "mode" "DI")])
2047 ;; Widening multiply with negation.
2048 (define_insn "*muls<u>_di"
2049   [(set (match_operand:DI 0 "muldiv_target_operand" "=x")
2050         (neg:DI
2051          (mult:DI
2052           (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2053           (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
2054   "!TARGET_64BIT && ISA_HAS_MULS"
2055   "muls<u>\t$0,%1,%2"
2056   [(set_attr "type" "imul")
2057    (set_attr "mode" "SI")])
2059 ;; As well as being named patterns, these instructions are used by the
2060 ;; __builtin_mips_msub<u>() functions.  We must always make those functions
2061 ;; available if !TARGET_64BIT && ISA_HAS_DSP.
2063 ;; This leads to a slight inconsistency.  We honor any tuning overrides
2064 ;; in GENERATE_MADD_MSUB for -mno-dsp, but always ignore them for -mdsp,
2065 ;; even if !ISA_HAS_DSP_MULT.
2066 (define_insn "<u>msubsidi4"
2067   [(set (match_operand:DI 0 "muldiv_target_operand" "=ka")
2068         (minus:DI
2069            (match_operand:DI 3 "muldiv_target_operand" "0")
2070            (mult:DI
2071               (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2072               (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
2073   "!TARGET_64BIT && (ISA_HAS_MSAC || GENERATE_MADD_MSUB || ISA_HAS_DSP)"
2075   if (ISA_HAS_DSP_MULT)
2076     return "msub<u>\t%q0,%1,%2";
2077   else if (TARGET_MIPS5500 || GENERATE_MADD_MSUB)
2078     return "msub<u>\t%1,%2";
2079   else
2080     return "msac<u>\t$0,%1,%2";
2082   [(set_attr "type" "imadd")
2083    (set_attr "accum_in" "3")
2084    (set_attr "mode" "SI")])
2086 ;; _highpart patterns
2088 (define_expand "<su>mulsi3_highpart"
2089   [(set (match_operand:SI 0 "register_operand")
2090         (truncate:SI
2091          (lshiftrt:DI
2092           (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
2093                    (any_extend:DI (match_operand:SI 2 "register_operand")))
2094           (const_int 32))))]
2095   ""
2097   if (ISA_HAS_MULHI)
2098     emit_insn (gen_<su>mulsi3_highpart_mulhi_internal (operands[0],
2099                                                        operands[1],
2100                                                        operands[2]));
2101   else if (TARGET_MIPS16)
2102     emit_insn (gen_<su>mulsi3_highpart_split (operands[0], operands[1],
2103                                               operands[2]));
2104   else
2105     emit_insn (gen_<su>mulsi3_highpart_internal (operands[0], operands[1],
2106                                                  operands[2]));
2107   DONE;
2110 (define_insn_and_split "<su>mulsi3_highpart_internal"
2111   [(set (match_operand:SI 0 "register_operand" "=d")
2112         (truncate:SI
2113          (lshiftrt:DI
2114           (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2115                    (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
2116           (const_int 32))))
2117    (clobber (match_scratch:SI 3 "=l"))]
2118   "!ISA_HAS_MULHI && !TARGET_MIPS16"
2119   { return TARGET_FIX_R4000 ? "mult<u>\t%1,%2\n\tmfhi\t%0" : "#"; }
2120   "&& reload_completed && !TARGET_FIX_R4000"
2121   [(const_int 0)]
2123   emit_insn (gen_<su>mulsi3_highpart_split (operands[0], operands[1],
2124                                             operands[2]));
2125   DONE;
2127   [(set_attr "type" "imul")
2128    (set_attr "mode" "SI")
2129    (set_attr "insn_count" "2")])
2131 (define_expand "<su>mulsi3_highpart_split"
2132   [(set (match_operand:SI 0 "register_operand")
2133         (truncate:SI
2134          (lshiftrt:DI
2135           (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
2136                    (any_extend:DI (match_operand:SI 2 "register_operand")))
2137           (const_int 32))))]
2138   ""
2140   rtx hilo;
2142   if (TARGET_64BIT)
2143     {
2144       hilo = gen_rtx_REG (TImode, MD_REG_FIRST);
2145       emit_insn (gen_<u>mulsidi3_64bit_hilo (hilo, operands[1], operands[2]));
2146       emit_insn (gen_mfhisi_ti (operands[0], hilo));
2147     }
2148   else
2149     {
2150       hilo = gen_rtx_REG (DImode, MD_REG_FIRST);
2151       emit_insn (gen_<u>mulsidi3_32bit (hilo, operands[1], operands[2]));
2152       emit_insn (gen_mfhisi_di (operands[0], hilo));
2153     }
2154   DONE;
2157 (define_insn "<su>mulsi3_highpart_mulhi_internal"
2158   [(set (match_operand:SI 0 "register_operand" "=d")
2159         (truncate:SI
2160          (lshiftrt:DI
2161           (mult:DI
2162            (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"
2167   "mulhi<u>\t%0,%1,%2"
2168   [(set_attr "type" "imul3")
2169    (set_attr "mode" "SI")])
2171 (define_insn "*<su>mulsi3_highpart_neg_mulhi_internal"
2172   [(set (match_operand:SI 0 "register_operand" "=d")
2173         (truncate:SI
2174          (lshiftrt:DI
2175           (neg:DI
2176            (mult:DI
2177             (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2178             (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
2179           (const_int 32))))
2180    (clobber (match_scratch:SI 3 "=l"))]
2181   "ISA_HAS_MULHI"
2182   "mulshi<u>\t%0,%1,%2"
2183   [(set_attr "type" "imul3")
2184    (set_attr "mode" "SI")])
2186 ;; Disable unsigned multiplication for -mfix-vr4120.  This is for VR4120
2187 ;; errata MD(0), which says that dmultu does not always produce the
2188 ;; correct result.
2189 (define_expand "<su>muldi3_highpart"
2190   [(set (match_operand:DI 0 "register_operand")
2191         (truncate:DI
2192          (lshiftrt:TI
2193           (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
2194                    (any_extend:TI (match_operand:DI 2 "register_operand")))
2195           (const_int 64))))]
2196   "ISA_HAS_DMULT && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
2198   if (TARGET_MIPS16)
2199     emit_insn (gen_<su>muldi3_highpart_split (operands[0], operands[1],
2200                                               operands[2]));
2201   else
2202     emit_insn (gen_<su>muldi3_highpart_internal (operands[0], operands[1],
2203                                                  operands[2]));
2204   DONE;
2207 (define_insn_and_split "<su>muldi3_highpart_internal"
2208   [(set (match_operand:DI 0 "register_operand" "=d")
2209         (truncate:DI
2210          (lshiftrt:TI
2211           (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
2212                    (any_extend:TI (match_operand:DI 2 "register_operand" "d")))
2213           (const_int 64))))
2214    (clobber (match_scratch:DI 3 "=l"))]
2215   "ISA_HAS_DMULT
2216    && !TARGET_MIPS16
2217    && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
2218   { return TARGET_FIX_R4000 ? "dmult<u>\t%1,%2\n\tmfhi\t%0" : "#"; }
2219   "&& reload_completed && !TARGET_FIX_R4000"
2220   [(const_int 0)]
2222   emit_insn (gen_<su>muldi3_highpart_split (operands[0], operands[1],
2223                                             operands[2]));
2224   DONE;
2226   [(set_attr "type" "imul")
2227    (set_attr "mode" "DI")
2228    (set_attr "insn_count" "2")])
2230 (define_expand "<su>muldi3_highpart_split"
2231   [(set (match_operand:DI 0 "register_operand")
2232         (truncate:DI
2233          (lshiftrt:TI
2234           (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
2235                    (any_extend:TI (match_operand:DI 2 "register_operand")))
2236           (const_int 64))))]
2237   ""
2239   rtx hilo;
2241   hilo = gen_rtx_REG (TImode, MD_REG_FIRST);
2242   emit_insn (gen_<u>mulditi3_internal (hilo, operands[1], operands[2]));
2243   emit_insn (gen_mfhidi_ti (operands[0], hilo));
2244   DONE;
2247 (define_expand "<u>mulditi3"
2248   [(set (match_operand:TI 0 "register_operand")
2249         (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
2250                  (any_extend:TI (match_operand:DI 2 "register_operand"))))]
2251   "ISA_HAS_DMULT && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
2253   rtx hilo;
2255   if (TARGET_MIPS16)
2256     {
2257       hilo = gen_rtx_REG (TImode, MD_REG_FIRST);
2258       emit_insn (gen_<u>mulditi3_internal (hilo, operands[1], operands[2]));
2259       emit_move_insn (operands[0], hilo);
2260     }
2261   else if (TARGET_FIX_R4000)
2262     emit_insn (gen_<u>mulditi3_r4000 (operands[0], operands[1], operands[2]));
2263   else
2264     emit_insn (gen_<u>mulditi3_internal (operands[0], operands[1],
2265                                          operands[2]));
2266   DONE;
2269 (define_insn "<u>mulditi3_internal"
2270   [(set (match_operand:TI 0 "muldiv_target_operand" "=x")
2271         (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
2272                  (any_extend:TI (match_operand:DI 2 "register_operand" "d"))))]
2273   "ISA_HAS_DMULT
2274    && !TARGET_FIX_R4000
2275    && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
2276   "dmult<u>\t%1,%2"
2277   [(set_attr "type" "imul")
2278    (set_attr "mode" "DI")])
2280 (define_insn "<u>mulditi3_r4000"
2281   [(set (match_operand:TI 0 "register_operand" "=d")
2282         (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
2283                  (any_extend:TI (match_operand:DI 2 "register_operand" "d"))))
2284    (clobber (match_scratch:TI 3 "=x"))]
2285   "ISA_HAS_DMULT
2286    && TARGET_FIX_R4000
2287    && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
2288   "dmult<u>\t%1,%2\;mflo\t%L0\;mfhi\t%M0"
2289   [(set_attr "type" "imul")
2290    (set_attr "mode" "DI")
2291    (set_attr "insn_count" "3")])
2293 ;; The R4650 supports a 32-bit multiply/ 64-bit accumulate
2294 ;; instruction.  The HI/LO registers are used as a 64-bit accumulator.
2296 (define_insn "madsi"
2297   [(set (match_operand:SI 0 "register_operand" "+l")
2298         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
2299                           (match_operand:SI 2 "register_operand" "d"))
2300                  (match_dup 0)))]
2301   "TARGET_MAD"
2302   "mad\t%1,%2"
2303   [(set_attr "type"     "imadd")
2304    (set_attr "accum_in" "0")
2305    (set_attr "mode"     "SI")])
2307 ;; See the comment above <u>msubsidi4 for the relationship between
2308 ;; ISA_HAS_DSP and ISA_HAS_DSP_MULT.
2309 (define_insn "<u>maddsidi4"
2310   [(set (match_operand:DI 0 "muldiv_target_operand" "=ka")
2311         (plus:DI
2312          (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2313                   (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
2314          (match_operand:DI 3 "muldiv_target_operand" "0")))]
2315   "(TARGET_MAD || ISA_HAS_MACC || GENERATE_MADD_MSUB || ISA_HAS_DSP)
2316    && !TARGET_64BIT"
2318   if (TARGET_MAD)
2319     return "mad<u>\t%1,%2";
2320   else if (ISA_HAS_DSP_MULT)
2321     return "madd<u>\t%q0,%1,%2";
2322   else if (GENERATE_MADD_MSUB || TARGET_MIPS5500)
2323     return "madd<u>\t%1,%2";
2324   else
2325     /* See comment in *macc.  */
2326     return "%[macc<u>\t%@,%1,%2%]";
2328   [(set_attr "type" "imadd")
2329    (set_attr "accum_in" "3")
2330    (set_attr "mode" "SI")])
2332 ;; Floating point multiply accumulate instructions.
2334 (define_insn "*madd4<mode>"
2335   [(set (match_operand:ANYF 0 "register_operand" "=f")
2336         (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
2337                               (match_operand:ANYF 2 "register_operand" "f"))
2338                    (match_operand:ANYF 3 "register_operand" "f")))]
2339   "ISA_HAS_FP_MADD4_MSUB4 && TARGET_FUSED_MADD"
2340   "madd.<fmt>\t%0,%3,%1,%2"
2341   [(set_attr "type" "fmadd")
2342    (set_attr "accum_in" "3")
2343    (set_attr "mode" "<UNITMODE>")])
2345 (define_insn "*madd3<mode>"
2346   [(set (match_operand:ANYF 0 "register_operand" "=f")
2347         (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
2348                               (match_operand:ANYF 2 "register_operand" "f"))
2349                    (match_operand:ANYF 3 "register_operand" "0")))]
2350   "ISA_HAS_FP_MADD3_MSUB3 && TARGET_FUSED_MADD"
2351   "madd.<fmt>\t%0,%1,%2"
2352   [(set_attr "type" "fmadd")
2353    (set_attr "accum_in" "3")
2354    (set_attr "mode" "<UNITMODE>")])
2356 (define_insn "*msub4<mode>"
2357   [(set (match_operand:ANYF 0 "register_operand" "=f")
2358         (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
2359                                (match_operand:ANYF 2 "register_operand" "f"))
2360                     (match_operand:ANYF 3 "register_operand" "f")))]
2361   "ISA_HAS_FP_MADD4_MSUB4 && TARGET_FUSED_MADD"
2362   "msub.<fmt>\t%0,%3,%1,%2"
2363   [(set_attr "type" "fmadd")
2364    (set_attr "accum_in" "3")
2365    (set_attr "mode" "<UNITMODE>")])
2367 (define_insn "*msub3<mode>"
2368   [(set (match_operand:ANYF 0 "register_operand" "=f")
2369         (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
2370                                (match_operand:ANYF 2 "register_operand" "f"))
2371                     (match_operand:ANYF 3 "register_operand" "0")))]
2372   "ISA_HAS_FP_MADD3_MSUB3 && TARGET_FUSED_MADD"
2373   "msub.<fmt>\t%0,%1,%2"
2374   [(set_attr "type" "fmadd")
2375    (set_attr "accum_in" "3")
2376    (set_attr "mode" "<UNITMODE>")])
2378 (define_insn "*nmadd4<mode>"
2379   [(set (match_operand:ANYF 0 "register_operand" "=f")
2380         (neg:ANYF (plus:ANYF
2381                    (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
2382                               (match_operand:ANYF 2 "register_operand" "f"))
2383                    (match_operand:ANYF 3 "register_operand" "f"))))]
2384   "ISA_HAS_NMADD4_NMSUB4
2385    && TARGET_FUSED_MADD
2386    && HONOR_SIGNED_ZEROS (<MODE>mode)
2387    && !HONOR_NANS (<MODE>mode)"
2388   "nmadd.<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 "*nmadd3<mode>"
2394   [(set (match_operand:ANYF 0 "register_operand" "=f")
2395         (neg:ANYF (plus:ANYF
2396                    (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
2397                               (match_operand:ANYF 2 "register_operand" "f"))
2398                    (match_operand:ANYF 3 "register_operand" "0"))))]
2399   "ISA_HAS_NMADD3_NMSUB3
2400    && TARGET_FUSED_MADD
2401    && HONOR_SIGNED_ZEROS (<MODE>mode)
2402    && !HONOR_NANS (<MODE>mode)"
2403   "nmadd.<fmt>\t%0,%1,%2"
2404   [(set_attr "type" "fmadd")
2405    (set_attr "accum_in" "3")
2406    (set_attr "mode" "<UNITMODE>")])
2408 (define_insn "*nmadd4<mode>_fastmath"
2409   [(set (match_operand:ANYF 0 "register_operand" "=f")
2410         (minus:ANYF
2411          (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
2412                     (match_operand:ANYF 2 "register_operand" "f"))
2413          (match_operand:ANYF 3 "register_operand" "f")))]
2414   "ISA_HAS_NMADD4_NMSUB4
2415    && TARGET_FUSED_MADD
2416    && !HONOR_SIGNED_ZEROS (<MODE>mode)
2417    && !HONOR_NANS (<MODE>mode)"
2418   "nmadd.<fmt>\t%0,%3,%1,%2"
2419   [(set_attr "type" "fmadd")
2420    (set_attr "accum_in" "3")
2421    (set_attr "mode" "<UNITMODE>")])
2423 (define_insn "*nmadd3<mode>_fastmath"
2424   [(set (match_operand:ANYF 0 "register_operand" "=f")
2425         (minus:ANYF
2426          (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
2427                     (match_operand:ANYF 2 "register_operand" "f"))
2428          (match_operand:ANYF 3 "register_operand" "0")))]
2429   "ISA_HAS_NMADD3_NMSUB3
2430    && TARGET_FUSED_MADD
2431    && !HONOR_SIGNED_ZEROS (<MODE>mode)
2432    && !HONOR_NANS (<MODE>mode)"
2433   "nmadd.<fmt>\t%0,%1,%2"
2434   [(set_attr "type" "fmadd")
2435    (set_attr "accum_in" "3")
2436    (set_attr "mode" "<UNITMODE>")])
2438 (define_insn "*nmsub4<mode>"
2439   [(set (match_operand:ANYF 0 "register_operand" "=f")
2440         (neg:ANYF (minus:ANYF
2441                    (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
2442                               (match_operand:ANYF 3 "register_operand" "f"))
2443                    (match_operand:ANYF 1 "register_operand" "f"))))]
2444   "ISA_HAS_NMADD4_NMSUB4
2445    && TARGET_FUSED_MADD
2446    && HONOR_SIGNED_ZEROS (<MODE>mode)
2447    && !HONOR_NANS (<MODE>mode)"
2448   "nmsub.<fmt>\t%0,%1,%2,%3"
2449   [(set_attr "type" "fmadd")
2450    (set_attr "accum_in" "1")
2451    (set_attr "mode" "<UNITMODE>")])
2453 (define_insn "*nmsub3<mode>"
2454   [(set (match_operand:ANYF 0 "register_operand" "=f")
2455         (neg:ANYF (minus:ANYF
2456                    (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
2457                               (match_operand:ANYF 3 "register_operand" "f"))
2458                    (match_operand:ANYF 1 "register_operand" "0"))))]
2459   "ISA_HAS_NMADD3_NMSUB3
2460    && TARGET_FUSED_MADD
2461    && HONOR_SIGNED_ZEROS (<MODE>mode)
2462    && !HONOR_NANS (<MODE>mode)"
2463   "nmsub.<fmt>\t%0,%1,%2"
2464   [(set_attr "type" "fmadd")
2465    (set_attr "accum_in" "1")
2466    (set_attr "mode" "<UNITMODE>")])
2468 (define_insn "*nmsub4<mode>_fastmath"
2469   [(set (match_operand:ANYF 0 "register_operand" "=f")
2470         (minus:ANYF
2471          (match_operand:ANYF 1 "register_operand" "f")
2472          (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
2473                     (match_operand:ANYF 3 "register_operand" "f"))))]
2474   "ISA_HAS_NMADD4_NMSUB4
2475    && TARGET_FUSED_MADD
2476    && !HONOR_SIGNED_ZEROS (<MODE>mode)
2477    && !HONOR_NANS (<MODE>mode)"
2478   "nmsub.<fmt>\t%0,%1,%2,%3"
2479   [(set_attr "type" "fmadd")
2480    (set_attr "accum_in" "1")
2481    (set_attr "mode" "<UNITMODE>")])
2483 (define_insn "*nmsub3<mode>_fastmath"
2484   [(set (match_operand:ANYF 0 "register_operand" "=f")
2485         (minus:ANYF
2486          (match_operand:ANYF 1 "register_operand" "f")
2487          (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
2488                     (match_operand:ANYF 3 "register_operand" "0"))))]
2489   "ISA_HAS_NMADD3_NMSUB3
2490    && TARGET_FUSED_MADD
2491    && !HONOR_SIGNED_ZEROS (<MODE>mode)
2492    && !HONOR_NANS (<MODE>mode)"
2493   "nmsub.<fmt>\t%0,%1,%2"
2494   [(set_attr "type" "fmadd")
2495    (set_attr "accum_in" "1")
2496    (set_attr "mode" "<UNITMODE>")])
2499 ;;  ....................
2501 ;;      DIVISION and REMAINDER
2503 ;;  ....................
2506 (define_expand "div<mode>3"
2507   [(set (match_operand:ANYF 0 "register_operand")
2508         (div:ANYF (match_operand:ANYF 1 "reg_or_1_operand")
2509                   (match_operand:ANYF 2 "register_operand")))]
2510   "<divide_condition>"
2512   if (const_1_operand (operands[1], <MODE>mode))
2513     if (!(ISA_HAS_FP_RECIP_RSQRT (<MODE>mode)
2514           && flag_unsafe_math_optimizations))
2515       operands[1] = force_reg (<MODE>mode, operands[1]);
2518 ;; These patterns work around the early SB-1 rev2 core "F1" erratum:
2520 ;; If an mfc1 or dmfc1 happens to access the floating point register
2521 ;; file at the same time a long latency operation (div, sqrt, recip,
2522 ;; sqrt) iterates an intermediate result back through the floating
2523 ;; point register file bypass, then instead returning the correct
2524 ;; register value the mfc1 or dmfc1 operation returns the intermediate
2525 ;; result of the long latency operation.
2527 ;; The workaround is to insert an unconditional 'mov' from/to the
2528 ;; long latency op destination register.
2530 (define_insn "*div<mode>3"
2531   [(set (match_operand:ANYF 0 "register_operand" "=f")
2532         (div:ANYF (match_operand:ANYF 1 "register_operand" "f")
2533                   (match_operand:ANYF 2 "register_operand" "f")))]
2534   "<divide_condition>"
2536   if (TARGET_FIX_SB1)
2537     return "div.<fmt>\t%0,%1,%2\;mov.<fmt>\t%0,%0";
2538   else
2539     return "div.<fmt>\t%0,%1,%2";
2541   [(set_attr "type" "fdiv")
2542    (set_attr "mode" "<UNITMODE>")
2543    (set (attr "insn_count")
2544         (if_then_else (match_test "TARGET_FIX_SB1")
2545                       (const_int 2)
2546                       (const_int 1)))])
2548 (define_insn "*recip<mode>3"
2549   [(set (match_operand:ANYF 0 "register_operand" "=f")
2550         (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
2551                   (match_operand:ANYF 2 "register_operand" "f")))]
2552   "ISA_HAS_FP_RECIP_RSQRT (<MODE>mode) && flag_unsafe_math_optimizations"
2554   if (TARGET_FIX_SB1)
2555     return "recip.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
2556   else
2557     return "recip.<fmt>\t%0,%2";
2559   [(set_attr "type" "frdiv")
2560    (set_attr "mode" "<UNITMODE>")
2561    (set (attr "insn_count")
2562         (if_then_else (match_test "TARGET_FIX_SB1")
2563                       (const_int 2)
2564                       (const_int 1)))])
2566 ;; VR4120 errata MD(A1): signed division instructions do not work correctly
2567 ;; with negative operands.  We use special libgcc functions instead.
2568 (define_expand "divmod<mode>4"
2569   [(parallel
2570      [(set (match_operand:GPR 0 "register_operand")
2571            (div:GPR (match_operand:GPR 1 "register_operand")
2572                     (match_operand:GPR 2 "register_operand")))
2573       (set (match_operand:GPR 3 "register_operand")
2574            (mod:GPR (match_dup 1)
2575                     (match_dup 2)))])]
2576   "ISA_HAS_<D>DIV && !TARGET_FIX_VR4120"
2578   if (TARGET_MIPS16)
2579     {
2580       rtx lo = gen_rtx_REG (<MODE>mode, LO_REGNUM);
2581       emit_insn (gen_divmod<mode>4_mips16 (operands[0], operands[1],
2582                                            operands[2], operands[3], lo));
2583       DONE;
2584     }
2587 (define_insn_and_split "*divmod<mode>4"
2588   [(set (match_operand:GPR 0 "register_operand" "=l")
2589         (div:GPR (match_operand:GPR 1 "register_operand" "d")
2590                  (match_operand:GPR 2 "register_operand" "d")))
2591    (set (match_operand:GPR 3 "register_operand" "=d")
2592         (mod:GPR (match_dup 1)
2593                  (match_dup 2)))]
2594   "ISA_HAS_<D>DIV && !TARGET_FIX_VR4120 && !TARGET_MIPS16"
2595   "#"
2596   "&& reload_completed"
2597   [(const_int 0)]
2599   emit_insn (gen_divmod<mode>4_split (operands[3], operands[1], operands[2]));
2600   DONE;
2602  [(set_attr "type" "idiv")
2603   (set_attr "mode" "<MODE>")
2604   (set_attr "insn_count" "2")])
2606 ;; Expand generates divmod instructions for individual division and modulus
2607 ;; operations.  We then rely on CSE to reuse earlier divmods where possible.
2608 ;; This means that, when generating MIPS16 code, it is better not to expose
2609 ;; the fixed LO register until after CSE has finished.  However, it's still
2610 ;; better to split before register allocation, so that we don't allocate
2611 ;; one of the scarce MIPS16 registers to an unused result.
2612 (define_insn_and_split "divmod<mode>4_mips16"
2613   [(set (match_operand:GPR 0 "register_operand" "=d")
2614         (div:GPR (match_operand:GPR 1 "register_operand" "d")
2615                  (match_operand:GPR 2 "register_operand" "d")))
2616    (set (match_operand:GPR 3 "register_operand" "=d")
2617         (mod:GPR (match_dup 1)
2618                  (match_dup 2)))
2619    (clobber (match_operand:GPR 4 "lo_operand" "=l"))]
2620   "ISA_HAS_<D>DIV && !TARGET_FIX_VR4120 && TARGET_MIPS16"
2621   "#"
2622   "&& cse_not_expected"
2623   [(const_int 0)]
2625   emit_insn (gen_divmod<mode>4_split (operands[3], operands[1], operands[2]));
2626   emit_move_insn (operands[0], operands[4]);
2627   DONE;
2629  [(set_attr "type" "idiv")
2630   (set_attr "mode" "<MODE>")
2631   (set_attr "insn_count" "3")])
2633 (define_expand "udivmod<mode>4"
2634   [(parallel
2635      [(set (match_operand:GPR 0 "register_operand")
2636            (udiv:GPR (match_operand:GPR 1 "register_operand")
2637                      (match_operand:GPR 2 "register_operand")))
2638       (set (match_operand:GPR 3 "register_operand")
2639            (umod:GPR (match_dup 1)
2640                      (match_dup 2)))])]
2641   "ISA_HAS_<D>DIV && !TARGET_FIX_VR4120"
2643   if (TARGET_MIPS16)
2644     {
2645       rtx lo = gen_rtx_REG (<MODE>mode, LO_REGNUM);
2646       emit_insn (gen_udivmod<mode>4_mips16 (operands[0], operands[1],
2647                                             operands[2], operands[3], lo));
2648       DONE;
2649     }
2652 (define_insn_and_split "*udivmod<mode>4"
2653   [(set (match_operand:GPR 0 "register_operand" "=l")
2654         (udiv:GPR (match_operand:GPR 1 "register_operand" "d")
2655                   (match_operand:GPR 2 "register_operand" "d")))
2656    (set (match_operand:GPR 3 "register_operand" "=d")
2657         (umod:GPR (match_dup 1)
2658                   (match_dup 2)))]
2659   "ISA_HAS_<D>DIV && !TARGET_MIPS16"
2660   "#"
2661   "reload_completed"
2662   [(const_int 0)]
2664   emit_insn (gen_udivmod<mode>4_split (operands[3], operands[1], operands[2]));
2665   DONE;
2667   [(set_attr "type" "idiv")
2668    (set_attr "mode" "<MODE>")
2669    (set_attr "insn_count" "2")])
2671 ;; See the comment above "divmod<mode>4_mips16" for the split timing.
2672 (define_insn_and_split "udivmod<mode>4_mips16"
2673   [(set (match_operand:GPR 0 "register_operand" "=d")
2674         (udiv:GPR (match_operand:GPR 1 "register_operand" "d")
2675                   (match_operand:GPR 2 "register_operand" "d")))
2676    (set (match_operand:GPR 3 "register_operand" "=d")
2677         (umod:GPR (match_dup 1)
2678                   (match_dup 2)))
2679    (clobber (match_operand:GPR 4 "lo_operand" "=l"))]
2680   "ISA_HAS_<D>DIV && TARGET_MIPS16"
2681   "#"
2682   "cse_not_expected"
2683   [(const_int 0)]
2685   emit_insn (gen_udivmod<mode>4_split (operands[3], operands[1], operands[2]));
2686   emit_move_insn (operands[0], operands[4]);
2687   DONE;
2689   [(set_attr "type" "idiv")
2690    (set_attr "mode" "<MODE>")
2691    (set_attr "insn_count" "3")])
2693 (define_expand "<u>divmod<mode>4_split"
2694   [(set (match_operand:GPR 0 "register_operand")
2695         (any_mod:GPR (match_operand:GPR 1 "register_operand")
2696                      (match_operand:GPR 2 "register_operand")))]
2697   ""
2699   rtx hilo;
2701   if (TARGET_64BIT)
2702     {
2703       hilo = gen_rtx_REG (TImode, MD_REG_FIRST);
2704       emit_insn (gen_<u>divmod<mode>4_hilo_ti (hilo, operands[1],
2705                                                operands[2]));
2706       emit_insn (gen_mfhi<mode>_ti (operands[0], hilo));
2707     }
2708   else
2709     {
2710       hilo = gen_rtx_REG (DImode, MD_REG_FIRST);
2711       emit_insn (gen_<u>divmod<mode>4_hilo_di (hilo, operands[1],
2712                                                operands[2]));
2713       emit_insn (gen_mfhi<mode>_di (operands[0], hilo));
2714     }
2715   DONE;
2718 (define_insn "<u>divmod<GPR:mode>4_hilo_<HILO:mode>"
2719   [(set (match_operand:HILO 0 "muldiv_target_operand" "=x")
2720         (unspec:HILO
2721           [(any_div:GPR (match_operand:GPR 1 "register_operand" "d")
2722                         (match_operand:GPR 2 "register_operand" "d"))]
2723           UNSPEC_SET_HILO))]
2724   "ISA_HAS_<GPR:D>DIV"
2725   { return mips_output_division ("<GPR:d>div<u>\t%.,%1,%2", operands); }
2726   [(set_attr "type" "idiv")
2727    (set_attr "mode" "<GPR:MODE>")])
2730 ;;  ....................
2732 ;;      SQUARE ROOT
2734 ;;  ....................
2736 ;; These patterns work around the early SB-1 rev2 core "F1" erratum (see
2737 ;; "*div[sd]f3" comment for details).
2739 (define_insn "sqrt<mode>2"
2740   [(set (match_operand:ANYF 0 "register_operand" "=f")
2741         (sqrt:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2742   "<sqrt_condition>"
2744   if (TARGET_FIX_SB1)
2745     return "sqrt.<fmt>\t%0,%1\;mov.<fmt>\t%0,%0";
2746   else
2747     return "sqrt.<fmt>\t%0,%1";
2749   [(set_attr "type" "fsqrt")
2750    (set_attr "mode" "<UNITMODE>")
2751    (set (attr "insn_count")
2752         (if_then_else (match_test "TARGET_FIX_SB1")
2753                       (const_int 2)
2754                       (const_int 1)))])
2756 (define_insn "*rsqrt<mode>a"
2757   [(set (match_operand:ANYF 0 "register_operand" "=f")
2758         (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
2759                   (sqrt:ANYF (match_operand:ANYF 2 "register_operand" "f"))))]
2760   "ISA_HAS_FP_RECIP_RSQRT (<MODE>mode) && flag_unsafe_math_optimizations"
2762   if (TARGET_FIX_SB1)
2763     return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
2764   else
2765     return "rsqrt.<fmt>\t%0,%2";
2767   [(set_attr "type" "frsqrt")
2768    (set_attr "mode" "<UNITMODE>")
2769    (set (attr "insn_count")
2770         (if_then_else (match_test "TARGET_FIX_SB1")
2771                       (const_int 2)
2772                       (const_int 1)))])
2774 (define_insn "*rsqrt<mode>b"
2775   [(set (match_operand:ANYF 0 "register_operand" "=f")
2776         (sqrt:ANYF (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
2777                              (match_operand:ANYF 2 "register_operand" "f"))))]
2778   "ISA_HAS_FP_RECIP_RSQRT (<MODE>mode) && flag_unsafe_math_optimizations"
2780   if (TARGET_FIX_SB1)
2781     return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
2782   else
2783     return "rsqrt.<fmt>\t%0,%2";
2785   [(set_attr "type" "frsqrt")
2786    (set_attr "mode" "<UNITMODE>")
2787    (set (attr "insn_count")
2788         (if_then_else (match_test "TARGET_FIX_SB1")
2789                       (const_int 2)
2790                       (const_int 1)))])
2793 ;;  ....................
2795 ;;      ABSOLUTE VALUE
2797 ;;  ....................
2799 ;; Do not use the integer abs macro instruction, since that signals an
2800 ;; exception on -2147483648 (sigh).
2802 ;; The "legacy" (as opposed to "2008") form of ABS.fmt is an arithmetic
2803 ;; instruction that treats all NaN inputs as invalid; it does not clear
2804 ;; their sign bit.  We therefore can't use that form if the signs of
2805 ;; NaNs matter.
2807 (define_insn "abs<mode>2"
2808   [(set (match_operand:ANYF 0 "register_operand" "=f")
2809         (abs:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2810   "mips_abs == MIPS_IEEE_754_2008 || !HONOR_NANS (<MODE>mode)"
2811   "abs.<fmt>\t%0,%1"
2812   [(set_attr "type" "fabs")
2813    (set_attr "mode" "<UNITMODE>")])
2816 ;;  ...................
2818 ;;  Count leading zeroes.
2820 ;;  ...................
2823 (define_insn "clz<mode>2"
2824   [(set (match_operand:GPR 0 "register_operand" "=d")
2825         (clz:GPR (match_operand:GPR 1 "register_operand" "d")))]
2826   "ISA_HAS_CLZ_CLO"
2827   "<d>clz\t%0,%1"
2828   [(set_attr "type" "clz")
2829    (set_attr "mode" "<MODE>")])
2832 ;;  ...................
2834 ;;  Count number of set bits.
2836 ;;  ...................
2839 (define_insn "popcount<mode>2"
2840   [(set (match_operand:GPR 0 "register_operand" "=d")
2841         (popcount:GPR (match_operand:GPR 1 "register_operand" "d")))]
2842   "ISA_HAS_POP"
2843   "<d>pop\t%0,%1"
2844   [(set_attr "type" "pop")
2845    (set_attr "mode" "<MODE>")])
2847 ;; The POP instruction is special as it does not take into account the upper
2848 ;; 32bits and is documented that way.
2849 (define_insn "*popcountdi2_trunc"
2850   [(set (match_operand:SI 0 "register_operand" "=d")
2851        (popcount:SI (truncate:SI (match_operand:DI 1 "register_operand" "d"))))]
2852   "ISA_HAS_POP && TARGET_64BIT"
2853   "pop\t%0,%1"
2854   [(set_attr "type" "pop")
2855    (set_attr "mode" "SI")])
2858 ;;  ....................
2860 ;;      NEGATION and ONE'S COMPLEMENT
2862 ;;  ....................
2864 (define_insn "negsi2"
2865   [(set (match_operand:SI 0 "register_operand" "=d")
2866         (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2867   ""
2869   if (TARGET_MIPS16)
2870     return "neg\t%0,%1";
2871   else
2872     return "subu\t%0,%.,%1";
2874   [(set_attr "alu_type" "sub")
2875    (set_attr "mode"     "SI")])
2877 (define_insn "negdi2"
2878   [(set (match_operand:DI 0 "register_operand" "=d")
2879         (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2880   "TARGET_64BIT && !TARGET_MIPS16"
2881   "dsubu\t%0,%.,%1"
2882   [(set_attr "alu_type" "sub")
2883    (set_attr "mode"     "DI")])
2885 ;; The "legacy" (as opposed to "2008") form of NEG.fmt is an arithmetic
2886 ;; instruction that treats all NaN inputs as invalid; it does not flip
2887 ;; their sign bit.  We therefore can't use that form if the signs of
2888 ;; NaNs matter.
2890 (define_insn "neg<mode>2"
2891   [(set (match_operand:ANYF 0 "register_operand" "=f")
2892         (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2893   "mips_abs == MIPS_IEEE_754_2008 || !HONOR_NANS (<MODE>mode)"
2894   "neg.<fmt>\t%0,%1"
2895   [(set_attr "type" "fneg")
2896    (set_attr "mode" "<UNITMODE>")])
2898 (define_insn "one_cmpl<mode>2"
2899   [(set (match_operand:GPR 0 "register_operand" "=!u,d")
2900         (not:GPR (match_operand:GPR 1 "register_operand" "!u,d")))]
2901   ""
2903   if (TARGET_MIPS16)
2904     return "not\t%0,%1";
2905   else
2906     return "nor\t%0,%.,%1";
2908   [(set_attr "alu_type" "not")
2909    (set_attr "compression" "micromips,*")
2910    (set_attr "mode" "<MODE>")])
2913 ;;  ....................
2915 ;;      LOGICAL
2917 ;;  ....................
2920 ;; Many of these instructions use trivial define_expands, because we
2921 ;; want to use a different set of constraints when TARGET_MIPS16.
2923 (define_expand "and<mode>3"
2924   [(set (match_operand:GPR 0 "register_operand")
2925         (and:GPR (match_operand:GPR 1 "register_operand")
2926                  (match_operand:GPR 2 "and_reg_operand")))])
2928 ;; The middle-end is not allowed to convert ANDing with 0xffff_ffff into a
2929 ;; zero_extendsidi2 because of TRULY_NOOP_TRUNCATION, so handle these here.
2930 ;; Note that this variant does not trigger for SI mode because we require
2931 ;; a 64-bit HOST_WIDE_INT and 0xffff_ffff wouldn't be a canonical
2932 ;; sign-extended SImode value.
2934 ;; These are possible combinations for operand 1 and 2.  The table
2935 ;; includes both MIPS and MIPS16 cases.  (r=register, mem=memory,
2936 ;; 16=MIPS16, x=match, S=split):
2938 ;;     \ op1    r/EXT   r/!EXT  mem   r/16   mem/16
2939 ;;  op2
2941 ;;  andi           x     x
2942 ;;  0xff           x     x       x             x
2943 ;;  0xffff         x     x       x             x
2944 ;;  0xffff_ffff    x     S       x     S       x
2945 ;;  low-bitmask    x
2946 ;;  register       x     x
2947 ;;  register =op1                      x
2949 (define_insn "*and<mode>3"
2950   [(set (match_operand:GPR 0 "register_operand" "=d,d,d,!u,d,d,d,!u,d")
2951         (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "o,o,W,!u,d,d,d,0,d")
2952                  (match_operand:GPR 2 "and_operand" "Yb,Yh,Yw,Uean,K,Yx,Yw,!u,d")))]
2953   "!TARGET_MIPS16 && and_operands_ok (<MODE>mode, operands[1], operands[2])"
2955   int len;
2957   switch (which_alternative)
2958     {
2959     case 0:
2960       operands[1] = gen_lowpart (QImode, operands[1]);
2961       return "lbu\t%0,%1";
2962     case 1:
2963       operands[1] = gen_lowpart (HImode, operands[1]);
2964       return "lhu\t%0,%1";
2965     case 2:
2966       operands[1] = gen_lowpart (SImode, operands[1]);
2967       return "lwu\t%0,%1";
2968     case 3:
2969     case 4:
2970       return "andi\t%0,%1,%x2";
2971     case 5:
2972       len = low_bitmask_len (<MODE>mode, INTVAL (operands[2]));
2973       operands[2] = GEN_INT (len);
2974       return "<d>ext\t%0,%1,0,%2";
2975     case 6:
2976       return "#";
2977     case 7:
2978     case 8:
2979       return "and\t%0,%1,%2";
2980     default:
2981       gcc_unreachable ();
2982     }
2984   [(set_attr "move_type" "load,load,load,andi,andi,ext_ins,shift_shift,logical,logical")
2985    (set_attr "compression" "*,*,*,micromips,*,*,*,micromips,*")
2986    (set_attr "mode" "<MODE>")])
2988 (define_insn "*and<mode>3_mips16"
2989   [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d")
2990         (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "%W,W,W,d,0")
2991                  (match_operand:GPR 2 "and_operand" "Yb,Yh,Yw,Yw,d")))]
2992   "TARGET_MIPS16 && and_operands_ok (<MODE>mode, operands[1], operands[2])"
2994   switch (which_alternative)
2995     {
2996     case 0:
2997       operands[1] = gen_lowpart (QImode, operands[1]);
2998       return "lbu\t%0,%1";
2999     case 1:
3000       operands[1] = gen_lowpart (HImode, operands[1]);
3001       return "lhu\t%0,%1";
3002     case 2:
3003       operands[1] = gen_lowpart (SImode, operands[1]);
3004       return "lwu\t%0,%1";
3005     case 3:
3006       return "#";
3007     case 4:
3008       return "and\t%0,%2";
3009     default:
3010       gcc_unreachable ();
3011     }
3013   [(set_attr "move_type" "load,load,load,shift_shift,logical")
3014    (set_attr "mode" "<MODE>")])
3016 (define_expand "ior<mode>3"
3017   [(set (match_operand:GPR 0 "register_operand")
3018         (ior:GPR (match_operand:GPR 1 "register_operand")
3019                  (match_operand:GPR 2 "uns_arith_operand")))]
3020   ""
3022   if (TARGET_MIPS16)
3023     operands[2] = force_reg (<MODE>mode, operands[2]);
3026 (define_insn "*ior<mode>3"
3027   [(set (match_operand:GPR 0 "register_operand" "=!u,d,d")
3028         (ior:GPR (match_operand:GPR 1 "register_operand" "%0,d,d")
3029                  (match_operand:GPR 2 "uns_arith_operand" "!u,d,K")))]
3030   "!TARGET_MIPS16"
3031   "@
3032    or\t%0,%1,%2
3033    or\t%0,%1,%2
3034    ori\t%0,%1,%x2"
3035   [(set_attr "alu_type" "or")
3036    (set_attr "compression" "micromips,*,*")
3037    (set_attr "mode" "<MODE>")])
3039 (define_insn "*ior<mode>3_mips16"
3040   [(set (match_operand:GPR 0 "register_operand" "=d")
3041         (ior:GPR (match_operand:GPR 1 "register_operand" "%0")
3042                  (match_operand:GPR 2 "register_operand" "d")))]
3043   "TARGET_MIPS16"
3044   "or\t%0,%2"
3045   [(set_attr "alu_type" "or")
3046    (set_attr "mode" "<MODE>")])
3048 (define_expand "xor<mode>3"
3049   [(set (match_operand:GPR 0 "register_operand")
3050         (xor:GPR (match_operand:GPR 1 "register_operand")
3051                  (match_operand:GPR 2 "uns_arith_operand")))]
3052   ""
3053   "")
3055 (define_insn "*xor<mode>3"
3056   [(set (match_operand:GPR 0 "register_operand" "=!u,d,d")
3057         (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d")
3058                  (match_operand:GPR 2 "uns_arith_operand" "!u,d,K")))]
3059   "!TARGET_MIPS16"
3060   "@
3061    xor\t%0,%1,%2
3062    xor\t%0,%1,%2
3063    xori\t%0,%1,%x2"
3064   [(set_attr "alu_type" "xor")
3065    (set_attr "compression" "micromips,*,*")
3066    (set_attr "mode" "<MODE>")])
3068 (define_insn "*xor<mode>3_mips16"
3069   [(set (match_operand:GPR 0 "register_operand" "=d,t,t,t")
3070         (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d,d")
3071                  (match_operand:GPR 2 "uns_arith_operand" "d,Uub8,K,d")))]
3072   "TARGET_MIPS16"
3073   "@
3074    xor\t%0,%2
3075    cmpi\t%1,%2
3076    cmpi\t%1,%2
3077    cmp\t%1,%2"
3078   [(set_attr "alu_type" "xor")
3079    (set_attr "mode" "<MODE>")
3080    (set_attr "extended_mips16" "no,no,yes,no")])
3082 (define_insn "*nor<mode>3"
3083   [(set (match_operand:GPR 0 "register_operand" "=d")
3084         (and:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
3085                  (not:GPR (match_operand:GPR 2 "register_operand" "d"))))]
3086   "!TARGET_MIPS16"
3087   "nor\t%0,%1,%2"
3088   [(set_attr "alu_type" "nor")
3089    (set_attr "mode" "<MODE>")])
3092 ;;  ....................
3094 ;;      TRUNCATION
3096 ;;  ....................
3100 (define_insn "truncdfsf2"
3101   [(set (match_operand:SF 0 "register_operand" "=f")
3102         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3103   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3104   "cvt.s.d\t%0,%1"
3105   [(set_attr "type"     "fcvt")
3106    (set_attr "cnv_mode" "D2S")   
3107    (set_attr "mode"     "SF")])
3109 ;; Integer truncation patterns.  Truncating SImode values to smaller
3110 ;; modes is a no-op, as it is for most other GCC ports.  Truncating
3111 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
3112 ;; need to make sure that the lower 32 bits are properly sign-extended
3113 ;; (see TRULY_NOOP_TRUNCATION).  Truncating DImode values into modes
3114 ;; smaller than SImode is equivalent to two separate truncations:
3116 ;;                        A       B
3117 ;;    DI ---> HI  ==  DI ---> SI ---> HI
3118 ;;    DI ---> QI  ==  DI ---> SI ---> QI
3120 ;; Step A needs a real instruction but step B does not.
3122 (define_insn "truncdi<mode>2"
3123   [(set (match_operand:SUBDI 0 "nonimmediate_operand" "=d,m")
3124         (truncate:SUBDI (match_operand:DI 1 "register_operand" "d,d")))]
3125   "TARGET_64BIT"
3126   "@
3127     sll\t%0,%1,0
3128     <store>\t%1,%0"
3129   [(set_attr "move_type" "sll0,store")
3130    (set_attr "mode" "SI")])
3132 ;; Combiner patterns to optimize shift/truncate combinations.
3134 (define_insn "*ashr_trunc<mode>"
3135   [(set (match_operand:SUBDI 0 "register_operand" "=d")
3136         (truncate:SUBDI
3137           (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
3138                        (match_operand:DI 2 "const_arith_operand" ""))))]
3139   "TARGET_64BIT && !TARGET_MIPS16 && IN_RANGE (INTVAL (operands[2]), 32, 63)"
3140   "dsra\t%0,%1,%2"
3141   [(set_attr "type" "shift")
3142    (set_attr "mode" "<MODE>")])
3144 (define_insn "*lshr32_trunc<mode>"
3145   [(set (match_operand:SUBDI 0 "register_operand" "=d")
3146         (truncate:SUBDI
3147           (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
3148                        (const_int 32))))]
3149   "TARGET_64BIT && !TARGET_MIPS16"
3150   "dsra\t%0,%1,32"
3151   [(set_attr "type" "shift")
3152    (set_attr "mode" "<MODE>")])
3154 ;; Logical shift by more than 32 results in proper SI values so truncation is
3155 ;; removed by the middle end.  Note that a logical shift by 32 is handled by
3156 ;; the previous pattern.
3157 (define_insn "*<optab>_trunc<mode>_exts"
3158   [(set (match_operand:SUBDI 0 "register_operand" "=d")
3159         (truncate:SUBDI
3160          (any_shiftrt:DI (match_operand:DI 1 "register_operand" "d")
3161                          (match_operand:DI 2 "const_arith_operand" ""))))]
3162   "ISA_HAS_EXTS && TARGET_64BIT && UINTVAL (operands[2]) < 32"
3163   "exts\t%0,%1,%2,31"
3164   [(set_attr "type" "arith")
3165    (set_attr "mode" "<MODE>")])
3168 ;;  ....................
3170 ;;      ZERO EXTENSION
3172 ;;  ....................
3174 ;; Extension insns.
3176 (define_expand "zero_extendsidi2"
3177   [(set (match_operand:DI 0 "register_operand")
3178         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3179   "TARGET_64BIT")
3181 (define_insn_and_split "*zero_extendsidi2"
3182   [(set (match_operand:DI 0 "register_operand" "=d,d")
3183         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,W")))]
3184   "TARGET_64BIT && !ISA_HAS_EXT_INS"
3185   "@
3186    #
3187    lwu\t%0,%1"
3188   "&& reload_completed && REG_P (operands[1])"
3189   [(set (match_dup 0)
3190         (ashift:DI (match_dup 1) (const_int 32)))
3191    (set (match_dup 0)
3192         (lshiftrt:DI (match_dup 0) (const_int 32)))]
3193   { operands[1] = gen_lowpart (DImode, operands[1]); }
3194   [(set_attr "move_type" "shift_shift,load")
3195    (set_attr "mode" "DI")])
3197 (define_insn "*zero_extendsidi2_dext"
3198   [(set (match_operand:DI 0 "register_operand" "=d,d")
3199         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,W")))]
3200   "TARGET_64BIT && ISA_HAS_EXT_INS"
3201   "@
3202    dext\t%0,%1,0,32
3203    lwu\t%0,%1"
3204   [(set_attr "move_type" "arith,load")
3205    (set_attr "mode" "DI")])
3207 ;; See the comment before the *and<mode>3 pattern why this is generated by
3208 ;; combine.
3210 (define_split
3211   [(set (match_operand:DI 0 "register_operand")
3212         (and:DI (match_operand:DI 1 "register_operand")
3213                 (const_int 4294967295)))]
3214   "TARGET_64BIT && !ISA_HAS_EXT_INS && reload_completed"
3215   [(set (match_dup 0)
3216         (ashift:DI (match_dup 1) (const_int 32)))
3217    (set (match_dup 0)
3218         (lshiftrt:DI (match_dup 0) (const_int 32)))])
3220 (define_expand "zero_extend<SHORT:mode><GPR:mode>2"
3221   [(set (match_operand:GPR 0 "register_operand")
3222         (zero_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
3223   ""
3225   if (TARGET_MIPS16 && !GENERATE_MIPS16E
3226       && !memory_operand (operands[1], <SHORT:MODE>mode))
3227     {
3228       emit_insn (gen_and<GPR:mode>3 (operands[0],
3229                                      gen_lowpart (<GPR:MODE>mode, operands[1]),
3230                                      force_reg (<GPR:MODE>mode,
3231                                                 GEN_INT (<SHORT:mask>))));
3232       DONE;
3233     }
3236 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2"
3237   [(set (match_operand:GPR 0 "register_operand" "=!u,d,d")
3238         (zero_extend:GPR
3239              (match_operand:SHORT 1 "nonimmediate_operand" "!u,d,m")))]
3240   "!TARGET_MIPS16"
3241   "@
3242    andi\t%0,%1,<SHORT:mask>
3243    andi\t%0,%1,<SHORT:mask>
3244    l<SHORT:size>u\t%0,%1"
3245   [(set_attr "move_type" "andi,andi,load")
3246    (set_attr "compression" "micromips,*,*")
3247    (set_attr "mode" "<GPR:MODE>")])
3249 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16e"
3250   [(set (match_operand:GPR 0 "register_operand" "=d")
3251         (zero_extend:GPR (match_operand:SHORT 1 "register_operand" "0")))]
3252   "GENERATE_MIPS16E"
3253   "ze<SHORT:size>\t%0"
3254   ;; This instruction is effectively a special encoding of ANDI.
3255   [(set_attr "move_type" "andi")
3256    (set_attr "mode" "<GPR:MODE>")])
3258 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16"
3259   [(set (match_operand:GPR 0 "register_operand" "=d")
3260         (zero_extend:GPR (match_operand:SHORT 1 "memory_operand" "m")))]
3261   "TARGET_MIPS16"
3262   "l<SHORT:size>u\t%0,%1"
3263   [(set_attr "move_type" "load")
3264    (set_attr "mode" "<GPR:MODE>")])
3266 (define_expand "zero_extendqihi2"
3267   [(set (match_operand:HI 0 "register_operand")
3268         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3269   ""
3271   if (TARGET_MIPS16 && !memory_operand (operands[1], QImode))
3272     {
3273       emit_insn (gen_zero_extendqisi2 (gen_lowpart (SImode, operands[0]),
3274                                        operands[1]));
3275       DONE;
3276     }
3279 (define_insn "*zero_extendqihi2"
3280   [(set (match_operand:HI 0 "register_operand" "=d,d")
3281         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3282   "!TARGET_MIPS16"
3283   "@
3284    andi\t%0,%1,0x00ff
3285    lbu\t%0,%1"
3286   [(set_attr "move_type" "andi,load")
3287    (set_attr "mode" "HI")])
3289 (define_insn "*zero_extendqihi2_mips16"
3290   [(set (match_operand:HI 0 "register_operand" "=d")
3291         (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3292   "TARGET_MIPS16"
3293   "lbu\t%0,%1"
3294   [(set_attr "move_type" "load")
3295    (set_attr "mode" "HI")])
3297 ;; Combiner patterns to optimize truncate/zero_extend combinations.
3299 (define_insn "*zero_extend<GPR:mode>_trunc<SHORT:mode>"
3300   [(set (match_operand:GPR 0 "register_operand" "=d")
3301         (zero_extend:GPR
3302             (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
3303   "TARGET_64BIT && !TARGET_MIPS16"
3305   operands[2] = GEN_INT (GET_MODE_MASK (<SHORT:MODE>mode));
3306   return "andi\t%0,%1,%x2";
3308   [(set_attr "alu_type" "and")
3309    (set_attr "mode" "<GPR:MODE>")])
3311 (define_insn "*zero_extendhi_truncqi"
3312   [(set (match_operand:HI 0 "register_operand" "=d")
3313         (zero_extend:HI
3314             (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
3315   "TARGET_64BIT && !TARGET_MIPS16"
3316   "andi\t%0,%1,0xff"
3317   [(set_attr "alu_type" "and")
3318    (set_attr "mode" "HI")])
3321 ;;  ....................
3323 ;;      SIGN EXTENSION
3325 ;;  ....................
3327 ;; Extension insns.
3328 ;; Those for integer source operand are ordered widest source type first.
3330 ;; When TARGET_64BIT, all SImode integer and accumulator registers
3331 ;; should already be in sign-extended form (see TRULY_NOOP_TRUNCATION
3332 ;; and truncdisi2).  We can therefore get rid of register->register
3333 ;; instructions if we constrain the source to be in the same register as
3334 ;; the destination.
3336 ;; Only the pre-reload scheduler sees the type of the register alternatives;
3337 ;; we split them into nothing before the post-reload scheduler runs.
3338 ;; These alternatives therefore have type "move" in order to reflect
3339 ;; what happens if the two pre-reload operands cannot be tied, and are
3340 ;; instead allocated two separate GPRs.  We don't distinguish between
3341 ;; the GPR and LO cases because we don't usually know during pre-reload
3342 ;; scheduling whether an operand will be LO or not.
3343 (define_insn_and_split "extendsidi2"
3344   [(set (match_operand:DI 0 "register_operand" "=d,l,d")
3345         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,0,m")))]
3346   "TARGET_64BIT"
3347   "@
3348    #
3349    #
3350    lw\t%0,%1"
3351   "&& reload_completed && register_operand (operands[1], VOIDmode)"
3352   [(const_int 0)]
3354   emit_note (NOTE_INSN_DELETED);
3355   DONE;
3357   [(set_attr "move_type" "move,move,load")
3358    (set_attr "mode" "DI")])
3360 (define_expand "extend<SHORT:mode><GPR:mode>2"
3361   [(set (match_operand:GPR 0 "register_operand")
3362         (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
3363   "")
3365 (define_insn "*extend<SHORT:mode><GPR:mode>2_mips16e"
3366   [(set (match_operand:GPR 0 "register_operand" "=d,d")
3367         (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand" "0,m")))]
3368   "GENERATE_MIPS16E"
3369   "@
3370    se<SHORT:size>\t%0
3371    l<SHORT:size>\t%0,%1"
3372   [(set_attr "move_type" "signext,load")
3373    (set_attr "mode" "<GPR:MODE>")])
3375 (define_insn_and_split "*extend<SHORT:mode><GPR:mode>2"
3376   [(set (match_operand:GPR 0 "register_operand" "=d,d")
3377         (sign_extend:GPR
3378              (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
3379   "!ISA_HAS_SEB_SEH && !GENERATE_MIPS16E"
3380   "@
3381    #
3382    l<SHORT:size>\t%0,%1"
3383   "&& reload_completed && REG_P (operands[1])"
3384   [(set (match_dup 0) (ashift:GPR (match_dup 1) (match_dup 2)))
3385    (set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))]
3387   operands[1] = gen_lowpart (<GPR:MODE>mode, operands[1]);
3388   operands[2] = GEN_INT (GET_MODE_BITSIZE (<GPR:MODE>mode)
3389                          - GET_MODE_BITSIZE (<SHORT:MODE>mode));
3391   [(set_attr "move_type" "shift_shift,load")
3392    (set_attr "mode" "<GPR:MODE>")])
3394 (define_insn "*extend<SHORT:mode><GPR:mode>2_se<SHORT:size>"
3395   [(set (match_operand:GPR 0 "register_operand" "=d,d")
3396         (sign_extend:GPR
3397              (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
3398   "ISA_HAS_SEB_SEH"
3399   "@
3400    se<SHORT:size>\t%0,%1
3401    l<SHORT:size>\t%0,%1"
3402   [(set_attr "move_type" "signext,load")
3403    (set_attr "mode" "<GPR:MODE>")])
3405 (define_expand "extendqihi2"
3406   [(set (match_operand:HI 0 "register_operand")
3407         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3408   "")
3410 (define_insn "*extendqihi2_mips16e"
3411   [(set (match_operand:HI 0 "register_operand" "=d,d")
3412         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,m")))]
3413   "GENERATE_MIPS16E"
3414   "@
3415    seb\t%0
3416    lb\t%0,%1"
3417   [(set_attr "move_type" "signext,load")
3418    (set_attr "mode" "SI")])
3420 (define_insn_and_split "*extendqihi2"
3421   [(set (match_operand:HI 0 "register_operand" "=d,d")
3422         (sign_extend:HI
3423              (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3424   "!ISA_HAS_SEB_SEH && !GENERATE_MIPS16E"
3425   "@
3426    #
3427    lb\t%0,%1"
3428   "&& reload_completed && REG_P (operands[1])"
3429   [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
3430    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
3432   operands[0] = gen_lowpart (SImode, operands[0]);
3433   operands[1] = gen_lowpart (SImode, operands[1]);
3434   operands[2] = GEN_INT (GET_MODE_BITSIZE (SImode)
3435                          - GET_MODE_BITSIZE (QImode));
3437   [(set_attr "move_type" "shift_shift,load")
3438    (set_attr "mode" "SI")])
3440 (define_insn "*extendqihi2_seb"
3441   [(set (match_operand:HI 0 "register_operand" "=d,d")
3442         (sign_extend:HI
3443              (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3444   "ISA_HAS_SEB_SEH"
3445   "@
3446    seb\t%0,%1
3447    lb\t%0,%1"
3448   [(set_attr "move_type" "signext,load")
3449    (set_attr "mode" "SI")])
3451 ;; Combiner patterns for truncate/sign_extend combinations.  The SI versions
3452 ;; use the shift/truncate patterns.
3454 (define_insn_and_split "*extenddi_truncate<mode>"
3455   [(set (match_operand:DI 0 "register_operand" "=d")
3456         (sign_extend:DI
3457             (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
3458   "TARGET_64BIT && !TARGET_MIPS16 && !ISA_HAS_EXTS"
3459   "#"
3460   "&& reload_completed"
3461   [(set (match_dup 2)
3462         (ashift:DI (match_dup 1)
3463                    (match_dup 3)))
3464    (set (match_dup 0)
3465         (ashiftrt:DI (match_dup 2)
3466                      (match_dup 3)))]
3468   operands[2] = gen_lowpart (DImode, operands[0]);
3469   operands[3] = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (<MODE>mode));
3471   [(set_attr "move_type" "shift_shift")
3472    (set_attr "mode" "DI")])
3474 (define_insn_and_split "*extendsi_truncate<mode>"
3475   [(set (match_operand:SI 0 "register_operand" "=d")
3476         (sign_extend:SI
3477             (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
3478   "TARGET_64BIT && !TARGET_MIPS16 && !ISA_HAS_EXTS"
3479   "#"
3480   "&& reload_completed"
3481   [(set (match_dup 2)
3482         (ashift:DI (match_dup 1)
3483                    (match_dup 3)))
3484    (set (match_dup 0)
3485         (truncate:SI (ashiftrt:DI (match_dup 2)
3486                                   (match_dup 3))))]
3488   operands[2] = gen_lowpart (DImode, operands[0]);
3489   operands[3] = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (<MODE>mode));
3491   [(set_attr "move_type" "shift_shift")
3492    (set_attr "mode" "SI")])
3494 (define_insn_and_split "*extendhi_truncateqi"
3495   [(set (match_operand:HI 0 "register_operand" "=d")
3496         (sign_extend:HI
3497             (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
3498   "TARGET_64BIT && !TARGET_MIPS16 && !ISA_HAS_EXTS"
3499   "#"
3500   "&& reload_completed"
3501   [(set (match_dup 2)
3502         (ashift:DI (match_dup 1)
3503                    (const_int 56)))
3504    (set (match_dup 0)
3505         (truncate:HI (ashiftrt:DI (match_dup 2)
3506                                   (const_int 56))))]
3508   operands[2] = gen_lowpart (DImode, operands[0]);
3510   [(set_attr "move_type" "shift_shift")
3511    (set_attr "mode" "SI")])
3513 (define_insn "*extend<GPR:mode>_truncate<SHORT:mode>_exts"
3514   [(set (match_operand:GPR 0 "register_operand" "=d")
3515         (sign_extend:GPR
3516             (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
3517   "TARGET_64BIT && !TARGET_MIPS16 && ISA_HAS_EXTS"
3519   operands[2] = GEN_INT (GET_MODE_BITSIZE (<SHORT:MODE>mode));
3520   return "exts\t%0,%1,0,%m2";
3522   [(set_attr "type" "arith")
3523    (set_attr "mode" "<GPR:MODE>")])
3525 (define_insn "*extendhi_truncateqi_exts"
3526   [(set (match_operand:HI 0 "register_operand" "=d")
3527         (sign_extend:HI
3528             (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
3529   "TARGET_64BIT && !TARGET_MIPS16 && ISA_HAS_EXTS"
3530   "exts\t%0,%1,0,7"
3531   [(set_attr "type" "arith")
3532    (set_attr "mode" "SI")])
3534 (define_insn "extendsfdf2"
3535   [(set (match_operand:DF 0 "register_operand" "=f")
3536         (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
3537   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3538   "cvt.d.s\t%0,%1"
3539   [(set_attr "type"     "fcvt")
3540    (set_attr "cnv_mode" "S2D")   
3541    (set_attr "mode"     "DF")])
3544 ;;  ....................
3546 ;;      CONVERSIONS
3548 ;;  ....................
3550 (define_expand "fix_truncdfsi2"
3551   [(set (match_operand:SI 0 "register_operand")
3552         (fix:SI (match_operand:DF 1 "register_operand")))]
3553   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3555   if (!ISA_HAS_TRUNC_W)
3556     {
3557       emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
3558       DONE;
3559     }
3562 (define_insn "fix_truncdfsi2_insn"
3563   [(set (match_operand:SI 0 "register_operand" "=f")
3564         (fix:SI (match_operand:DF 1 "register_operand" "f")))]
3565   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
3566   "trunc.w.d %0,%1"
3567   [(set_attr "type"     "fcvt")
3568    (set_attr "mode"     "DF")
3569    (set_attr "cnv_mode" "D2I")])
3571 (define_insn "fix_truncdfsi2_macro"
3572   [(set (match_operand:SI 0 "register_operand" "=f")
3573         (fix:SI (match_operand:DF 1 "register_operand" "f")))
3574    (clobber (match_scratch:DF 2 "=d"))]
3575   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
3577   if (mips_nomacro.nesting_level > 0)
3578     return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
3579   else
3580     return "trunc.w.d %0,%1,%2";
3582   [(set_attr "type"     "fcvt")
3583    (set_attr "mode"     "DF")
3584    (set_attr "cnv_mode" "D2I")
3585    (set_attr "insn_count" "9")])
3587 (define_expand "fix_truncsfsi2"
3588   [(set (match_operand:SI 0 "register_operand")
3589         (fix:SI (match_operand:SF 1 "register_operand")))]
3590   "TARGET_HARD_FLOAT"
3592   if (!ISA_HAS_TRUNC_W)
3593     {
3594       emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
3595       DONE;
3596     }
3599 (define_insn "fix_truncsfsi2_insn"
3600   [(set (match_operand:SI 0 "register_operand" "=f")
3601         (fix:SI (match_operand:SF 1 "register_operand" "f")))]
3602   "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
3603   "trunc.w.s %0,%1"
3604   [(set_attr "type"     "fcvt")
3605    (set_attr "mode"     "SF")
3606    (set_attr "cnv_mode" "S2I")])
3608 (define_insn "fix_truncsfsi2_macro"
3609   [(set (match_operand:SI 0 "register_operand" "=f")
3610         (fix:SI (match_operand:SF 1 "register_operand" "f")))
3611    (clobber (match_scratch:SF 2 "=d"))]
3612   "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
3614   if (mips_nomacro.nesting_level > 0)
3615     return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
3616   else
3617     return "trunc.w.s %0,%1,%2";
3619   [(set_attr "type"     "fcvt")
3620    (set_attr "mode"     "SF")
3621    (set_attr "cnv_mode" "S2I")
3622    (set_attr "insn_count" "9")])
3625 (define_insn "fix_truncdfdi2"
3626   [(set (match_operand:DI 0 "register_operand" "=f")
3627         (fix:DI (match_operand:DF 1 "register_operand" "f")))]
3628   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3629   "trunc.l.d %0,%1"
3630   [(set_attr "type"     "fcvt")
3631    (set_attr "mode"     "DF")
3632    (set_attr "cnv_mode" "D2I")])
3635 (define_insn "fix_truncsfdi2"
3636   [(set (match_operand:DI 0 "register_operand" "=f")
3637         (fix:DI (match_operand:SF 1 "register_operand" "f")))]
3638   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3639   "trunc.l.s %0,%1"
3640   [(set_attr "type"     "fcvt")
3641    (set_attr "mode"     "SF")
3642    (set_attr "cnv_mode" "S2I")])
3645 (define_insn "floatsidf2"
3646   [(set (match_operand:DF 0 "register_operand" "=f")
3647         (float:DF (match_operand:SI 1 "register_operand" "f")))]
3648   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3649   "cvt.d.w\t%0,%1"
3650   [(set_attr "type"     "fcvt")
3651    (set_attr "mode"     "DF")
3652    (set_attr "cnv_mode" "I2D")])
3655 (define_insn "floatdidf2"
3656   [(set (match_operand:DF 0 "register_operand" "=f")
3657         (float:DF (match_operand:DI 1 "register_operand" "f")))]
3658   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3659   "cvt.d.l\t%0,%1"
3660   [(set_attr "type"     "fcvt")
3661    (set_attr "mode"     "DF")
3662    (set_attr "cnv_mode" "I2D")])
3665 (define_insn "floatsisf2"
3666   [(set (match_operand:SF 0 "register_operand" "=f")
3667         (float:SF (match_operand:SI 1 "register_operand" "f")))]
3668   "TARGET_HARD_FLOAT"
3669   "cvt.s.w\t%0,%1"
3670   [(set_attr "type"     "fcvt")
3671    (set_attr "mode"     "SF")
3672    (set_attr "cnv_mode" "I2S")])
3675 (define_insn "floatdisf2"
3676   [(set (match_operand:SF 0 "register_operand" "=f")
3677         (float:SF (match_operand:DI 1 "register_operand" "f")))]
3678   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3679   "cvt.s.l\t%0,%1"
3680   [(set_attr "type"     "fcvt")
3681    (set_attr "mode"     "SF")
3682    (set_attr "cnv_mode" "I2S")])
3685 (define_expand "fixuns_truncdfsi2"
3686   [(set (match_operand:SI 0 "register_operand")
3687         (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
3688   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3690   rtx reg1 = gen_reg_rtx (DFmode);
3691   rtx reg2 = gen_reg_rtx (DFmode);
3692   rtx reg3 = gen_reg_rtx (SImode);
3693   rtx label1 = gen_label_rtx ();
3694   rtx label2 = gen_label_rtx ();
3695   rtx test;
3696   REAL_VALUE_TYPE offset;
3698   real_2expN (&offset, 31, DFmode);
3700   if (reg1)                     /* Turn off complaints about unreached code.  */
3701     {
3702       mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3703       do_pending_stack_adjust ();
3705       test = gen_rtx_GE (VOIDmode, operands[1], reg1);
3706       emit_jump_insn (gen_cbranchdf4 (test, operands[1], reg1, label1));
3708       emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
3709       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3710                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
3711       emit_barrier ();
3713       emit_label (label1);
3714       mips_emit_move (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3715       mips_emit_move (reg3, GEN_INT (trunc_int_for_mode
3716                                      (BITMASK_HIGH, SImode)));
3718       emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
3719       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3721       emit_label (label2);
3723       /* Allow REG_NOTES to be set on last insn (labels don't have enough
3724          fields, and can't be used for REG_NOTES anyway).  */
3725       emit_use (stack_pointer_rtx);
3726       DONE;
3727     }
3731 (define_expand "fixuns_truncdfdi2"
3732   [(set (match_operand:DI 0 "register_operand")
3733         (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
3734   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3736   rtx reg1 = gen_reg_rtx (DFmode);
3737   rtx reg2 = gen_reg_rtx (DFmode);
3738   rtx reg3 = gen_reg_rtx (DImode);
3739   rtx label1 = gen_label_rtx ();
3740   rtx label2 = gen_label_rtx ();
3741   rtx test;
3742   REAL_VALUE_TYPE offset;
3744   real_2expN (&offset, 63, DFmode);
3746   mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3747   do_pending_stack_adjust ();
3749   test = gen_rtx_GE (VOIDmode, operands[1], reg1);
3750   emit_jump_insn (gen_cbranchdf4 (test, operands[1], reg1, label1));
3752   emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
3753   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3754                                gen_rtx_LABEL_REF (VOIDmode, label2)));
3755   emit_barrier ();
3757   emit_label (label1);
3758   mips_emit_move (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3759   mips_emit_move (reg3, GEN_INT (BITMASK_HIGH));
3760   emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3762   emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
3763   emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3765   emit_label (label2);
3767   /* Allow REG_NOTES to be set on last insn (labels don't have enough
3768      fields, and can't be used for REG_NOTES anyway).  */
3769   emit_use (stack_pointer_rtx);
3770   DONE;
3774 (define_expand "fixuns_truncsfsi2"
3775   [(set (match_operand:SI 0 "register_operand")
3776         (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
3777   "TARGET_HARD_FLOAT"
3779   rtx reg1 = gen_reg_rtx (SFmode);
3780   rtx reg2 = gen_reg_rtx (SFmode);
3781   rtx reg3 = gen_reg_rtx (SImode);
3782   rtx label1 = gen_label_rtx ();
3783   rtx label2 = gen_label_rtx ();
3784   rtx test;
3785   REAL_VALUE_TYPE offset;
3787   real_2expN (&offset, 31, SFmode);
3789   mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3790   do_pending_stack_adjust ();
3792   test = gen_rtx_GE (VOIDmode, operands[1], reg1);
3793   emit_jump_insn (gen_cbranchsf4 (test, operands[1], reg1, label1));
3795   emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
3796   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3797                                gen_rtx_LABEL_REF (VOIDmode, label2)));
3798   emit_barrier ();
3800   emit_label (label1);
3801   mips_emit_move (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3802   mips_emit_move (reg3, GEN_INT (trunc_int_for_mode
3803                                  (BITMASK_HIGH, SImode)));
3805   emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
3806   emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3808   emit_label (label2);
3810   /* Allow REG_NOTES to be set on last insn (labels don't have enough
3811      fields, and can't be used for REG_NOTES anyway).  */
3812   emit_use (stack_pointer_rtx);
3813   DONE;
3817 (define_expand "fixuns_truncsfdi2"
3818   [(set (match_operand:DI 0 "register_operand")
3819         (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
3820   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3822   rtx reg1 = gen_reg_rtx (SFmode);
3823   rtx reg2 = gen_reg_rtx (SFmode);
3824   rtx reg3 = gen_reg_rtx (DImode);
3825   rtx label1 = gen_label_rtx ();
3826   rtx label2 = gen_label_rtx ();
3827   rtx test;
3828   REAL_VALUE_TYPE offset;
3830   real_2expN (&offset, 63, SFmode);
3832   mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3833   do_pending_stack_adjust ();
3835   test = gen_rtx_GE (VOIDmode, operands[1], reg1);
3836   emit_jump_insn (gen_cbranchsf4 (test, operands[1], reg1, label1));
3838   emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
3839   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3840                                gen_rtx_LABEL_REF (VOIDmode, label2)));
3841   emit_barrier ();
3843   emit_label (label1);
3844   mips_emit_move (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3845   mips_emit_move (reg3, GEN_INT (BITMASK_HIGH));
3846   emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3848   emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
3849   emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3851   emit_label (label2);
3853   /* Allow REG_NOTES to be set on last insn (labels don't have enough
3854      fields, and can't be used for REG_NOTES anyway).  */
3855   emit_use (stack_pointer_rtx);
3856   DONE;
3860 ;;  ....................
3862 ;;      DATA MOVEMENT
3864 ;;  ....................
3866 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
3868 (define_expand "extvmisalign<mode>"
3869   [(set (match_operand:GPR 0 "register_operand")
3870         (sign_extract:GPR (match_operand:BLK 1 "memory_operand")
3871                           (match_operand 2 "const_int_operand")
3872                           (match_operand 3 "const_int_operand")))]
3873   "!TARGET_MIPS16"
3875   if (mips_expand_ext_as_unaligned_load (operands[0], operands[1],
3876                                          INTVAL (operands[2]),
3877                                          INTVAL (operands[3]),
3878                                          /*unsigned=*/ false))
3879     DONE;
3880   else
3881     FAIL;
3884 (define_expand "extv<mode>"
3885   [(set (match_operand:GPR 0 "register_operand")
3886         (sign_extract:GPR (match_operand:GPR 1 "register_operand")
3887                           (match_operand 2 "const_int_operand")
3888                           (match_operand 3 "const_int_operand")))]
3889   "ISA_HAS_EXTS"
3891   if (UINTVAL (operands[2]) > 32)
3892     FAIL;
3895 (define_insn "*extv<mode>"
3896   [(set (match_operand:GPR 0 "register_operand" "=d")
3897         (sign_extract:GPR (match_operand:GPR 1 "register_operand" "d")
3898                           (match_operand 2 "const_int_operand" "")
3899                           (match_operand 3 "const_int_operand" "")))]
3900   "ISA_HAS_EXTS && UINTVAL (operands[2]) <= 32"
3901   "exts\t%0,%1,%3,%m2"
3902   [(set_attr "type"     "arith")
3903    (set_attr "mode"     "<MODE>")])
3905 (define_expand "extzvmisalign<mode>"
3906   [(set (match_operand:GPR 0 "register_operand")
3907         (zero_extract:GPR (match_operand:BLK 1 "memory_operand")
3908                           (match_operand 2 "const_int_operand")
3909                           (match_operand 3 "const_int_operand")))]
3910   "!TARGET_MIPS16"
3912   if (mips_expand_ext_as_unaligned_load (operands[0], operands[1],
3913                                          INTVAL (operands[2]),
3914                                          INTVAL (operands[3]),
3915                                          /*unsigned=*/ true))
3916     DONE;
3917   else
3918     FAIL;
3921 (define_expand "extzv<mode>"
3922   [(set (match_operand:GPR 0 "register_operand")
3923         (zero_extract:GPR (match_operand:GPR 1 "register_operand")
3924                           (match_operand 2 "const_int_operand")
3925                           (match_operand 3 "const_int_operand")))]
3926   ""
3928   if (!mips_use_ins_ext_p (operands[1], INTVAL (operands[2]),
3929                            INTVAL (operands[3])))
3930     FAIL;
3933 (define_insn "*extzv<mode>"
3934   [(set (match_operand:GPR 0 "register_operand" "=d")
3935         (zero_extract:GPR (match_operand:GPR 1 "register_operand" "d")
3936                           (match_operand 2 "const_int_operand" "")
3937                           (match_operand 3 "const_int_operand" "")))]
3938   "mips_use_ins_ext_p (operands[1], INTVAL (operands[2]),
3939                        INTVAL (operands[3]))"
3940   "<d>ext\t%0,%1,%3,%2"
3941   [(set_attr "type"     "arith")
3942    (set_attr "mode"     "<MODE>")])
3944 (define_insn "*extzv_truncsi_exts"
3945   [(set (match_operand:SI 0 "register_operand" "=d")
3946         (truncate:SI
3947          (zero_extract:DI (match_operand:DI 1 "register_operand" "d")
3948                           (match_operand 2 "const_int_operand" "")
3949                           (match_operand 3 "const_int_operand" ""))))]
3950   "ISA_HAS_EXTS && TARGET_64BIT && IN_RANGE (INTVAL (operands[2]), 32, 63)"
3951   "exts\t%0,%1,%3,31"
3952   [(set_attr "type"     "arith")
3953    (set_attr "mode"     "SI")])
3956 (define_expand "insvmisalign<mode>"
3957   [(set (zero_extract:GPR (match_operand:BLK 0 "memory_operand")
3958                           (match_operand 1 "const_int_operand")
3959                           (match_operand 2 "const_int_operand"))
3960         (match_operand:GPR 3 "reg_or_0_operand"))]
3961   "!TARGET_MIPS16"
3963   if (mips_expand_ins_as_unaligned_store (operands[0], operands[3],
3964                                           INTVAL (operands[1]),
3965                                           INTVAL (operands[2])))
3966     DONE;
3967   else
3968     FAIL;
3971 (define_expand "insv<mode>"
3972   [(set (zero_extract:GPR (match_operand:GPR 0 "register_operand")
3973                           (match_operand 1 "const_int_operand")
3974                           (match_operand 2 "const_int_operand"))
3975         (match_operand:GPR 3 "reg_or_0_operand"))]
3976   ""
3978   if (!mips_use_ins_ext_p (operands[0], INTVAL (operands[1]),
3979                            INTVAL (operands[2])))
3980     FAIL;
3983 (define_insn "*insv<mode>"
3984   [(set (zero_extract:GPR (match_operand:GPR 0 "register_operand" "+d")
3985                           (match_operand:SI 1 "const_int_operand" "")
3986                           (match_operand:SI 2 "const_int_operand" ""))
3987         (match_operand:GPR 3 "reg_or_0_operand" "dJ"))]
3988   "mips_use_ins_ext_p (operands[0], INTVAL (operands[1]),
3989                        INTVAL (operands[2]))"
3990   "<d>ins\t%0,%z3,%2,%1"
3991   [(set_attr "type"     "arith")
3992    (set_attr "mode"     "<MODE>")])
3994 ;; Combiner pattern for cins (clear and insert bit field).  We can
3995 ;; implement mask-and-shift-left operation with this.  Note that if
3996 ;; the upper bit of the mask is set in an SImode operation, the mask
3997 ;; itself will be sign-extended.  mask_low_and_shift_len will
3998 ;; therefore be greater than our threshold of 32.
4000 (define_insn "*cins<mode>"
4001   [(set (match_operand:GPR 0 "register_operand" "=d")
4002         (and:GPR
4003          (ashift:GPR (match_operand:GPR 1 "register_operand" "d")
4004                      (match_operand:GPR 2 "const_int_operand" ""))
4005          (match_operand:GPR 3 "const_int_operand" "")))]
4006   "ISA_HAS_CINS
4007    && mask_low_and_shift_p (<MODE>mode, operands[3], operands[2], 32)"
4009   operands[3] =
4010     GEN_INT (mask_low_and_shift_len (<MODE>mode, operands[3], operands[2]));
4011   return "cins\t%0,%1,%2,%m3";
4013   [(set_attr "type"     "shift")
4014    (set_attr "mode"     "<MODE>")])
4016 ;; Unaligned word moves generated by the bit field patterns.
4018 ;; As far as the rtl is concerned, both the left-part and right-part
4019 ;; instructions can access the whole field.  However, the real operand
4020 ;; refers to just the first or the last byte (depending on endianness).
4021 ;; We therefore use two memory operands to each instruction, one to
4022 ;; describe the rtl effect and one to use in the assembly output.
4024 ;; Operands 0 and 1 are the rtl-level target and source respectively.
4025 ;; This allows us to use the standard length calculations for the "load"
4026 ;; and "store" type attributes.
4028 (define_insn "mov_<load>l"
4029   [(set (match_operand:GPR 0 "register_operand" "=d")
4030         (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
4031                      (match_operand:QI 2 "memory_operand" "ZC")]
4032                     UNSPEC_LOAD_LEFT))]
4033   "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
4034   "<load>l\t%0,%2"
4035   [(set_attr "move_type" "load")
4036    (set_attr "mode" "<MODE>")])
4038 (define_insn "mov_<load>r"
4039   [(set (match_operand:GPR 0 "register_operand" "=d")
4040         (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
4041                      (match_operand:QI 2 "memory_operand" "ZC")
4042                      (match_operand:GPR 3 "register_operand" "0")]
4043                     UNSPEC_LOAD_RIGHT))]
4044   "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
4045   "<load>r\t%0,%2"
4046   [(set_attr "move_type" "load")
4047    (set_attr "mode" "<MODE>")])
4049 (define_insn "mov_<store>l"
4050   [(set (match_operand:BLK 0 "memory_operand" "=m")
4051         (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
4052                      (match_operand:QI 2 "memory_operand" "ZC")]
4053                     UNSPEC_STORE_LEFT))]
4054   "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
4055   "<store>l\t%z1,%2"
4056   [(set_attr "move_type" "store")
4057    (set_attr "mode" "<MODE>")])
4059 (define_insn "mov_<store>r"
4060   [(set (match_operand:BLK 0 "memory_operand" "+m")
4061         (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
4062                      (match_operand:QI 2 "memory_operand" "ZC")
4063                      (match_dup 0)]
4064                     UNSPEC_STORE_RIGHT))]
4065   "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
4066   "<store>r\t%z1,%2"
4067   [(set_attr "move_type" "store")
4068    (set_attr "mode" "<MODE>")])
4070 ;; An instruction to calculate the high part of a 64-bit SYMBOL_ABSOLUTE.
4071 ;; The required value is:
4073 ;;      (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
4075 ;; which translates to:
4077 ;;      lui     op0,%highest(op1)
4078 ;;      daddiu  op0,op0,%higher(op1)
4079 ;;      dsll    op0,op0,16
4080 ;;      daddiu  op0,op0,%hi(op1)
4081 ;;      dsll    op0,op0,16
4083 ;; The split is deferred until after flow2 to allow the peephole2 below
4084 ;; to take effect.
4085 (define_insn_and_split "*lea_high64"
4086   [(set (match_operand:DI 0 "register_operand" "=d")
4087         (high:DI (match_operand:DI 1 "absolute_symbolic_operand" "")))]
4088   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
4089   "#"
4090   "&& epilogue_completed"
4091   [(set (match_dup 0) (high:DI (match_dup 2)))
4092    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
4093    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
4094    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
4095    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
4097   operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
4098   operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
4100   [(set_attr "insn_count" "5")])
4102 ;; Use a scratch register to reduce the latency of the above pattern
4103 ;; on superscalar machines.  The optimized sequence is:
4105 ;;      lui     op1,%highest(op2)
4106 ;;      lui     op0,%hi(op2)
4107 ;;      daddiu  op1,op1,%higher(op2)
4108 ;;      dsll32  op1,op1,0
4109 ;;      daddu   op1,op1,op0
4110 (define_peephole2
4111   [(set (match_operand:DI 1 "d_operand")
4112         (high:DI (match_operand:DI 2 "absolute_symbolic_operand")))
4113    (match_scratch:DI 0 "d")]
4114   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
4115   [(set (match_dup 1) (high:DI (match_dup 3)))
4116    (set (match_dup 0) (high:DI (match_dup 4)))
4117    (set (match_dup 1) (lo_sum:DI (match_dup 1) (match_dup 3)))
4118    (set (match_dup 1) (ashift:DI (match_dup 1) (const_int 32)))
4119    (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 0)))]
4121   operands[3] = mips_unspec_address (operands[2], SYMBOL_64_HIGH);
4122   operands[4] = mips_unspec_address (operands[2], SYMBOL_64_LOW);
4125 ;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
4126 ;; SYMBOL_ABSOLUTE X will take 6 cycles.  This next pattern allows combine
4127 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
4128 ;; used once.  We can then use the sequence:
4130 ;;      lui     op0,%highest(op1)
4131 ;;      lui     op2,%hi(op1)
4132 ;;      daddiu  op0,op0,%higher(op1)
4133 ;;      daddiu  op2,op2,%lo(op1)
4134 ;;      dsll32  op0,op0,0
4135 ;;      daddu   op0,op0,op2
4137 ;; which takes 4 cycles on most superscalar targets.
4138 (define_insn_and_split "*lea64"
4139   [(set (match_operand:DI 0 "register_operand" "=d")
4140         (match_operand:DI 1 "absolute_symbolic_operand" ""))
4141    (clobber (match_scratch:DI 2 "=&d"))]
4142   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
4143   "#"
4144   "&& reload_completed"
4145   [(set (match_dup 0) (high:DI (match_dup 3)))
4146    (set (match_dup 2) (high:DI (match_dup 4)))
4147    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
4148    (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
4149    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
4150    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
4152   operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
4153   operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
4155   [(set_attr "insn_count" "6")])
4157 ;; Split HIGHs into:
4159 ;;      li op0,%hi(sym)
4160 ;;      sll op0,16
4162 ;; on MIPS16 targets.
4163 (define_split
4164   [(set (match_operand:P 0 "d_operand")
4165         (high:P (match_operand:P 1 "symbolic_operand_with_high")))]
4166   "TARGET_MIPS16 && reload_completed"
4167   [(set (match_dup 0) (unspec:P [(match_dup 1)] UNSPEC_UNSHIFTED_HIGH))
4168    (set (match_dup 0) (ashift:P (match_dup 0) (const_int 16)))])
4170 (define_insn "*unshifted_high"
4171   [(set (match_operand:P 0 "d_operand" "=d")
4172         (unspec:P [(match_operand:P 1 "symbolic_operand_with_high")]
4173                   UNSPEC_UNSHIFTED_HIGH))]
4174   ""
4175   "li\t%0,%h1"
4176   [(set_attr "extended_mips16" "yes")])
4178 ;; Insns to fetch a symbol from a big GOT.
4180 (define_insn_and_split "*xgot_hi<mode>"
4181   [(set (match_operand:P 0 "register_operand" "=d")
4182         (high:P (match_operand:P 1 "got_disp_operand" "")))]
4183   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
4184   "#"
4185   "&& reload_completed"
4186   [(set (match_dup 0) (high:P (match_dup 2)))
4187    (set (match_dup 0) (plus:P (match_dup 0) (match_dup 3)))]
4189   operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_DISP);
4190   operands[3] = pic_offset_table_rtx;
4192   [(set_attr "got" "xgot_high")
4193    (set_attr "mode" "<MODE>")])
4195 (define_insn_and_split "*xgot_lo<mode>"
4196   [(set (match_operand:P 0 "register_operand" "=d")
4197         (lo_sum:P (match_operand:P 1 "register_operand" "d")
4198                   (match_operand:P 2 "got_disp_operand" "")))]
4199   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
4200   "#"
4201   "&& reload_completed"
4202   [(set (match_dup 0)
4203         (unspec:P [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
4204   { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_DISP); }
4205   [(set_attr "got" "load")
4206    (set_attr "mode" "<MODE>")])
4208 ;; Insns to fetch a symbol from a normal GOT.
4210 (define_insn_and_split "*got_disp<mode>"
4211   [(set (match_operand:P 0 "register_operand" "=d")
4212         (match_operand:P 1 "got_disp_operand" ""))]
4213   "TARGET_EXPLICIT_RELOCS && !mips_split_p[SYMBOL_GOT_DISP]"
4214   "#"
4215   "&& reload_completed"
4216   [(set (match_dup 0) (match_dup 2))]
4217   { operands[2] = mips_got_load (NULL, operands[1], SYMBOL_GOTOFF_DISP); }
4218   [(set_attr "got" "load")
4219    (set_attr "mode" "<MODE>")])
4221 ;; Insns for loading the "page" part of a page/ofst address from the GOT.
4223 (define_insn_and_split "*got_page<mode>"
4224   [(set (match_operand:P 0 "register_operand" "=d")
4225         (high:P (match_operand:P 1 "got_page_ofst_operand" "")))]
4226   "TARGET_EXPLICIT_RELOCS && !mips_split_hi_p[SYMBOL_GOT_PAGE_OFST]"
4227   "#"
4228   "&& reload_completed"
4229   [(set (match_dup 0) (match_dup 2))]
4230   { operands[2] = mips_got_load (NULL, operands[1], SYMBOL_GOTOFF_PAGE); }
4231   [(set_attr "got" "load")
4232    (set_attr "mode" "<MODE>")])
4234 ;; Convenience expander that generates the rhs of a load_got<mode> insn.
4235 (define_expand "unspec_got_<mode>"
4236   [(unspec:P [(match_operand:P 0)
4237               (match_operand:P 1)] UNSPEC_LOAD_GOT)])
4239 ;; Lower-level instructions for loading an address from the GOT.
4240 ;; We could use MEMs, but an unspec gives more optimization
4241 ;; opportunities.
4243 (define_insn "load_got<mode>"
4244   [(set (match_operand:P 0 "register_operand" "=d")
4245         (unspec:P [(match_operand:P 1 "register_operand" "d")
4246                    (match_operand:P 2 "immediate_operand" "")]
4247                   UNSPEC_LOAD_GOT))]
4248   ""
4249   "<load>\t%0,%R2(%1)"
4250   [(set_attr "got" "load")
4251    (set_attr "mode" "<MODE>")])
4253 ;; Instructions for adding the low 16 bits of an address to a register.
4254 ;; Operand 2 is the address: mips_print_operand works out which relocation
4255 ;; should be applied.
4257 (define_insn "*low<mode>"
4258   [(set (match_operand:P 0 "register_operand" "=d")
4259         (lo_sum:P (match_operand:P 1 "register_operand" "d")
4260                   (match_operand:P 2 "immediate_operand" "")))]
4261   "!TARGET_MIPS16"
4262   "<d>addiu\t%0,%1,%R2"
4263   [(set_attr "alu_type" "add")
4264    (set_attr "mode" "<MODE>")])
4266 (define_insn "*low<mode>_mips16"
4267   [(set (match_operand:P 0 "register_operand" "=d")
4268         (lo_sum:P (match_operand:P 1 "register_operand" "0")
4269                   (match_operand:P 2 "immediate_operand" "")))]
4270   "TARGET_MIPS16"
4271   "<d>addiu\t%0,%R2"
4272   [(set_attr "alu_type" "add")
4273    (set_attr "mode" "<MODE>")
4274    (set_attr "extended_mips16" "yes")])
4276 ;; Expose MIPS16 uses of the global pointer after reload if the function
4277 ;; is responsible for setting up the register itself.
4278 (define_split
4279   [(set (match_operand:GPR 0 "d_operand")
4280         (const:GPR (unspec:GPR [(const_int 0)] UNSPEC_GP)))]
4281   "TARGET_MIPS16 && TARGET_USE_GOT && reload_completed"
4282   [(set (match_dup 0) (match_dup 1))]
4283   { operands[1] = pic_offset_table_rtx; })
4285 ;; Allow combine to split complex const_int load sequences, using operand 2
4286 ;; to store the intermediate results.  See move_operand for details.
4287 (define_split
4288   [(set (match_operand:GPR 0 "register_operand")
4289         (match_operand:GPR 1 "splittable_const_int_operand"))
4290    (clobber (match_operand:GPR 2 "register_operand"))]
4291   ""
4292   [(const_int 0)]
4294   mips_move_integer (operands[2], operands[0], INTVAL (operands[1]));
4295   DONE;
4298 ;; Likewise, for symbolic operands.
4299 (define_split
4300   [(set (match_operand:P 0 "register_operand")
4301         (match_operand:P 1))
4302    (clobber (match_operand:P 2 "register_operand"))]
4303   "mips_split_symbol (operands[2], operands[1], MAX_MACHINE_MODE, NULL)"
4304   [(set (match_dup 0) (match_dup 3))]
4306   mips_split_symbol (operands[2], operands[1],
4307                      MAX_MACHINE_MODE, &operands[3]);
4310 ;; 64-bit integer moves
4312 ;; Unlike most other insns, the move insns can't be split with
4313 ;; different predicates, because register spilling and other parts of
4314 ;; the compiler, have memoized the insn number already.
4316 (define_expand "movdi"
4317   [(set (match_operand:DI 0 "")
4318         (match_operand:DI 1 ""))]
4319   ""
4321   if (mips_legitimize_move (DImode, operands[0], operands[1]))
4322     DONE;
4325 ;; For mips16, we need a special case to handle storing $31 into
4326 ;; memory, since we don't have a constraint to match $31.  This
4327 ;; instruction can be generated by save_restore_insns.
4329 (define_insn "*mov<mode>_ra"
4330   [(set (match_operand:GPR 0 "stack_operand" "=m")
4331         (reg:GPR RETURN_ADDR_REGNUM))]
4332   "TARGET_MIPS16"
4333   "<store>\t$31,%0"
4334   [(set_attr "move_type" "store")
4335    (set_attr "mode" "<MODE>")])
4337 (define_insn "*movdi_32bit"
4338   [(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")
4339         (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"))]
4340   "!TARGET_64BIT && !TARGET_MIPS16
4341    && (register_operand (operands[0], DImode)
4342        || reg_or_0_operand (operands[1], DImode))"
4343   { return mips_output_move (operands[0], operands[1]); }
4344   [(set_attr "move_type" "move,const,load,store,imul,mtlo,mflo,mtc,fpload,mfc,fpstore,mtc,fpload,mfc,fpstore")
4345    (set (attr "mode")
4346         (if_then_else (eq_attr "move_type" "imul")
4347                       (const_string "SI")
4348                       (const_string "DI")))])
4350 (define_insn "*movdi_32bit_mips16"
4351   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4352         (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
4353   "!TARGET_64BIT && TARGET_MIPS16
4354    && (register_operand (operands[0], DImode)
4355        || register_operand (operands[1], DImode))"
4356   { return mips_output_move (operands[0], operands[1]); }
4357   [(set_attr "move_type" "move,move,move,const,constN,load,store,mflo")
4358    (set_attr "mode" "DI")])
4360 (define_insn "*movdi_64bit"
4361   [(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")
4362         (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"))]
4363   "TARGET_64BIT && !TARGET_MIPS16
4364    && (register_operand (operands[0], DImode)
4365        || reg_or_0_operand (operands[1], DImode))"
4366   { return mips_output_move (operands[0], operands[1]); }
4367   [(set_attr "move_type" "move,const,const,load,store,mtc,fpload,mfc,fpstore,mtlo,mflo,mtc,fpload,mfc,fpstore")
4368    (set_attr "mode" "DI")])
4370 (define_insn "*movdi_64bit_mips16"
4371   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,m,*d")
4372         (match_operand:DI 1 "move_operand" "d,d,y,K,N,Yd,kf,m,d,*a"))]
4373   "TARGET_64BIT && TARGET_MIPS16
4374    && (register_operand (operands[0], DImode)
4375        || register_operand (operands[1], DImode))"
4376   { return mips_output_move (operands[0], operands[1]); }
4377   [(set_attr "move_type" "move,move,move,const,constN,const,loadpool,load,store,mflo")
4378    (set_attr "mode" "DI")])
4380 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
4381 ;; when the original load is a 4 byte instruction but the add and the
4382 ;; load are 2 2 byte instructions.
4384 (define_split
4385   [(set (match_operand:DI 0 "d_operand")
4386         (mem:DI (plus:DI (match_dup 0)
4387                          (match_operand:DI 1 "const_int_operand"))))]
4388   "TARGET_64BIT && TARGET_MIPS16 && reload_completed
4389    && !TARGET_DEBUG_D_MODE
4390    && ((INTVAL (operands[1]) < 0
4391         && INTVAL (operands[1]) >= -0x10)
4392        || (INTVAL (operands[1]) >= 32 * 8
4393            && INTVAL (operands[1]) <= 31 * 8 + 0x8)
4394        || (INTVAL (operands[1]) >= 0
4395            && INTVAL (operands[1]) < 32 * 8
4396            && (INTVAL (operands[1]) & 7) != 0))"
4397   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
4398    (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
4400   HOST_WIDE_INT val = INTVAL (operands[1]);
4402   if (val < 0)
4403     operands[2] = const0_rtx;
4404   else if (val >= 32 * 8)
4405     {
4406       int off = val & 7;
4408       operands[1] = GEN_INT (0x8 + off);
4409       operands[2] = GEN_INT (val - off - 0x8);
4410     }
4411   else
4412     {
4413       int off = val & 7;
4415       operands[1] = GEN_INT (off);
4416       operands[2] = GEN_INT (val - off);
4417     }
4420 ;; 32-bit Integer moves
4422 ;; Unlike most other insns, the move insns can't be split with
4423 ;; different predicates, because register spilling and other parts of
4424 ;; the compiler, have memoized the insn number already.
4426 (define_expand "mov<mode>"
4427   [(set (match_operand:IMOVE32 0 "")
4428         (match_operand:IMOVE32 1 ""))]
4429   ""
4431   if (mips_legitimize_move (<MODE>mode, operands[0], operands[1]))
4432     DONE;
4435 ;; The difference between these two is whether or not ints are allowed
4436 ;; in FP registers (off by default, use -mdebugh to enable).
4438 (define_insn "*mov<mode>_internal"
4439   [(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")
4440         (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"))]
4441   "!TARGET_MIPS16
4442    && (register_operand (operands[0], <MODE>mode)
4443        || reg_or_0_operand (operands[1], <MODE>mode))"
4444   { return mips_output_move (operands[0], operands[1]); }
4445   [(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")
4446    (set_attr "compression" "all,micromips,micromips,*,*,micromips,micromips,*,micromips,micromips,*,*,*,*,*,*,*,*,*,*,*,*,*")
4447    (set_attr "mode" "SI")])
4449 (define_insn "*mov<mode>_mips16"
4450   [(set (match_operand:IMOVE32 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,m,*d")
4451         (match_operand:IMOVE32 1 "move_operand" "d,d,y,K,N,Yd,kf,m,d,*a"))]
4452   "TARGET_MIPS16
4453    && (register_operand (operands[0], <MODE>mode)
4454        || register_operand (operands[1], <MODE>mode))"
4455   { return mips_output_move (operands[0], operands[1]); }
4456   [(set_attr "move_type" "move,move,move,const,constN,const,loadpool,load,store,mflo")
4457    (set_attr "mode" "SI")])
4459 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
4460 ;; when the original load is a 4 byte instruction but the add and the
4461 ;; load are 2 2 byte instructions.
4463 (define_split
4464   [(set (match_operand:SI 0 "d_operand")
4465         (mem:SI (plus:SI (match_dup 0)
4466                          (match_operand:SI 1 "const_int_operand"))))]
4467   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4468    && ((INTVAL (operands[1]) < 0
4469         && INTVAL (operands[1]) >= -0x80)
4470        || (INTVAL (operands[1]) >= 32 * 4
4471            && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
4472        || (INTVAL (operands[1]) >= 0
4473            && INTVAL (operands[1]) < 32 * 4
4474            && (INTVAL (operands[1]) & 3) != 0))"
4475   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4476    (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
4478   HOST_WIDE_INT val = INTVAL (operands[1]);
4480   if (val < 0)
4481     operands[2] = const0_rtx;
4482   else if (val >= 32 * 4)
4483     {
4484       int off = val & 3;
4486       operands[1] = GEN_INT (0x7c + off);
4487       operands[2] = GEN_INT (val - off - 0x7c);
4488     }
4489   else
4490     {
4491       int off = val & 3;
4493       operands[1] = GEN_INT (off);
4494       operands[2] = GEN_INT (val - off);
4495     }
4498 ;; On the mips16, we can split a load of certain constants into a load
4499 ;; and an add.  This turns a 4 byte instruction into 2 2 byte
4500 ;; instructions.
4502 (define_split
4503   [(set (match_operand:SI 0 "d_operand")
4504         (match_operand:SI 1 "const_int_operand"))]
4505   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4506    && INTVAL (operands[1]) >= 0x100
4507    && INTVAL (operands[1]) <= 0xff + 0x7f"
4508   [(set (match_dup 0) (match_dup 1))
4509    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
4511   int val = INTVAL (operands[1]);
4513   operands[1] = GEN_INT (0xff);
4514   operands[2] = GEN_INT (val - 0xff);
4517 ;; MIPS4 supports loading and storing a floating point register from
4518 ;; the sum of two general registers.  We use two versions for each of
4519 ;; these four instructions: one where the two general registers are
4520 ;; SImode, and one where they are DImode.  This is because general
4521 ;; registers will be in SImode when they hold 32-bit values, but,
4522 ;; since the 32-bit values are always sign extended, the [ls][wd]xc1
4523 ;; instructions will still work correctly.
4525 ;; ??? Perhaps it would be better to support these instructions by
4526 ;; modifying TARGET_LEGITIMATE_ADDRESS_P and friends.  However, since
4527 ;; these instructions can only be used to load and store floating
4528 ;; point registers, that would probably cause trouble in reload.
4530 (define_insn "*<ANYF:loadx>_<P:mode>"
4531   [(set (match_operand:ANYF 0 "register_operand" "=f")
4532         (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d")
4533                           (match_operand:P 2 "register_operand" "d"))))]
4534   "ISA_HAS_LXC1_SXC1"
4535   "<ANYF:loadx>\t%0,%1(%2)"
4536   [(set_attr "type" "fpidxload")
4537    (set_attr "mode" "<ANYF:UNITMODE>")])
4539 (define_insn "*<ANYF:storex>_<P:mode>"
4540   [(set (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d")
4541                           (match_operand:P 2 "register_operand" "d")))
4542         (match_operand:ANYF 0 "register_operand" "f"))]
4543   "ISA_HAS_LXC1_SXC1"
4544   "<ANYF:storex>\t%0,%1(%2)"
4545   [(set_attr "type" "fpidxstore")
4546    (set_attr "mode" "<ANYF:UNITMODE>")])
4548 ;; Scaled indexed address load.
4549 ;; Per md.texi, we only need to look for a pattern with multiply in the
4550 ;; address expression, not shift.
4552 (define_insn "*lwxs"
4553   [(set (match_operand:IMOVE32 0 "register_operand" "=d")
4554         (mem:IMOVE32
4555           (plus:P (mult:P (match_operand:P 1 "register_operand" "d")
4556                           (const_int 4))
4557                   (match_operand:P 2 "register_operand" "d"))))]
4558   "ISA_HAS_LWXS"
4559   "lwxs\t%0,%1(%2)"
4560   [(set_attr "type"     "load")
4561    (set_attr "mode"     "SI")])
4563 ;; 16-bit Integer moves
4565 ;; Unlike most other insns, the move insns can't be split with
4566 ;; different predicates, because register spilling and other parts of
4567 ;; the compiler, have memoized the insn number already.
4568 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4570 (define_expand "movhi"
4571   [(set (match_operand:HI 0 "")
4572         (match_operand:HI 1 ""))]
4573   ""
4575   if (mips_legitimize_move (HImode, operands[0], operands[1]))
4576     DONE;
4579 (define_insn "*movhi_internal"
4580   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,!u,d,!u,d,ZU,m,*a,*d")
4581         (match_operand:HI 1 "move_operand"         "d,J,I,ZU,m,!kbJ,dJ,*d*J,*a"))]
4582   "!TARGET_MIPS16
4583    && (register_operand (operands[0], HImode)
4584        || reg_or_0_operand (operands[1], HImode))"
4585   { return mips_output_move (operands[0], operands[1]); }
4586   [(set_attr "move_type" "move,const,const,load,load,store,store,mtlo,mflo")
4587    (set_attr "compression" "all,micromips,*,micromips,*,micromips,*,*,*")
4588    (set_attr "mode" "HI")])
4590 (define_insn "*movhi_mips16"
4591   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4592         (match_operand:HI 1 "move_operand"         "d,d,y,K,N,m,d,*a"))]
4593   "TARGET_MIPS16
4594    && (register_operand (operands[0], HImode)
4595        || register_operand (operands[1], HImode))"
4596   { return mips_output_move (operands[0], operands[1]); }
4597   [(set_attr "move_type" "move,move,move,const,constN,load,store,mflo")
4598    (set_attr "mode" "HI")])
4600 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
4601 ;; when the original load is a 4 byte instruction but the add and the
4602 ;; load are 2 2 byte instructions.
4604 (define_split
4605   [(set (match_operand:HI 0 "d_operand")
4606         (mem:HI (plus:SI (match_dup 0)
4607                          (match_operand:SI 1 "const_int_operand"))))]
4608   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4609    && ((INTVAL (operands[1]) < 0
4610         && INTVAL (operands[1]) >= -0x80)
4611        || (INTVAL (operands[1]) >= 32 * 2
4612            && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
4613        || (INTVAL (operands[1]) >= 0
4614            && INTVAL (operands[1]) < 32 * 2
4615            && (INTVAL (operands[1]) & 1) != 0))"
4616   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4617    (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
4619   HOST_WIDE_INT val = INTVAL (operands[1]);
4621   if (val < 0)
4622     operands[2] = const0_rtx;
4623   else if (val >= 32 * 2)
4624     {
4625       int off = val & 1;
4627       operands[1] = GEN_INT (0x7e + off);
4628       operands[2] = GEN_INT (val - off - 0x7e);
4629     }
4630   else
4631     {
4632       int off = val & 1;
4634       operands[1] = GEN_INT (off);
4635       operands[2] = GEN_INT (val - off);
4636     }
4639 ;; 8-bit Integer moves
4641 ;; Unlike most other insns, the move insns can't be split with
4642 ;; different predicates, because register spilling and other parts of
4643 ;; the compiler, have memoized the insn number already.
4644 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4646 (define_expand "movqi"
4647   [(set (match_operand:QI 0 "")
4648         (match_operand:QI 1 ""))]
4649   ""
4651   if (mips_legitimize_move (QImode, operands[0], operands[1]))
4652     DONE;
4655 (define_insn "*movqi_internal"
4656   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,!u,d,!u,d,ZV,m,*a,*d")
4657         (match_operand:QI 1 "move_operand"         "d,J,I,ZW,m,!kbJ,dJ,*d*J,*a"))]
4658   "!TARGET_MIPS16
4659    && (register_operand (operands[0], QImode)
4660        || reg_or_0_operand (operands[1], QImode))"
4661   { return mips_output_move (operands[0], operands[1]); }
4662   [(set_attr "move_type" "move,const,const,load,load,store,store,mtlo,mflo")
4663    (set_attr "compression" "all,micromips,*,micromips,*,micromips,*,*,*")
4664    (set_attr "mode" "QI")])
4666 (define_insn "*movqi_mips16"
4667   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4668         (match_operand:QI 1 "move_operand"         "d,d,y,K,N,m,d,*a"))]
4669   "TARGET_MIPS16
4670    && (register_operand (operands[0], QImode)
4671        || register_operand (operands[1], QImode))"
4672   { return mips_output_move (operands[0], operands[1]); }
4673   [(set_attr "move_type" "move,move,move,const,constN,load,store,mflo")
4674    (set_attr "mode" "QI")])
4676 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
4677 ;; when the original load is a 4 byte instruction but the add and the
4678 ;; load are 2 2 byte instructions.
4680 (define_split
4681   [(set (match_operand:QI 0 "d_operand")
4682         (mem:QI (plus:SI (match_dup 0)
4683                          (match_operand:SI 1 "const_int_operand"))))]
4684   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4685    && ((INTVAL (operands[1]) < 0
4686         && INTVAL (operands[1]) >= -0x80)
4687        || (INTVAL (operands[1]) >= 32
4688            && INTVAL (operands[1]) <= 31 + 0x7f))"
4689   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4690    (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
4692   HOST_WIDE_INT val = INTVAL (operands[1]);
4694   if (val < 0)
4695     operands[2] = const0_rtx;
4696   else
4697     {
4698       operands[1] = GEN_INT (0x7f);
4699       operands[2] = GEN_INT (val - 0x7f);
4700     }
4703 ;; 32-bit floating point moves
4705 (define_expand "movsf"
4706   [(set (match_operand:SF 0 "")
4707         (match_operand:SF 1 ""))]
4708   ""
4710   if (mips_legitimize_move (SFmode, operands[0], operands[1]))
4711     DONE;
4714 (define_insn "*movsf_hardfloat"
4715   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
4716         (match_operand:SF 1 "move_operand" "f,G,m,f,G,*d,*f,*G*d,*m,*d"))]
4717   "TARGET_HARD_FLOAT
4718    && (register_operand (operands[0], SFmode)
4719        || reg_or_0_operand (operands[1], SFmode))"
4720   { return mips_output_move (operands[0], operands[1]); }
4721   [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
4722    (set_attr "mode" "SF")])
4724 (define_insn "*movsf_softfloat"
4725   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
4726         (match_operand:SF 1 "move_operand" "Gd,m,d"))]
4727   "TARGET_SOFT_FLOAT && !TARGET_MIPS16
4728    && (register_operand (operands[0], SFmode)
4729        || reg_or_0_operand (operands[1], SFmode))"
4730   { return mips_output_move (operands[0], operands[1]); }
4731   [(set_attr "move_type" "move,load,store")
4732    (set_attr "mode" "SF")])
4734 (define_insn "*movsf_mips16"
4735   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
4736         (match_operand:SF 1 "move_operand" "d,d,y,m,d"))]
4737   "TARGET_MIPS16
4738    && (register_operand (operands[0], SFmode)
4739        || register_operand (operands[1], SFmode))"
4740   { return mips_output_move (operands[0], operands[1]); }
4741   [(set_attr "move_type" "move,move,move,load,store")
4742    (set_attr "mode" "SF")])
4744 ;; 64-bit floating point moves
4746 (define_expand "movdf"
4747   [(set (match_operand:DF 0 "")
4748         (match_operand:DF 1 ""))]
4749   ""
4751   if (mips_legitimize_move (DFmode, operands[0], operands[1]))
4752     DONE;
4755 (define_insn "*movdf_hardfloat"
4756   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
4757         (match_operand:DF 1 "move_operand" "f,G,m,f,G,*d,*f,*d*G,*m,*d"))]
4758   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
4759    && (register_operand (operands[0], DFmode)
4760        || reg_or_0_operand (operands[1], DFmode))"
4761   { return mips_output_move (operands[0], operands[1]); }
4762   [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
4763    (set_attr "mode" "DF")])
4765 (define_insn "*movdf_softfloat"
4766   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m")
4767         (match_operand:DF 1 "move_operand" "dG,m,dG"))]
4768   "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
4769    && (register_operand (operands[0], DFmode)
4770        || reg_or_0_operand (operands[1], DFmode))"
4771   { return mips_output_move (operands[0], operands[1]); }
4772   [(set_attr "move_type" "move,load,store")
4773    (set_attr "mode" "DF")])
4775 (define_insn "*movdf_mips16"
4776   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
4777         (match_operand:DF 1 "move_operand" "d,d,y,m,d"))]
4778   "TARGET_MIPS16
4779    && (register_operand (operands[0], DFmode)
4780        || register_operand (operands[1], DFmode))"
4781   { return mips_output_move (operands[0], operands[1]); }
4782   [(set_attr "move_type" "move,move,move,load,store")
4783    (set_attr "mode" "DF")])
4785 ;; 128-bit integer moves
4787 (define_expand "movti"
4788   [(set (match_operand:TI 0)
4789         (match_operand:TI 1))]
4790   "TARGET_64BIT"
4792   if (mips_legitimize_move (TImode, operands[0], operands[1]))
4793     DONE;
4796 (define_insn "*movti"
4797   [(set (match_operand:TI 0 "nonimmediate_operand" "=d,d,d,m,*a,*a,*d")
4798         (match_operand:TI 1 "move_operand" "d,i,m,dJ,*J,*d,*a"))]
4799   "TARGET_64BIT
4800    && !TARGET_MIPS16
4801    && (register_operand (operands[0], TImode)
4802        || reg_or_0_operand (operands[1], TImode))"
4803   { return mips_output_move (operands[0], operands[1]); }
4804   [(set_attr "move_type" "move,const,load,store,imul,mtlo,mflo")
4805    (set (attr "mode")
4806         (if_then_else (eq_attr "move_type" "imul")
4807                       (const_string "SI")
4808                       (const_string "TI")))])
4810 (define_insn "*movti_mips16"
4811   [(set (match_operand:TI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4812         (match_operand:TI 1 "move_operand" "d,d,y,K,N,m,d,*a"))]
4813   "TARGET_64BIT
4814    && TARGET_MIPS16
4815    && (register_operand (operands[0], TImode)
4816        || register_operand (operands[1], TImode))"
4817   "#"
4818   [(set_attr "move_type" "move,move,move,const,constN,load,store,mflo")
4819    (set_attr "mode" "TI")])
4821 ;; 128-bit floating point moves
4823 (define_expand "movtf"
4824   [(set (match_operand:TF 0)
4825         (match_operand:TF 1))]
4826   "TARGET_64BIT"
4828   if (mips_legitimize_move (TFmode, operands[0], operands[1]))
4829     DONE;
4832 ;; This pattern handles both hard- and soft-float cases.
4833 (define_insn "*movtf"
4834   [(set (match_operand:TF 0 "nonimmediate_operand" "=d,d,m,f,d,f,m")
4835         (match_operand:TF 1 "move_operand" "dG,m,dG,dG,f,m,f"))]
4836   "TARGET_64BIT
4837    && !TARGET_MIPS16
4838    && (register_operand (operands[0], TFmode)
4839        || reg_or_0_operand (operands[1], TFmode))"
4840   "#"
4841   [(set_attr "move_type" "move,load,store,mtc,mfc,fpload,fpstore")
4842    (set_attr "mode" "TF")])
4844 (define_insn "*movtf_mips16"
4845   [(set (match_operand:TF 0 "nonimmediate_operand" "=d,y,d,d,m")
4846         (match_operand:TF 1 "move_operand" "d,d,y,m,d"))]
4847   "TARGET_64BIT
4848    && TARGET_MIPS16
4849    && (register_operand (operands[0], TFmode)
4850        || register_operand (operands[1], TFmode))"
4851   "#"
4852   [(set_attr "move_type" "move,move,move,load,store")
4853    (set_attr "mode" "TF")])
4855 (define_split
4856   [(set (match_operand:MOVE64 0 "nonimmediate_operand")
4857         (match_operand:MOVE64 1 "move_operand"))]
4858   "reload_completed && mips_split_move_insn_p (operands[0], operands[1], insn)"
4859   [(const_int 0)]
4861   mips_split_move_insn (operands[0], operands[1], curr_insn);
4862   DONE;
4865 (define_split
4866   [(set (match_operand:MOVE128 0 "nonimmediate_operand")
4867         (match_operand:MOVE128 1 "move_operand"))]
4868   "reload_completed && mips_split_move_insn_p (operands[0], operands[1], insn)"
4869   [(const_int 0)]
4871   mips_split_move_insn (operands[0], operands[1], curr_insn);
4872   DONE;
4875 ;; When generating mips16 code, split moves of negative constants into
4876 ;; a positive "li" followed by a negation.
4877 (define_split
4878   [(set (match_operand 0 "d_operand")
4879         (match_operand 1 "const_int_operand"))]
4880   "TARGET_MIPS16 && reload_completed && INTVAL (operands[1]) < 0"
4881   [(set (match_dup 2)
4882         (match_dup 3))
4883    (set (match_dup 2)
4884         (neg:SI (match_dup 2)))]
4886   operands[2] = gen_lowpart (SImode, operands[0]);
4887   operands[3] = GEN_INT (-INTVAL (operands[1]));
4890 ;; 64-bit paired-single floating point moves
4892 (define_expand "movv2sf"
4893   [(set (match_operand:V2SF 0)
4894         (match_operand:V2SF 1))]
4895   "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
4897   if (mips_legitimize_move (V2SFmode, operands[0], operands[1]))
4898     DONE;
4901 (define_insn "*movv2sf"
4902   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
4903         (match_operand:V2SF 1 "move_operand" "f,YG,m,f,YG,*d,*f,*d*YG,*m,*d"))]
4904   "TARGET_HARD_FLOAT
4905    && TARGET_PAIRED_SINGLE_FLOAT
4906    && (register_operand (operands[0], V2SFmode)
4907        || reg_or_0_operand (operands[1], V2SFmode))"
4908   { return mips_output_move (operands[0], operands[1]); }
4909   [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
4910    (set_attr "mode" "DF")])
4912 ;; Extract the high part of a HI/LO value.  See mips_hard_regno_mode_ok_p
4913 ;; for the reason why we can't just use (reg:GPR HI_REGNUM).
4915 ;; When generating VR4120 or VR4130 code, we use MACCHI and DMACCHI
4916 ;; instead of MFHI.  This avoids both the normal MIPS III hi/lo hazards
4917 ;; and the errata related to -mfix-vr4130.
4918 (define_insn "mfhi<GPR:mode>_<HILO:mode>"
4919   [(set (match_operand:GPR 0 "register_operand" "=d")
4920         (unspec:GPR [(match_operand:HILO 1 "hilo_operand" "x")]
4921                     UNSPEC_MFHI))]
4922   ""
4923   { return ISA_HAS_MACCHI ? "<GPR:d>macchi\t%0,%.,%." : "mfhi\t%0"; }
4924   [(set_attr "type" "mfhi")
4925    (set_attr "mode" "<GPR:MODE>")])
4927 ;; Set the high part of a HI/LO value, given that the low part has
4928 ;; already been set.  See mips_hard_regno_mode_ok_p for the reason
4929 ;; why we can't just use (reg:GPR HI_REGNUM).
4930 (define_insn "mthi<GPR:mode>_<HILO:mode>"
4931   [(set (match_operand:HILO 0 "register_operand" "=x")
4932         (unspec:HILO [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
4933                       (match_operand:GPR 2 "register_operand" "l")]
4934                      UNSPEC_MTHI))]
4935   ""
4936   "mthi\t%z1"
4937   [(set_attr "type" "mthi")
4938    (set_attr "mode" "SI")])
4940 ;; Emit a doubleword move in which exactly one of the operands is
4941 ;; a floating-point register.  We can't just emit two normal moves
4942 ;; because of the constraints imposed by the FPU register model;
4943 ;; see mips_cannot_change_mode_class for details.  Instead, we keep
4944 ;; the FPR whole and use special patterns to refer to each word of
4945 ;; the other operand.
4947 (define_expand "move_doubleword_fpr<mode>"
4948   [(set (match_operand:SPLITF 0)
4949         (match_operand:SPLITF 1))]
4950   ""
4952   if (FP_REG_RTX_P (operands[0]))
4953     {
4954       rtx low = mips_subword (operands[1], 0);
4955       rtx high = mips_subword (operands[1], 1);
4956       emit_insn (gen_load_low<mode> (operands[0], low));
4957       if (TARGET_FLOAT64 && !TARGET_64BIT)
4958         emit_insn (gen_mthc1<mode> (operands[0], high, operands[0]));
4959       else
4960         emit_insn (gen_load_high<mode> (operands[0], high, operands[0]));
4961     }
4962   else
4963     {
4964       rtx low = mips_subword (operands[0], 0);
4965       rtx high = mips_subword (operands[0], 1);
4966       emit_insn (gen_store_word<mode> (low, operands[1], const0_rtx));
4967       if (TARGET_FLOAT64 && !TARGET_64BIT)
4968         emit_insn (gen_mfhc1<mode> (high, operands[1]));
4969       else
4970         emit_insn (gen_store_word<mode> (high, operands[1], const1_rtx));
4971     }
4972   DONE;
4975 ;; Load the low word of operand 0 with operand 1.
4976 (define_insn "load_low<mode>"
4977   [(set (match_operand:SPLITF 0 "register_operand" "=f,f")
4978         (unspec:SPLITF [(match_operand:<HALFMODE> 1 "general_operand" "dJ,m")]
4979                        UNSPEC_LOAD_LOW))]
4980   "TARGET_HARD_FLOAT"
4982   operands[0] = mips_subword (operands[0], 0);
4983   return mips_output_move (operands[0], operands[1]);
4985   [(set_attr "move_type" "mtc,fpload")
4986    (set_attr "mode" "<HALFMODE>")])
4988 ;; Load the high word of operand 0 from operand 1, preserving the value
4989 ;; in the low word.
4990 (define_insn "load_high<mode>"
4991   [(set (match_operand:SPLITF 0 "register_operand" "=f,f")
4992         (unspec:SPLITF [(match_operand:<HALFMODE> 1 "general_operand" "dJ,m")
4993                         (match_operand:SPLITF 2 "register_operand" "0,0")]
4994                        UNSPEC_LOAD_HIGH))]
4995   "TARGET_HARD_FLOAT"
4997   operands[0] = mips_subword (operands[0], 1);
4998   return mips_output_move (operands[0], operands[1]);
5000   [(set_attr "move_type" "mtc,fpload")
5001    (set_attr "mode" "<HALFMODE>")])
5003 ;; Store one word of operand 1 in operand 0.  Operand 2 is 1 to store the
5004 ;; high word and 0 to store the low word.
5005 (define_insn "store_word<mode>"
5006   [(set (match_operand:<HALFMODE> 0 "nonimmediate_operand" "=d,m")
5007         (unspec:<HALFMODE> [(match_operand:SPLITF 1 "register_operand" "f,f")
5008                             (match_operand 2 "const_int_operand")]
5009                            UNSPEC_STORE_WORD))]
5010   "TARGET_HARD_FLOAT"
5012   operands[1] = mips_subword (operands[1], INTVAL (operands[2]));
5013   return mips_output_move (operands[0], operands[1]);
5015   [(set_attr "move_type" "mfc,fpstore")
5016    (set_attr "mode" "<HALFMODE>")])
5018 ;; Move operand 1 to the high word of operand 0 using mthc1, preserving the
5019 ;; value in the low word.
5020 (define_insn "mthc1<mode>"
5021   [(set (match_operand:SPLITF 0 "register_operand" "=f")
5022         (unspec:SPLITF [(match_operand:<HALFMODE> 1 "reg_or_0_operand" "dJ")
5023                         (match_operand:SPLITF 2 "register_operand" "0")]
5024                        UNSPEC_MTHC1))]
5025   "TARGET_HARD_FLOAT && ISA_HAS_MXHC1"
5026   "mthc1\t%z1,%0"
5027   [(set_attr "move_type" "mtc")
5028    (set_attr "mode" "<HALFMODE>")])
5030 ;; Move high word of operand 1 to operand 0 using mfhc1.
5031 (define_insn "mfhc1<mode>"
5032   [(set (match_operand:<HALFMODE> 0 "register_operand" "=d")
5033         (unspec:<HALFMODE> [(match_operand:SPLITF 1 "register_operand" "f")]
5034                             UNSPEC_MFHC1))]
5035   "TARGET_HARD_FLOAT && ISA_HAS_MXHC1"
5036   "mfhc1\t%0,%1"
5037   [(set_attr "move_type" "mfc")
5038    (set_attr "mode" "<HALFMODE>")])
5040 ;; Move a constant that satisfies CONST_GP_P into operand 0.
5041 (define_expand "load_const_gp_<mode>"
5042   [(set (match_operand:P 0 "register_operand" "=d")
5043         (const:P (unspec:P [(const_int 0)] UNSPEC_GP)))])
5045 ;; Insn to initialize $gp for n32/n64 abicalls.  Operand 0 is the offset
5046 ;; of _gp from the start of this function.  Operand 1 is the incoming
5047 ;; function address.
5048 (define_insn_and_split "loadgp_newabi_<mode>"
5049   [(set (match_operand:P 0 "register_operand" "=&d")
5050         (unspec:P [(match_operand:P 1)
5051                    (match_operand:P 2 "register_operand" "d")]
5052                   UNSPEC_LOADGP))]
5053   "mips_current_loadgp_style () == LOADGP_NEWABI"
5054   { return mips_must_initialize_gp_p () ? "#" : ""; }
5055   "&& mips_must_initialize_gp_p ()"
5056   [(set (match_dup 0) (match_dup 3))
5057    (set (match_dup 0) (match_dup 4))
5058    (set (match_dup 0) (match_dup 5))]
5060   operands[3] = gen_rtx_HIGH (Pmode, operands[1]);
5061   operands[4] = gen_rtx_PLUS (Pmode, operands[0], operands[2]);
5062   operands[5] = gen_rtx_LO_SUM (Pmode, operands[0], operands[1]);
5064   [(set_attr "type" "ghost")])
5066 ;; Likewise, for -mno-shared code.  Operand 0 is the __gnu_local_gp symbol.
5067 (define_insn_and_split "loadgp_absolute_<mode>"
5068   [(set (match_operand:P 0 "register_operand" "=d")
5069         (unspec:P [(match_operand:P 1)] UNSPEC_LOADGP))]
5070   "mips_current_loadgp_style () == LOADGP_ABSOLUTE"
5071   { return mips_must_initialize_gp_p () ? "#" : ""; }
5072   "&& mips_must_initialize_gp_p ()"
5073   [(const_int 0)]
5075   mips_emit_move (operands[0], operands[1]);
5076   DONE;
5078   [(set_attr "type" "ghost")])
5080 ;; This blockage instruction prevents the gp load from being
5081 ;; scheduled after an implicit use of gp.  It also prevents
5082 ;; the load from being deleted as dead.
5083 (define_insn "loadgp_blockage"
5084   [(unspec_volatile [(reg:SI 28)] UNSPEC_BLOCKAGE)]
5085   ""
5086   ""
5087   [(set_attr "type" "ghost")])
5089 ;; Initialize $gp for RTP PIC.  Operand 0 is the __GOTT_BASE__ symbol
5090 ;; and operand 1 is the __GOTT_INDEX__ symbol.
5091 (define_insn_and_split "loadgp_rtp_<mode>"
5092   [(set (match_operand:P 0 "register_operand" "=d")
5093         (unspec:P [(match_operand:P 1 "symbol_ref_operand")
5094                    (match_operand:P 2 "symbol_ref_operand")]
5095                   UNSPEC_LOADGP))]
5096   "mips_current_loadgp_style () == LOADGP_RTP"
5097   { return mips_must_initialize_gp_p () ? "#" : ""; }
5098   "&& mips_must_initialize_gp_p ()"
5099   [(set (match_dup 0) (high:P (match_dup 3)))
5100    (set (match_dup 0) (unspec:P [(match_dup 0)
5101                                  (match_dup 3)] UNSPEC_LOAD_GOT))
5102    (set (match_dup 0) (unspec:P [(match_dup 0)
5103                                  (match_dup 4)] UNSPEC_LOAD_GOT))]
5105   operands[3] = mips_unspec_address (operands[1], SYMBOL_ABSOLUTE);
5106   operands[4] = mips_unspec_address (operands[2], SYMBOL_HALF);
5108   [(set_attr "type" "ghost")])
5110 ;; Initialize the global pointer for MIPS16 code.  Operand 0 is the
5111 ;; global pointer and operand 1 is the MIPS16 register that holds
5112 ;; the required value.
5113 (define_insn_and_split "copygp_mips16_<mode>"
5114   [(set (match_operand:P 0 "register_operand" "=y")
5115         (unspec:P [(match_operand:P 1 "register_operand" "d")]
5116                   UNSPEC_COPYGP))]
5117   "TARGET_MIPS16"
5118   { return mips_must_initialize_gp_p () ? "#" : ""; }
5119   "&& mips_must_initialize_gp_p ()"
5120   [(set (match_dup 0) (match_dup 1))]
5121   ""
5122   [(set_attr "type" "ghost")])
5124 ;; A placeholder for where the cprestore instruction should go,
5125 ;; if we decide we need one.  Operand 0 and operand 1 are as for
5126 ;; "cprestore".  Operand 2 is a register that holds the gp value.
5128 ;; The "cprestore" pattern requires operand 2 to be pic_offset_table_rtx,
5129 ;; otherwise any register that holds the correct value will do.
5130 (define_insn_and_split "potential_cprestore_<mode>"
5131   [(set (match_operand:P 0 "cprestore_save_slot_operand" "=X,X")
5132         (unspec:P [(match_operand:P 1 "const_int_operand" "I,i")
5133                    (match_operand:P 2 "register_operand" "d,d")]
5134                   UNSPEC_POTENTIAL_CPRESTORE))
5135    (clobber (match_operand:P 3 "scratch_operand" "=X,&d"))]
5136   "!TARGET_CPRESTORE_DIRECTIVE || operands[2] == pic_offset_table_rtx"
5137   { return mips_must_initialize_gp_p () ? "#" : ""; }
5138   "mips_must_initialize_gp_p ()"
5139   [(const_int 0)]
5141   mips_save_gp_to_cprestore_slot (operands[0], operands[1],
5142                                   operands[2], operands[3]);
5143   DONE;
5145   [(set_attr "type" "ghost")])
5147 ;; Emit a .cprestore directive, which normally expands to a single store
5148 ;; instruction.  Operand 0 is a (possibly illegitimate) sp-based MEM
5149 ;; for the cprestore slot.  Operand 1 is the offset of the slot from
5150 ;; the stack pointer.  (This is redundant with operand 0, but it makes
5151 ;; things a little simpler.)
5152 (define_insn "cprestore_<mode>"
5153   [(set (match_operand:P 0 "cprestore_save_slot_operand" "=X,X")
5154         (unspec:P [(match_operand:P 1 "const_int_operand" "I,i")
5155                    (reg:P 28)]
5156                   UNSPEC_CPRESTORE))]
5157   "TARGET_CPRESTORE_DIRECTIVE"
5159   if (mips_nomacro.nesting_level > 0 && which_alternative == 1)
5160     return ".set\tmacro\;.cprestore\t%1\;.set\tnomacro";
5161   else
5162     return ".cprestore\t%1";
5164   [(set_attr "type" "store")
5165    (set_attr "insn_count" "1,3")])
5167 (define_insn "use_cprestore_<mode>"
5168   [(set (reg:P CPRESTORE_SLOT_REGNUM)
5169         (match_operand:P 0 "cprestore_load_slot_operand"))]
5170   ""
5171   ""
5172   [(set_attr "type" "ghost")])
5174 ;; Expand in-line code to clear the instruction cache between operand[0] and
5175 ;; operand[1].
5176 (define_expand "clear_cache"
5177   [(match_operand 0 "pmode_register_operand")
5178    (match_operand 1 "pmode_register_operand")]
5179   ""
5180   "
5182   if (TARGET_SYNCI)
5183     {
5184       mips_expand_synci_loop (operands[0], operands[1]);
5185       emit_insn (gen_sync ());
5186       emit_insn (PMODE_INSN (gen_clear_hazard, ()));
5187     }
5188   else if (mips_cache_flush_func && mips_cache_flush_func[0])
5189     {
5190       rtx len = gen_reg_rtx (Pmode);
5191       emit_insn (gen_sub3_insn (len, operands[1], operands[0]));
5192       MIPS_ICACHE_SYNC (operands[0], len);
5193     }
5194   DONE;
5197 (define_insn "sync"
5198   [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)]
5199   "GENERATE_SYNC"
5200   { return mips_output_sync (); })
5202 (define_insn "synci"
5203   [(unspec_volatile [(match_operand 0 "pmode_register_operand" "d")]
5204                     UNSPEC_SYNCI)]
5205   "TARGET_SYNCI"
5206   "synci\t0(%0)")
5208 (define_insn "rdhwr_synci_step_<mode>"
5209   [(set (match_operand:P 0 "register_operand" "=d")
5210         (unspec_volatile [(const_int 1)]
5211         UNSPEC_RDHWR))]
5212   "ISA_HAS_SYNCI"
5213   "rdhwr\t%0,$1")
5215 (define_insn "clear_hazard_<mode>"
5216   [(unspec_volatile [(const_int 0)] UNSPEC_CLEAR_HAZARD)
5217    (clobber (reg:P RETURN_ADDR_REGNUM))]
5218   "ISA_HAS_SYNCI"
5220   return "%(%<bal\t1f\n"
5221          "\tnop\n"
5222          "1:\t<d>addiu\t$31,$31,12\n"
5223          "\tjr.hb\t$31\n"
5224          "\tnop%>%)";
5226   [(set_attr "insn_count" "5")])
5228 ;; Cache operations for R4000-style caches.
5229 (define_insn "mips_cache"
5230   [(set (mem:BLK (scratch))
5231         (unspec:BLK [(match_operand:SI 0 "const_int_operand")
5232                      (match_operand:QI 1 "address_operand" "p")]
5233                     UNSPEC_MIPS_CACHE))]
5234   "ISA_HAS_CACHE"
5235   "cache\t%X0,%a1")
5237 ;; Similar, but with the operands hard-coded to an R10K cache barrier
5238 ;; operation.  We keep the pattern distinct so that we can identify
5239 ;; cache operations inserted by -mr10k-cache-barrier=, and so that
5240 ;; the operation is never inserted into a delay slot.
5241 (define_insn "r10k_cache_barrier"
5242   [(set (mem:BLK (scratch))
5243         (unspec:BLK [(const_int 0)] UNSPEC_R10K_CACHE_BARRIER))]
5244   "ISA_HAS_CACHE"
5245   "cache\t0x14,0(%$)"
5246   [(set_attr "can_delay" "no")])
5248 ;; Block moves, see mips.c for more details.
5249 ;; Argument 0 is the destination
5250 ;; Argument 1 is the source
5251 ;; Argument 2 is the length
5252 ;; Argument 3 is the alignment
5254 (define_expand "movmemsi"
5255   [(parallel [(set (match_operand:BLK 0 "general_operand")
5256                    (match_operand:BLK 1 "general_operand"))
5257               (use (match_operand:SI 2 ""))
5258               (use (match_operand:SI 3 "const_int_operand"))])]
5259   "!TARGET_MIPS16 && !TARGET_MEMCPY"
5261   if (mips_expand_block_move (operands[0], operands[1], operands[2]))
5262     DONE;
5263   else
5264     FAIL;
5268 ;;  ....................
5270 ;;      SHIFTS
5272 ;;  ....................
5274 (define_expand "<optab><mode>3"
5275   [(set (match_operand:GPR 0 "register_operand")
5276         (any_shift:GPR (match_operand:GPR 1 "register_operand")
5277                        (match_operand:SI 2 "arith_operand")))]
5278   ""
5280   /* On the mips16, a shift of more than 8 is a four byte instruction,
5281      so, for a shift between 8 and 16, it is just as fast to do two
5282      shifts of 8 or less.  If there is a lot of shifting going on, we
5283      may win in CSE.  Otherwise combine will put the shifts back
5284      together again.  This can be called by mips_function_arg, so we must
5285      be careful not to allocate a new register if we've reached the
5286      reload pass.  */
5287   if (TARGET_MIPS16
5288       && optimize
5289       && CONST_INT_P (operands[2])
5290       && INTVAL (operands[2]) > 8
5291       && INTVAL (operands[2]) <= 16
5292       && !reload_in_progress
5293       && !reload_completed)
5294     {
5295       rtx temp = gen_reg_rtx (<MODE>mode);
5297       emit_insn (gen_<optab><mode>3 (temp, operands[1], GEN_INT (8)));
5298       emit_insn (gen_<optab><mode>3 (operands[0], temp,
5299                                      GEN_INT (INTVAL (operands[2]) - 8)));
5300       DONE;
5301     }
5304 (define_insn "*<optab><mode>3"
5305   [(set (match_operand:GPR 0 "register_operand" "=!u,d")
5306         (any_shift:GPR (match_operand:GPR 1 "register_operand" "!u,d")
5307                        (match_operand:SI 2 "arith_operand" "Uib3,dI")))]
5308   "!TARGET_MIPS16"
5310   if (CONST_INT_P (operands[2]))
5311     operands[2] = GEN_INT (INTVAL (operands[2])
5312                            & (GET_MODE_BITSIZE (<MODE>mode) - 1));
5314   return "<d><insn>\t%0,%1,%2";
5316   [(set_attr "type" "shift")
5317    (set_attr "compression" "<shift_compression>,none")
5318    (set_attr "mode" "<MODE>")])
5320 (define_insn "*<optab>si3_extend"
5321   [(set (match_operand:DI 0 "register_operand" "=d")
5322         (sign_extend:DI
5323            (any_shift:SI (match_operand:SI 1 "register_operand" "d")
5324                          (match_operand:SI 2 "arith_operand" "dI"))))]
5325   "TARGET_64BIT && !TARGET_MIPS16"
5327   if (CONST_INT_P (operands[2]))
5328     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5330   return "<insn>\t%0,%1,%2";
5332   [(set_attr "type" "shift")
5333    (set_attr "mode" "SI")])
5335 (define_insn "*<optab>si3_mips16"
5336   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
5337         (any_shift:SI (match_operand:SI 1 "register_operand" "0,d,d")
5338                       (match_operand:SI 2 "arith_operand" "d,Uib3,I")))]
5339   "TARGET_MIPS16"
5341   if (which_alternative == 0)
5342     return "<insn>\t%0,%2";
5344   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5345   return "<insn>\t%0,%1,%2";
5347   [(set_attr "type" "shift")
5348    (set_attr "mode" "SI")
5349    (set_attr "extended_mips16" "no,no,yes")])
5351 ;; We need separate DImode MIPS16 patterns because of the irregularity
5352 ;; of right shifts.
5353 (define_insn "*ashldi3_mips16"
5354   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
5355         (ashift:DI (match_operand:DI 1 "register_operand" "0,d,d")
5356                    (match_operand:SI 2 "arith_operand" "d,Uib3,I")))]
5357   "TARGET_64BIT && TARGET_MIPS16"
5359   if (which_alternative == 0)
5360     return "dsll\t%0,%2";
5362   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5363   return "dsll\t%0,%1,%2";
5365   [(set_attr "type" "shift")
5366    (set_attr "mode" "DI")
5367    (set_attr "extended_mips16" "no,no,yes")])
5369 (define_insn "*ashrdi3_mips16"
5370   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
5371         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0,0")
5372                      (match_operand:SI 2 "arith_operand" "d,Uib3,I")))]
5373   "TARGET_64BIT && TARGET_MIPS16"
5375   if (CONST_INT_P (operands[2]))
5376     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5378   return "dsra\t%0,%2";
5380   [(set_attr "type" "shift")
5381    (set_attr "mode" "DI")
5382    (set_attr "extended_mips16" "no,no,yes")])
5384 (define_insn "*lshrdi3_mips16"
5385   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
5386         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0,0")
5387                      (match_operand:SI 2 "arith_operand" "d,Uib3,I")))]
5388   "TARGET_64BIT && TARGET_MIPS16"
5390   if (CONST_INT_P (operands[2]))
5391     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5393   return "dsrl\t%0,%2";
5395   [(set_attr "type" "shift")
5396    (set_attr "mode" "DI")
5397    (set_attr "extended_mips16" "no,no,yes")])
5399 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5401 (define_split
5402   [(set (match_operand:GPR 0 "d_operand")
5403         (any_shift:GPR (match_operand:GPR 1 "d_operand")
5404                        (match_operand:GPR 2 "const_int_operand")))]
5405   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5406    && INTVAL (operands[2]) > 8
5407    && INTVAL (operands[2]) <= 16"
5408   [(set (match_dup 0) (any_shift:GPR (match_dup 1) (const_int 8)))
5409    (set (match_dup 0) (any_shift:GPR (match_dup 0) (match_dup 2)))]
5410   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5412 ;; If we load a byte on the mips16 as a bitfield, the resulting
5413 ;; sequence of instructions is too complicated for combine, because it
5414 ;; involves four instructions: a load, a shift, a constant load into a
5415 ;; register, and an and (the key problem here is that the mips16 does
5416 ;; not have and immediate).  We recognize a shift of a load in order
5417 ;; to make it simple enough for combine to understand.
5419 ;; The instruction count here is the worst case.
5420 (define_insn_and_split ""
5421   [(set (match_operand:SI 0 "register_operand" "=d")
5422         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
5423                      (match_operand:SI 2 "immediate_operand" "I")))]
5424   "TARGET_MIPS16"
5425   "#"
5426   ""
5427   [(set (match_dup 0) (match_dup 1))
5428    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
5429   ""
5430   [(set_attr "type"     "load")
5431    (set_attr "mode"     "SI")
5432    (set (attr "insn_count")
5433         (symbol_ref "mips_load_store_insns (operands[1], insn) + 2"))])
5435 (define_insn "rotr<mode>3"
5436   [(set (match_operand:GPR 0 "register_operand" "=d")
5437         (rotatert:GPR (match_operand:GPR 1 "register_operand" "d")
5438                       (match_operand:SI 2 "arith_operand" "dI")))]
5439   "ISA_HAS_ROR"
5441   if (CONST_INT_P (operands[2]))
5442     gcc_assert (INTVAL (operands[2]) >= 0
5443                 && INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode));
5445   return "<d>ror\t%0,%1,%2";
5447   [(set_attr "type" "shift")
5448    (set_attr "mode" "<MODE>")])
5450 (define_insn "bswaphi2"
5451   [(set (match_operand:HI 0 "register_operand" "=d")
5452         (bswap:HI (match_operand:HI 1 "register_operand" "d")))]
5453   "ISA_HAS_WSBH"
5454   "wsbh\t%0,%1"
5455   [(set_attr "type" "shift")])
5457 (define_insn_and_split "bswapsi2"
5458   [(set (match_operand:SI 0 "register_operand" "=d")
5459         (bswap:SI (match_operand:SI 1 "register_operand" "d")))]
5460   "ISA_HAS_WSBH && ISA_HAS_ROR"
5461   "#"
5462   ""
5463   [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_WSBH))
5464    (set (match_dup 0) (rotatert:SI (match_dup 0) (const_int 16)))]
5465   ""
5466   [(set_attr "insn_count" "2")])
5468 (define_insn_and_split "bswapdi2"
5469   [(set (match_operand:DI 0 "register_operand" "=d")
5470         (bswap:DI (match_operand:DI 1 "register_operand" "d")))]
5471   "TARGET_64BIT && ISA_HAS_WSBH"
5472   "#"
5473   ""
5474   [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_DSBH))
5475    (set (match_dup 0) (unspec:DI [(match_dup 0)] UNSPEC_DSHD))]
5476   ""
5477   [(set_attr "insn_count" "2")])
5479 (define_insn "wsbh"
5480   [(set (match_operand:SI 0 "register_operand" "=d")
5481         (unspec:SI [(match_operand:SI 1 "register_operand" "d")] UNSPEC_WSBH))]
5482   "ISA_HAS_WSBH"
5483   "wsbh\t%0,%1"
5484   [(set_attr "type" "shift")])
5486 (define_insn "dsbh"
5487   [(set (match_operand:DI 0 "register_operand" "=d")
5488         (unspec:DI [(match_operand:DI 1 "register_operand" "d")] UNSPEC_DSBH))]
5489   "TARGET_64BIT && ISA_HAS_WSBH"
5490   "dsbh\t%0,%1"
5491   [(set_attr "type" "shift")])
5493 (define_insn "dshd"
5494   [(set (match_operand:DI 0 "register_operand" "=d")
5495         (unspec:DI [(match_operand:DI 1 "register_operand" "d")] UNSPEC_DSHD))]
5496   "TARGET_64BIT && ISA_HAS_WSBH"
5497   "dshd\t%0,%1"
5498   [(set_attr "type" "shift")])
5501 ;;  ....................
5503 ;;      CONDITIONAL BRANCHES
5505 ;;  ....................
5507 ;; Conditional branches on floating-point equality tests.
5509 (define_insn "*branch_fp"
5510   [(set (pc)
5511         (if_then_else
5512          (match_operator 1 "equality_operator"
5513                          [(match_operand:CC 2 "register_operand" "z")
5514                           (const_int 0)])
5515          (label_ref (match_operand 0 "" ""))
5516          (pc)))]
5517   "TARGET_HARD_FLOAT"
5519   return mips_output_conditional_branch (insn, operands,
5520                                          MIPS_BRANCH ("b%F1", "%Z2%0"),
5521                                          MIPS_BRANCH ("b%W1", "%Z2%0"));
5523   [(set_attr "type" "branch")])
5525 (define_insn "*branch_fp_inverted"
5526   [(set (pc)
5527         (if_then_else
5528          (match_operator 1 "equality_operator"
5529                          [(match_operand:CC 2 "register_operand" "z")
5530                           (const_int 0)])
5531          (pc)
5532          (label_ref (match_operand 0 "" ""))))]
5533   "TARGET_HARD_FLOAT"
5535   return mips_output_conditional_branch (insn, operands,
5536                                          MIPS_BRANCH ("b%W1", "%Z2%0"),
5537                                          MIPS_BRANCH ("b%F1", "%Z2%0"));
5539   [(set_attr "type" "branch")])
5541 ;; Conditional branches on ordered comparisons with zero.
5543 (define_insn "*branch_order<mode>"
5544   [(set (pc)
5545         (if_then_else
5546          (match_operator 1 "order_operator"
5547                          [(match_operand:GPR 2 "register_operand" "d")
5548                           (const_int 0)])
5549          (label_ref (match_operand 0 "" ""))
5550          (pc)))]
5551   "!TARGET_MIPS16"
5552   { return mips_output_order_conditional_branch (insn, operands, false); }
5553   [(set_attr "type" "branch")])
5555 (define_insn "*branch_order<mode>_inverted"
5556   [(set (pc)
5557         (if_then_else
5558          (match_operator 1 "order_operator"
5559                          [(match_operand:GPR 2 "register_operand" "d")
5560                           (const_int 0)])
5561          (pc)
5562          (label_ref (match_operand 0 "" ""))))]
5563   "!TARGET_MIPS16"
5564   { return mips_output_order_conditional_branch (insn, operands, true); }
5565   [(set_attr "type" "branch")])
5567 ;; Conditional branch on equality comparison.
5569 (define_insn "*branch_equality<mode>"
5570   [(set (pc)
5571         (if_then_else
5572          (match_operator 1 "equality_operator"
5573                          [(match_operand:GPR 2 "register_operand" "d")
5574                           (match_operand:GPR 3 "reg_or_0_operand" "dJ")])
5575          (label_ref (match_operand 0 "" ""))
5576          (pc)))]
5577   "!TARGET_MIPS16"
5579   /* For a simple BNEZ or BEQZ microMIPS branch.  */
5580   if (TARGET_MICROMIPS
5581       && operands[3] == const0_rtx
5582       && get_attr_length (insn) <= 8)
5583     return mips_output_conditional_branch (insn, operands,
5584                                            "%*b%C1z%:\t%2,%0",
5585                                            "%*b%N1z%:\t%2,%0");
5587   return mips_output_conditional_branch (insn, operands,
5588                                          MIPS_BRANCH ("b%C1", "%2,%z3,%0"),
5589                                          MIPS_BRANCH ("b%N1", "%2,%z3,%0"));
5591   [(set_attr "type" "branch")])
5593 (define_insn "*branch_equality<mode>_inverted"
5594   [(set (pc)
5595         (if_then_else
5596          (match_operator 1 "equality_operator"
5597                          [(match_operand:GPR 2 "register_operand" "d")
5598                           (match_operand:GPR 3 "reg_or_0_operand" "dJ")])
5599          (pc)
5600          (label_ref (match_operand 0 "" ""))))]
5601   "!TARGET_MIPS16"
5603   /* For a simple BNEZ or BEQZ microMIPS branch.  */
5604   if (TARGET_MICROMIPS
5605       && operands[3] == const0_rtx
5606       && get_attr_length (insn) <= 8)
5607     return mips_output_conditional_branch (insn, operands,
5608                                            "%*b%N0z%:\t%2,%1",
5609                                            "%*b%C0z%:\t%2,%1");
5611   return mips_output_conditional_branch (insn, operands,
5612                                          MIPS_BRANCH ("b%N1", "%2,%z3,%0"),
5613                                          MIPS_BRANCH ("b%C1", "%2,%z3,%0"));
5615   [(set_attr "type" "branch")])
5617 ;; MIPS16 branches
5619 (define_insn "*branch_equality<mode>_mips16"
5620   [(set (pc)
5621         (if_then_else
5622          (match_operator 1 "equality_operator"
5623                          [(match_operand:GPR 2 "register_operand" "d,t")
5624                           (const_int 0)])
5625          (label_ref (match_operand 0 "" ""))
5626          (pc)))]
5627   "TARGET_MIPS16"
5628   "@
5629    b%C1z\t%2,%0
5630    bt%C1z\t%0"
5631   [(set_attr "type" "branch")])
5633 (define_insn "*branch_equality<mode>_mips16_inverted"
5634   [(set (pc)
5635         (if_then_else
5636          (match_operator 1 "equality_operator"
5637                          [(match_operand:GPR 2 "register_operand" "d,t")
5638                           (const_int 0)])
5639          (pc)
5640          (label_ref (match_operand 0 "" ""))))]
5641   "TARGET_MIPS16"
5642   "@
5643    b%N1z\t%2,%0
5644    bt%N1z\t%0"
5645   [(set_attr "type" "branch")])
5647 (define_expand "cbranch<mode>4"
5648   [(set (pc)
5649         (if_then_else (match_operator 0 "comparison_operator"
5650                        [(match_operand:GPR 1 "register_operand")
5651                         (match_operand:GPR 2 "nonmemory_operand")])
5652                       (label_ref (match_operand 3 ""))
5653                       (pc)))]
5654   ""
5656   mips_expand_conditional_branch (operands);
5657   DONE;
5660 (define_expand "cbranch<mode>4"
5661   [(set (pc)
5662         (if_then_else (match_operator 0 "comparison_operator"
5663                        [(match_operand:SCALARF 1 "register_operand")
5664                         (match_operand:SCALARF 2 "register_operand")])
5665                       (label_ref (match_operand 3 ""))
5666                       (pc)))]
5667   ""
5669   mips_expand_conditional_branch (operands);
5670   DONE;
5673 ;; Used to implement built-in functions.
5674 (define_expand "condjump"
5675   [(set (pc)
5676         (if_then_else (match_operand 0)
5677                       (label_ref (match_operand 1))
5678                       (pc)))])
5680 ;; Branch if bit is set/clear.
5682 (define_insn "*branch_bit<bbv><mode>"
5683   [(set (pc)
5684         (if_then_else
5685          (equality_op (zero_extract:GPR
5686                        (match_operand:GPR 1 "register_operand" "d")
5687                        (const_int 1)
5688                        (match_operand 2 "const_int_operand" ""))
5689                       (const_int 0))
5690          (label_ref (match_operand 0 ""))
5691          (pc)))]
5692   "ISA_HAS_BBIT && UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
5694   return
5695     mips_output_conditional_branch (insn, operands,
5696                                     MIPS_BRANCH ("bbit<bbv>", "%1,%2,%0"),
5697                                     MIPS_BRANCH ("bbit<bbinv>", "%1,%2,%0"));
5699   [(set_attr "type"          "branch")
5700    (set_attr "branch_likely" "no")])
5702 (define_insn "*branch_bit<bbv><mode>_inverted"
5703   [(set (pc)
5704         (if_then_else
5705          (equality_op (zero_extract:GPR
5706                        (match_operand:GPR 1 "register_operand" "d")
5707                        (const_int 1)
5708                        (match_operand 2 "const_int_operand" ""))
5709                       (const_int 0))
5710          (pc)
5711          (label_ref (match_operand 0 ""))))]
5712   "ISA_HAS_BBIT && UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
5714   return
5715     mips_output_conditional_branch (insn, operands,
5716                                     MIPS_BRANCH ("bbit<bbinv>", "%1,%2,%0"),
5717                                     MIPS_BRANCH ("bbit<bbv>", "%1,%2,%0"));
5719   [(set_attr "type"          "branch")
5720    (set_attr "branch_likely" "no")])
5723 ;;  ....................
5725 ;;      SETTING A REGISTER FROM A COMPARISON
5727 ;;  ....................
5729 ;; Destination is always set in SI mode.
5731 (define_expand "cstore<mode>4"
5732   [(set (match_operand:SI 0 "register_operand")
5733         (match_operator:SI 1 "mips_cstore_operator"
5734          [(match_operand:GPR 2 "register_operand")
5735           (match_operand:GPR 3 "nonmemory_operand")]))]
5736   ""
5738   mips_expand_scc (operands);
5739   DONE;
5742 (define_insn "*seq_zero_<GPR:mode><GPR2:mode>"
5743   [(set (match_operand:GPR2 0 "register_operand" "=d")
5744         (eq:GPR2 (match_operand:GPR 1 "register_operand" "d")
5745                  (const_int 0)))]
5746   "!TARGET_MIPS16 && !ISA_HAS_SEQ_SNE"
5747   "sltu\t%0,%1,1"
5748   [(set_attr "type" "slt")
5749    (set_attr "mode" "<GPR:MODE>")])
5751 (define_insn "*seq_zero_<GPR:mode><GPR2:mode>_mips16"
5752   [(set (match_operand:GPR2 0 "register_operand" "=t")
5753         (eq:GPR2 (match_operand:GPR 1 "register_operand" "d")
5754                  (const_int 0)))]
5755   "TARGET_MIPS16 && !ISA_HAS_SEQ_SNE"
5756   "sltu\t%1,1"
5757   [(set_attr "type" "slt")
5758    (set_attr "mode" "<GPR:MODE>")])
5760 ;; Generate sltiu unless using seq results in better code.
5761 (define_insn "*seq_<GPR:mode><GPR2:mode>_seq"
5762   [(set (match_operand:GPR2 0 "register_operand" "=d,d,d")
5763         (eq:GPR2 (match_operand:GPR 1 "register_operand" "%d,d,d")
5764                  (match_operand:GPR 2 "reg_imm10_operand" "d,J,YB")))]
5765   "ISA_HAS_SEQ_SNE"
5766   "@
5767    seq\t%0,%1,%2
5768    sltiu\t%0,%1,1
5769    seqi\t%0,%1,%2"
5770   [(set_attr "type" "slt")
5771    (set_attr "mode" "<GPR:MODE>")])
5773 (define_insn "*sne_zero_<GPR:mode><GPR2:mode>"
5774   [(set (match_operand:GPR2 0 "register_operand" "=d")
5775         (ne:GPR2 (match_operand:GPR 1 "register_operand" "d")
5776                  (const_int 0)))]
5777   "!TARGET_MIPS16 && !ISA_HAS_SEQ_SNE"
5778   "sltu\t%0,%.,%1"
5779   [(set_attr "type" "slt")
5780    (set_attr "mode" "<GPR:MODE>")])
5782 ;; Generate sltu unless using sne results in better code.
5783 (define_insn "*sne_<GPR:mode><GPR2:mode>_sne"
5784   [(set (match_operand:GPR2 0 "register_operand" "=d,d,d")
5785         (ne:GPR2 (match_operand:GPR 1 "register_operand" "%d,d,d")
5786                  (match_operand:GPR 2 "reg_imm10_operand" "d,J,YB")))]
5787   "ISA_HAS_SEQ_SNE"
5788   "@
5789    sne\t%0,%1,%2
5790    sltu\t%0,%.,%1
5791    snei\t%0,%1,%2"
5792   [(set_attr "type" "slt")
5793    (set_attr "mode" "<GPR:MODE>")])
5795 (define_insn "*sgt<u>_<GPR:mode><GPR2:mode>"
5796   [(set (match_operand:GPR2 0 "register_operand" "=d")
5797         (any_gt:GPR2 (match_operand:GPR 1 "register_operand" "d")
5798                      (match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
5799   "!TARGET_MIPS16"
5800   "slt<u>\t%0,%z2,%1"
5801   [(set_attr "type" "slt")
5802    (set_attr "mode" "<GPR:MODE>")])
5804 (define_insn "*sgt<u>_<GPR:mode><GPR2:mode>_mips16"
5805   [(set (match_operand:GPR2 0 "register_operand" "=t")
5806         (any_gt:GPR2 (match_operand:GPR 1 "register_operand" "d")
5807                      (match_operand:GPR 2 "register_operand" "d")))]
5808   "TARGET_MIPS16"
5809   "slt<u>\t%2,%1"
5810   [(set_attr "type" "slt")
5811    (set_attr "mode" "<GPR:MODE>")])
5813 (define_insn "*sge<u>_<GPR:mode><GPR2:mode>"
5814   [(set (match_operand:GPR2 0 "register_operand" "=d")
5815         (any_ge:GPR2 (match_operand:GPR 1 "register_operand" "d")
5816                      (const_int 1)))]
5817   "!TARGET_MIPS16"
5818   "slt<u>\t%0,%.,%1"
5819   [(set_attr "type" "slt")
5820    (set_attr "mode" "<GPR:MODE>")])
5822 (define_insn "*slt<u>_<GPR:mode><GPR2:mode>"
5823   [(set (match_operand:GPR2 0 "register_operand" "=d")
5824         (any_lt:GPR2 (match_operand:GPR 1 "register_operand" "d")
5825                      (match_operand:GPR 2 "arith_operand" "dI")))]
5826   "!TARGET_MIPS16"
5827   "slt<u>\t%0,%1,%2"
5828   [(set_attr "type" "slt")
5829    (set_attr "mode" "<GPR:MODE>")])
5831 (define_insn "*slt<u>_<GPR:mode><GPR2:mode>_mips16"
5832   [(set (match_operand:GPR2 0 "register_operand" "=t,t,t")
5833         (any_lt:GPR2 (match_operand:GPR 1 "register_operand" "d,d,d")
5834                      (match_operand:GPR 2 "arith_operand" "d,Uub8,I")))]
5835   "TARGET_MIPS16"
5836   "slt<u>\t%1,%2"
5837   [(set_attr "type" "slt")
5838    (set_attr "mode" "<GPR:MODE>")
5839    (set_attr "extended_mips16" "no,no,yes")])
5841 (define_insn "*sle<u>_<GPR:mode><GPR2:mode>"
5842   [(set (match_operand:GPR2 0 "register_operand" "=d")
5843         (any_le:GPR2 (match_operand:GPR 1 "register_operand" "d")
5844                      (match_operand:GPR 2 "sle_operand" "")))]
5845   "!TARGET_MIPS16"
5847   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5848   return "slt<u>\t%0,%1,%2";
5850   [(set_attr "type" "slt")
5851    (set_attr "mode" "<GPR:MODE>")])
5853 (define_insn "*sle<u>_<GPR:mode><GPR2:mode>_mips16"
5854   [(set (match_operand:GPR2 0 "register_operand" "=t,t")
5855         (any_le:GPR2 (match_operand:GPR 1 "register_operand" "d,d")
5856                      (match_operand:GPR 2 "sle_operand" "Udb8,i")))]
5857   "TARGET_MIPS16"
5859   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5860   return "slt<u>\t%1,%2";
5862   [(set_attr "type" "slt")
5863    (set_attr "mode" "<GPR:MODE>")
5864    (set_attr "extended_mips16" "no,yes")])
5867 ;;  ....................
5869 ;;      FLOATING POINT COMPARISONS
5871 ;;  ....................
5873 (define_insn "s<code>_<mode>"
5874   [(set (match_operand:CC 0 "register_operand" "=z")
5875         (fcond:CC (match_operand:SCALARF 1 "register_operand" "f")
5876                   (match_operand:SCALARF 2 "register_operand" "f")))]
5877   ""
5878   "c.<fcond>.<fmt>\t%Z0%1,%2"
5879   [(set_attr "type" "fcmp")
5880    (set_attr "mode" "FPSW")])
5882 (define_insn "s<code>_<mode>"
5883   [(set (match_operand:CC 0 "register_operand" "=z")
5884         (swapped_fcond:CC (match_operand:SCALARF 1 "register_operand" "f")
5885                           (match_operand:SCALARF 2 "register_operand" "f")))]
5886   ""
5887   "c.<swapped_fcond>.<fmt>\t%Z0%2,%1"
5888   [(set_attr "type" "fcmp")
5889    (set_attr "mode" "FPSW")])
5892 ;;  ....................
5894 ;;      UNCONDITIONAL BRANCHES
5896 ;;  ....................
5898 ;; Unconditional branches.
5900 (define_expand "jump"
5901   [(set (pc)
5902         (label_ref (match_operand 0)))])
5904 (define_insn "*jump_absolute"
5905   [(set (pc)
5906         (label_ref (match_operand 0)))]
5907   "!TARGET_MIPS16 && TARGET_ABSOLUTE_JUMPS"
5909   /* Use a branch for microMIPS.  The assembler will choose
5910      a 16-bit branch, a 32-bit branch, or a 32-bit jump.  */
5911   if (TARGET_MICROMIPS && !TARGET_ABICALLS_PIC2)
5912     return "%*b\t%l0%/";
5913   else
5914     return MIPS_ABSOLUTE_JUMP ("%*j\t%l0%/");
5916   [(set_attr "type" "jump")])
5918 (define_insn "*jump_pic"
5919   [(set (pc)
5920         (label_ref (match_operand 0)))]
5921   "!TARGET_MIPS16 && !TARGET_ABSOLUTE_JUMPS"
5923   if (get_attr_length (insn) <= 8)
5924     return "%*b\t%l0%/";
5925   else
5926     {
5927       mips_output_load_label (operands[0]);
5928       return "%*jr\t%@%/%]";
5929     }
5931   [(set_attr "type" "branch")])
5933 ;; We need a different insn for the mips16, because a mips16 branch
5934 ;; does not have a delay slot.
5936 (define_insn "*jump_mips16"
5937   [(set (pc)
5938         (label_ref (match_operand 0 "" "")))]
5939   "TARGET_MIPS16"
5940   "b\t%l0"
5941   [(set_attr "type" "branch")
5942    (set (attr "length")
5943         ;; This calculation is like the normal branch one, but the
5944         ;; range of the unextended instruction is [-0x800, 0x7fe] rather
5945         ;; than [-0x100, 0xfe].  This translates to a range of:
5946         ;;
5947         ;;    [-(0x800 - sizeof (branch)), 0x7fe]
5948         ;; == [-0x7fe, 0x7fe]
5949         ;;
5950         ;; from the shorten_branches reference address.  Long-branch
5951         ;; sequences will replace this one, so the minimum length
5952         ;; is one instruction shorter than for conditional branches.
5953         (cond [(and (le (minus (match_dup 0) (pc)) (const_int 2046))
5954                     (le (minus (pc) (match_dup 0)) (const_int 2046)))
5955                (const_int 2)
5956                (and (le (minus (match_dup 0) (pc)) (const_int 65534))
5957                     (le (minus (pc) (match_dup 0)) (const_int 65532)))
5958                (const_int 4)
5959                (and (match_test "TARGET_ABICALLS")
5960                     (not (match_test "TARGET_ABSOLUTE_ABICALLS")))
5961                (const_int 18)
5962                (match_test "Pmode == SImode")
5963                (const_int 14)
5964                ] (const_int 22)))])
5966 (define_expand "indirect_jump"
5967   [(set (pc) (match_operand 0 "register_operand"))]
5968   ""
5970   operands[0] = force_reg (Pmode, operands[0]);
5971   emit_jump_insn (PMODE_INSN (gen_indirect_jump, (operands[0])));
5972   DONE;
5975 (define_insn "indirect_jump_<mode>"
5976   [(set (pc) (match_operand:P 0 "register_operand" "d"))]
5977   ""
5979   if (TARGET_MICROMIPS)
5980     return "%*jr%:\t%0";
5981   else
5982     return "%*j\t%0%/";
5984   [(set_attr "type" "jump")
5985    (set_attr "mode" "none")])
5987 ;; A combined jump-and-move instruction, used for MIPS16 long-branch
5988 ;; sequences.  Having a dedicated pattern is more convenient than
5989 ;; creating a SEQUENCE for this special case.
5990 (define_insn "indirect_jump_and_restore_<mode>"
5991   [(set (pc) (match_operand:P 1 "register_operand" "d"))
5992    (set (match_operand:P 0 "register_operand" "=d")
5993         (match_operand:P 2 "register_operand" "y"))]
5994   ""
5995   "%(%<jr\t%1\;move\t%0,%2%>%)"
5996   [(set_attr "type" "multi")
5997    (set_attr "extended_mips16" "yes")])
5999 (define_expand "tablejump"
6000   [(set (pc)
6001         (match_operand 0 "register_operand"))
6002    (use (label_ref (match_operand 1 "")))]
6003   "!TARGET_MIPS16_SHORT_JUMP_TABLES"
6005   if (TARGET_GPWORD)
6006     operands[0] = expand_binop (Pmode, add_optab, operands[0],
6007                                 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
6008   else if (TARGET_RTP_PIC)
6009     {
6010       /* When generating RTP PIC, we use case table entries that are relative
6011          to the start of the function.  Add the function's address to the
6012          value we loaded.  */
6013       rtx start = get_hard_reg_initial_val (Pmode, PIC_FUNCTION_ADDR_REGNUM);
6014       operands[0] = expand_binop (ptr_mode, add_optab, operands[0],
6015                                   start, 0, 0, OPTAB_WIDEN);
6016     }
6018   emit_jump_insn (PMODE_INSN (gen_tablejump, (operands[0], operands[1])));
6019   DONE;
6022 (define_insn "tablejump_<mode>"
6023   [(set (pc)
6024         (match_operand:P 0 "register_operand" "d"))
6025    (use (label_ref (match_operand 1 "" "")))]
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 ;; For MIPS16, we don't know whether a given jump table will use short or
6037 ;; word-sized offsets until late in compilation, when we are able to determine
6038 ;; the sizes of the insns which comprise the containing function.  This
6039 ;; necessitates the use of the casesi rather than the tablejump pattern, since
6040 ;; the latter tries to calculate the index of the offset to jump through early
6041 ;; in compilation, i.e. at expand time, when nothing is known about the
6042 ;; eventual function layout.
6044 (define_expand "casesi"
6045   [(match_operand:SI 0 "register_operand" "")   ; index to jump on
6046    (match_operand:SI 1 "const_int_operand" "")  ; lower bound
6047    (match_operand:SI 2 "const_int_operand" "")  ; total range
6048    (match_operand 3 "" "")                      ; table label
6049    (match_operand 4 "" "")]                     ; out of range label
6050   "TARGET_MIPS16_SHORT_JUMP_TABLES"
6052   if (operands[1] != const0_rtx)
6053     {
6054       rtx reg = gen_reg_rtx (SImode);
6055       rtx offset = gen_int_mode (-INTVAL (operands[1]), SImode);
6056       
6057       if (!arith_operand (offset, SImode))
6058         offset = force_reg (SImode, offset);
6059       
6060       emit_insn (gen_addsi3 (reg, operands[0], offset));
6061       operands[0] = reg;
6062     }
6064   if (!arith_operand (operands[0], SImode))
6065     operands[0] = force_reg (SImode, operands[0]);
6067   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6069   emit_jump_insn (PMODE_INSN (gen_casesi_internal_mips16,
6070                               (operands[0], operands[2],
6071                                operands[3], operands[4])));
6073   DONE;
6076 (define_insn "casesi_internal_mips16_<mode>"
6077   [(set (pc)
6078      (if_then_else
6079        (leu (match_operand:SI 0 "register_operand" "d")
6080             (match_operand:SI 1 "arith_operand" "dI"))
6081        (unspec:P
6082         [(match_dup 0)
6083          (label_ref (match_operand 2 "" ""))]
6084         UNSPEC_CASESI_DISPATCH)
6085        (label_ref (match_operand 3 "" ""))))
6086    (clobber (match_scratch:P 4 "=d"))
6087    (clobber (match_scratch:P 5 "=d"))
6088    (clobber (reg:SI MIPS16_T_REGNUM))]
6089   "TARGET_MIPS16_SHORT_JUMP_TABLES"
6091   rtx diff_vec = PATTERN (NEXT_INSN (operands[2]));
6093   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
6094   
6095   output_asm_insn ("sltu\t%0, %1", operands);
6096   output_asm_insn ("bteqz\t%3", operands);
6097   
6098   switch (GET_MODE (diff_vec))
6099     {
6100     case HImode:
6101       output_asm_insn ("sll\t%5, %0, 1", operands);
6102       output_asm_insn ("la\t%4, %2", operands);
6103       output_asm_insn ("<d>addu\t%5, %4, %5", operands);
6104       output_asm_insn ("lh\t%5, 0(%5)", operands);
6105       break;
6106     
6107     case SImode:
6108       output_asm_insn ("sll\t%5, %0, 2", operands);
6109       output_asm_insn ("la\t%4, %2", operands);
6110       output_asm_insn ("<d>addu\t%5, %4, %5", operands);
6111       output_asm_insn ("lw\t%5, 0(%5)", operands);
6112       break;
6114     default:
6115       gcc_unreachable ();
6116     }
6117   
6118   output_asm_insn ("addu\t%4, %4, %5", operands);
6119   
6120   return "j\t%4";
6122   [(set_attr "insn_count" "16")])
6124 ;; For TARGET_USE_GOT, we save the gp in the jmp_buf as well.
6125 ;; While it is possible to either pull it off the stack (in the
6126 ;; o32 case) or recalculate it given t9 and our target label,
6127 ;; it takes 3 or 4 insns to do so.
6129 (define_expand "builtin_setjmp_setup"
6130   [(use (match_operand 0 "register_operand"))]
6131   "TARGET_USE_GOT"
6133   rtx addr;
6135   addr = plus_constant (Pmode, operands[0], GET_MODE_SIZE (Pmode) * 3);
6136   mips_emit_move (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
6137   DONE;
6140 ;; Restore the gp that we saved above.  Despite the earlier comment, it seems
6141 ;; that older code did recalculate the gp from $25.  Continue to jump through
6142 ;; $25 for compatibility (we lose nothing by doing so).
6144 (define_expand "builtin_longjmp"
6145   [(use (match_operand 0 "register_operand"))]
6146   "TARGET_USE_GOT"
6148   /* The elements of the buffer are, in order:  */
6149   int W = GET_MODE_SIZE (Pmode);
6150   rtx fp = gen_rtx_MEM (Pmode, operands[0]);
6151   rtx lab = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], 1*W));
6152   rtx stack = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], 2*W));
6153   rtx gpv = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], 3*W));
6154   rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
6155   /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
6156      The target is bound to be using $28 as the global pointer
6157      but the current function might not be.  */
6158   rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
6160   /* This bit is similar to expand_builtin_longjmp except that it
6161      restores $gp as well.  */
6162   mips_emit_move (hard_frame_pointer_rtx, fp);
6163   mips_emit_move (pv, lab);
6164   emit_stack_restore (SAVE_NONLOCAL, stack);
6165   mips_emit_move (gp, gpv);
6166   emit_use (hard_frame_pointer_rtx);
6167   emit_use (stack_pointer_rtx);
6168   emit_use (gp);
6169   emit_indirect_jump (pv);
6170   DONE;
6174 ;;  ....................
6176 ;;      Function prologue/epilogue
6178 ;;  ....................
6181 (define_expand "prologue"
6182   [(const_int 1)]
6183   ""
6185   mips_expand_prologue ();
6186   DONE;
6189 ;; Block any insns from being moved before this point, since the
6190 ;; profiling call to mcount can use various registers that aren't
6191 ;; saved or used to pass arguments.
6193 (define_insn "blockage"
6194   [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
6195   ""
6196   ""
6197   [(set_attr "type" "ghost")
6198    (set_attr "mode" "none")])
6200 (define_insn "probe_stack_range_<P:mode>"
6201   [(set (match_operand:P 0 "register_operand" "=d")
6202         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6203                             (match_operand:P 2 "register_operand" "d")]
6204                             UNSPEC_PROBE_STACK_RANGE))]
6205   ""
6206  { return mips_output_probe_stack_range (operands[0], operands[2]); }
6207   [(set_attr "type" "unknown")
6208    (set_attr "can_delay" "no")
6209    (set_attr "mode" "<MODE>")])
6211 (define_expand "epilogue"
6212   [(const_int 2)]
6213   ""
6215   mips_expand_epilogue (false);
6216   DONE;
6219 (define_expand "sibcall_epilogue"
6220   [(const_int 2)]
6221   ""
6223   mips_expand_epilogue (true);
6224   DONE;
6227 ;; Trivial return.  Make it look like a normal return insn as that
6228 ;; allows jump optimizations to work better.
6230 (define_expand "return"
6231   [(simple_return)]
6232   "mips_can_use_return_insn ()"
6233   { mips_expand_before_return (); })
6235 (define_expand "simple_return"
6236   [(simple_return)]
6237   ""
6238   { mips_expand_before_return (); })
6240 (define_insn "*<optab>"
6241   [(any_return)]
6242   ""
6243   {
6244     if (TARGET_MICROMIPS)
6245       return "%*jr%:\t$31";
6246     else
6247       return "%*j\t$31%/";
6248   }
6249   [(set_attr "type"     "jump")
6250    (set_attr "mode"     "none")])
6252 ;; Normal return.
6254 (define_insn "<optab>_internal"
6255   [(any_return)
6256    (use (match_operand 0 "pmode_register_operand" ""))]
6257   ""
6259   if (TARGET_MICROMIPS)
6260     return "%*jr%:\t%0";
6261   else
6262     return "%*j\t%0%/";
6264   [(set_attr "type"     "jump")
6265    (set_attr "mode"     "none")])
6267 ;; Exception return.
6268 (define_insn "mips_eret"
6269   [(return)
6270    (unspec_volatile [(const_int 0)] UNSPEC_ERET)]
6271   ""
6272   "eret"
6273   [(set_attr "type"     "trap")
6274    (set_attr "mode"     "none")])
6276 ;; Debug exception return.
6277 (define_insn "mips_deret"
6278   [(return)
6279    (unspec_volatile [(const_int 0)] UNSPEC_DERET)]
6280   ""
6281   "deret"
6282   [(set_attr "type"     "trap")
6283    (set_attr "mode"     "none")])
6285 ;; Disable interrupts.
6286 (define_insn "mips_di"
6287   [(unspec_volatile [(const_int 0)] UNSPEC_DI)]
6288   ""
6289   "di"
6290   [(set_attr "type"     "trap")
6291    (set_attr "mode"     "none")])
6293 ;; Execution hazard barrier.
6294 (define_insn "mips_ehb"
6295   [(unspec_volatile [(const_int 0)] UNSPEC_EHB)]
6296   ""
6297   "ehb"
6298   [(set_attr "type"     "trap")
6299    (set_attr "mode"     "none")])
6301 ;; Read GPR from previous shadow register set.
6302 (define_insn "mips_rdpgpr"
6303   [(set (match_operand:SI 0 "register_operand" "=d")
6304         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "d")]
6305                             UNSPEC_RDPGPR))]
6306   ""
6307   "rdpgpr\t%0,%1"
6308   [(set_attr "type"     "move")
6309    (set_attr "mode"     "SI")])
6311 ;; Move involving COP0 registers.
6312 (define_insn "cop0_move"
6313   [(set (match_operand:SI 0 "register_operand" "=B,d")
6314         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "d,B")]
6315                             UNSPEC_COP0))]
6316   ""
6317 { return mips_output_move (operands[0], operands[1]); }
6318   [(set_attr "type"     "mtc,mfc")
6319    (set_attr "mode"     "SI")])
6321 ;; This is used in compiling the unwind routines.
6322 (define_expand "eh_return"
6323   [(use (match_operand 0 "general_operand"))]
6324   ""
6326   if (GET_MODE (operands[0]) != word_mode)
6327     operands[0] = convert_to_mode (word_mode, operands[0], 0);
6328   if (TARGET_64BIT)
6329     emit_insn (gen_eh_set_lr_di (operands[0]));
6330   else
6331     emit_insn (gen_eh_set_lr_si (operands[0]));
6332   DONE;
6335 ;; Clobber the return address on the stack.  We can't expand this
6336 ;; until we know where it will be put in the stack frame.
6338 (define_insn "eh_set_lr_si"
6339   [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
6340    (clobber (match_scratch:SI 1 "=&d"))]
6341   "! TARGET_64BIT"
6342   "#")
6344 (define_insn "eh_set_lr_di"
6345   [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
6346    (clobber (match_scratch:DI 1 "=&d"))]
6347   "TARGET_64BIT"
6348   "#")
6350 (define_split
6351   [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
6352    (clobber (match_scratch 1))]
6353   "reload_completed"
6354   [(const_int 0)]
6356   mips_set_return_address (operands[0], operands[1]);
6357   DONE;
6360 (define_expand "exception_receiver"
6361   [(const_int 0)]
6362   "TARGET_USE_GOT"
6364   /* See the comment above load_call<mode> for details.  */
6365   emit_insn (gen_set_got_version ());
6367   /* If we have a call-clobbered $gp, restore it from its save slot.  */
6368   if (HAVE_restore_gp_si)
6369     emit_insn (gen_restore_gp_si ());
6370   else if (HAVE_restore_gp_di)
6371     emit_insn (gen_restore_gp_di ());
6372   DONE;
6375 (define_expand "nonlocal_goto_receiver"
6376   [(const_int 0)]
6377   "TARGET_USE_GOT"
6379   /* See the comment above load_call<mode> for details.  */
6380   emit_insn (gen_set_got_version ());
6381   DONE;
6384 ;; Restore $gp from its .cprestore stack slot.  The instruction remains
6385 ;; volatile until all uses of $28 are exposed.
6386 (define_insn_and_split "restore_gp_<mode>"
6387   [(set (reg:P 28)
6388         (unspec_volatile:P [(const_int 0)] UNSPEC_RESTORE_GP))
6389    (clobber (match_scratch:P 0 "=&d"))]
6390   "TARGET_CALL_CLOBBERED_GP"
6391   "#"
6392   "&& epilogue_completed"
6393   [(const_int 0)]
6395   mips_restore_gp_from_cprestore_slot (operands[0]);
6396   DONE;
6398   [(set_attr "type" "ghost")])
6400 ;; Move between $gp and its register save slot.
6401 (define_insn_and_split "move_gp<mode>"
6402   [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,m")
6403         (unspec:GPR [(match_operand:GPR 1 "move_operand" "m,d")]
6404                     UNSPEC_MOVE_GP))]
6405   ""
6406   { return mips_must_initialize_gp_p () ? "#" : ""; }
6407   "mips_must_initialize_gp_p ()"
6408   [(const_int 0)]
6410   mips_emit_move (operands[0], operands[1]);
6411   DONE;
6413   [(set_attr "type" "ghost")])
6416 ;;  ....................
6418 ;;      FUNCTION CALLS
6420 ;;  ....................
6422 ;; Instructions to load a call address from the GOT.  The address might
6423 ;; point to a function or to a lazy binding stub.  In the latter case,
6424 ;; the stub will use the dynamic linker to resolve the function, which
6425 ;; in turn will change the GOT entry to point to the function's real
6426 ;; address.
6428 ;; This means that every call, even pure and constant ones, can
6429 ;; potentially modify the GOT entry.  And once a stub has been called,
6430 ;; we must not call it again.
6432 ;; We represent this restriction using an imaginary, fixed, call-saved
6433 ;; register called GOT_VERSION_REGNUM.  The idea is to make the register
6434 ;; live throughout the function and to change its value after every
6435 ;; potential call site.  This stops any rtx value that uses the register
6436 ;; from being computed before an earlier call.  To do this, we:
6438 ;;    - Ensure that the register is live on entry to the function,
6439 ;;      so that it is never thought to be used uninitalized.
6441 ;;    - Ensure that the register is live on exit from the function,
6442 ;;      so that it is live throughout.
6444 ;;    - Make each call (lazily-bound or not) use the current value
6445 ;;      of GOT_VERSION_REGNUM, so that updates of the register are
6446 ;;      not moved across call boundaries.
6448 ;;    - Add "ghost" definitions of the register to the beginning of
6449 ;;      blocks reached by EH and ABNORMAL_CALL edges, because those
6450 ;;      edges may involve calls that normal paths don't.  (E.g. the
6451 ;;      unwinding code that handles a non-call exception may change
6452 ;;      lazily-bound GOT entries.)  We do this by making the
6453 ;;      exception_receiver and nonlocal_goto_receiver expanders emit
6454 ;;      a set_got_version instruction.
6456 ;;    - After each call (lazily-bound or not), use a "ghost"
6457 ;;      update_got_version instruction to change the register's value.
6458 ;;      This instruction mimics the _possible_ effect of the dynamic
6459 ;;      resolver during the call and it remains live even if the call
6460 ;;      itself becomes dead.
6462 ;;    - Leave GOT_VERSION_REGNUM out of all register classes.
6463 ;;      The register is therefore not a valid register_operand
6464 ;;      and cannot be moved to or from other registers.
6466 (define_insn "load_call<mode>"
6467   [(set (match_operand:P 0 "register_operand" "=d")
6468         (unspec:P [(match_operand:P 1 "register_operand" "d")
6469                    (match_operand:P 2 "immediate_operand" "")
6470                    (reg:SI GOT_VERSION_REGNUM)] UNSPEC_LOAD_CALL))]
6471   "TARGET_USE_GOT"
6472   "<load>\t%0,%R2(%1)"
6473   [(set_attr "got" "load")
6474    (set_attr "mode" "<MODE>")])
6476 (define_insn "set_got_version"
6477   [(set (reg:SI GOT_VERSION_REGNUM)
6478         (unspec_volatile:SI [(const_int 0)] UNSPEC_SET_GOT_VERSION))]
6479   "TARGET_USE_GOT"
6480   ""
6481   [(set_attr "type" "ghost")])
6483 (define_insn "update_got_version"
6484   [(set (reg:SI GOT_VERSION_REGNUM)
6485         (unspec:SI [(reg:SI GOT_VERSION_REGNUM)] UNSPEC_UPDATE_GOT_VERSION))]
6486   "TARGET_USE_GOT"
6487   ""
6488   [(set_attr "type" "ghost")])
6490 ;; Sibling calls.  All these patterns use jump instructions.
6492 ;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
6493 ;; addresses if a direct jump is acceptable.  Since the 'S' constraint
6494 ;; is defined in terms of call_insn_operand, the same is true of the
6495 ;; constraints.
6497 ;; When we use an indirect jump, we need a register that will be
6498 ;; preserved by the epilogue.  Since TARGET_USE_PIC_FN_ADDR_REG forces
6499 ;; us to use $25 for this purpose -- and $25 is never clobbered by the
6500 ;; epilogue -- we might as well use it for !TARGET_USE_PIC_FN_ADDR_REG
6501 ;; as well.
6503 (define_expand "sibcall"
6504   [(parallel [(call (match_operand 0 "")
6505                     (match_operand 1 ""))
6506               (use (match_operand 2 ""))        ;; next_arg_reg
6507               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
6508   "TARGET_SIBCALLS"
6510   mips_expand_call (MIPS_CALL_SIBCALL, NULL_RTX, XEXP (operands[0], 0),
6511                     operands[1], operands[2], false);
6512   DONE;
6515 (define_insn "sibcall_internal"
6516   [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
6517          (match_operand 1 "" ""))]
6518   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6520   if (TARGET_MICROMIPS)
6521     return MICROMIPS_J ("j", operands, 0);
6522   else
6523     return MIPS_CALL ("j", operands, 0, 1);
6525   [(set_attr "jal" "indirect,direct")
6526    (set_attr "jal_macro" "no")])
6528 (define_expand "sibcall_value"
6529   [(parallel [(set (match_operand 0 "")
6530                    (call (match_operand 1 "")
6531                          (match_operand 2 "")))
6532               (use (match_operand 3 ""))])]             ;; next_arg_reg
6533   "TARGET_SIBCALLS"
6535   mips_expand_call (MIPS_CALL_SIBCALL, operands[0], XEXP (operands[1], 0),
6536                     operands[2], operands[3], false);
6537   DONE;
6540 (define_insn "sibcall_value_internal"
6541   [(set (match_operand 0 "register_operand" "")
6542         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
6543               (match_operand 2 "" "")))]
6544   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6546   if (TARGET_MICROMIPS)
6547     return MICROMIPS_J ("j", operands, 1);
6548   else
6549     return MIPS_CALL ("j", operands, 1, 2);
6551   [(set_attr "jal" "indirect,direct")
6552    (set_attr "jal_macro" "no")])
6554 (define_insn "sibcall_value_multiple_internal"
6555   [(set (match_operand 0 "register_operand" "")
6556         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
6557               (match_operand 2 "" "")))
6558    (set (match_operand 3 "register_operand" "")
6559         (call (mem:SI (match_dup 1))
6560               (match_dup 2)))]
6561   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6563   if (TARGET_MICROMIPS)
6564     return MICROMIPS_J ("j", operands, 1);
6565   else
6566     return MIPS_CALL ("j", operands, 1, 2);
6568   [(set_attr "jal" "indirect,direct")
6569    (set_attr "jal_macro" "no")])
6571 (define_expand "call"
6572   [(parallel [(call (match_operand 0 "")
6573                     (match_operand 1 ""))
6574               (use (match_operand 2 ""))        ;; next_arg_reg
6575               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
6576   ""
6578   mips_expand_call (MIPS_CALL_NORMAL, NULL_RTX, XEXP (operands[0], 0),
6579                     operands[1], operands[2], false);
6580   DONE;
6583 ;; This instruction directly corresponds to an assembly-language "jal".
6584 ;; There are four cases:
6586 ;;    - -mno-abicalls:
6587 ;;        Both symbolic and register destinations are OK.  The pattern
6588 ;;        always expands to a single mips instruction.
6590 ;;    - -mabicalls/-mno-explicit-relocs:
6591 ;;        Again, both symbolic and register destinations are OK.
6592 ;;        The call is treated as a multi-instruction black box.
6594 ;;    - -mabicalls/-mexplicit-relocs with n32 or n64:
6595 ;;        Only "jal $25" is allowed.  This expands to a single "jalr $25"
6596 ;;        instruction.
6598 ;;    - -mabicalls/-mexplicit-relocs with o32 or o64:
6599 ;;        Only "jal $25" is allowed.  The call is actually two instructions:
6600 ;;        "jalr $25" followed by an insn to reload $gp.
6602 ;; In the last case, we can generate the individual instructions with
6603 ;; a define_split.  There are several things to be wary of:
6605 ;;   - We can't expose the load of $gp before reload.  If we did,
6606 ;;     it might get removed as dead, but reload can introduce new
6607 ;;     uses of $gp by rematerializing constants.
6609 ;;   - We shouldn't restore $gp after calls that never return.
6610 ;;     It isn't valid to insert instructions between a noreturn
6611 ;;     call and the following barrier.
6613 ;;   - The splitter deliberately changes the liveness of $gp.  The unsplit
6614 ;;     instruction preserves $gp and so have no effect on its liveness.
6615 ;;     But once we generate the separate insns, it becomes obvious that
6616 ;;     $gp is not live on entry to the call.
6618 (define_insn_and_split "call_internal"
6619   [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
6620          (match_operand 1 "" ""))
6621    (clobber (reg:SI RETURN_ADDR_REGNUM))]
6622   ""
6623   { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 0, 1); }
6624   "reload_completed && TARGET_SPLIT_CALLS"
6625   [(const_int 0)]
6627   mips_split_call (curr_insn, gen_call_split (operands[0], operands[1]));
6628   DONE;
6630   [(set_attr "jal" "indirect,direct")])
6632 (define_insn "call_split"
6633   [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
6634          (match_operand 1 "" ""))
6635    (clobber (reg:SI RETURN_ADDR_REGNUM))
6636    (clobber (reg:SI 28))]
6637   "TARGET_SPLIT_CALLS"
6638   { return MIPS_CALL ("jal", operands, 0, 1); }
6639   [(set_attr "jal" "indirect,direct")
6640    (set_attr "jal_macro" "no")])
6642 ;; A pattern for calls that must be made directly.  It is used for
6643 ;; MIPS16 calls that the linker may need to redirect to a hard-float
6644 ;; stub; the linker relies on the call relocation type to detect when
6645 ;; such redirection is needed.
6646 (define_insn_and_split "call_internal_direct"
6647   [(call (mem:SI (match_operand 0 "const_call_insn_operand"))
6648          (match_operand 1))
6649    (const_int 1)
6650    (clobber (reg:SI RETURN_ADDR_REGNUM))]
6651   ""
6652   { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 0, -1); }
6653   "reload_completed && TARGET_SPLIT_CALLS"
6654   [(const_int 0)]
6656   mips_split_call (curr_insn,
6657                    gen_call_direct_split (operands[0], operands[1]));
6658   DONE;
6660   [(set_attr "jal" "direct")])
6662 (define_insn "call_direct_split"
6663   [(call (mem:SI (match_operand 0 "const_call_insn_operand"))
6664          (match_operand 1))
6665    (const_int 1)
6666    (clobber (reg:SI RETURN_ADDR_REGNUM))
6667    (clobber (reg:SI 28))]
6668   "TARGET_SPLIT_CALLS"
6669   { return MIPS_CALL ("jal", operands, 0, -1); }
6670   [(set_attr "jal" "direct")
6671    (set_attr "jal_macro" "no")])
6673 (define_expand "call_value"
6674   [(parallel [(set (match_operand 0 "")
6675                    (call (match_operand 1 "")
6676                          (match_operand 2 "")))
6677               (use (match_operand 3 ""))])]             ;; next_arg_reg
6678   ""
6680   mips_expand_call (MIPS_CALL_NORMAL, operands[0], XEXP (operands[1], 0),
6681                     operands[2], operands[3], false);
6682   DONE;
6685 ;; See comment for call_internal.
6686 (define_insn_and_split "call_value_internal"
6687   [(set (match_operand 0 "register_operand" "")
6688         (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
6689               (match_operand 2 "" "")))
6690    (clobber (reg:SI RETURN_ADDR_REGNUM))]
6691   ""
6692   { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1, 2); }
6693   "reload_completed && TARGET_SPLIT_CALLS"
6694   [(const_int 0)]
6696   mips_split_call (curr_insn,
6697                    gen_call_value_split (operands[0], operands[1],
6698                                          operands[2]));
6699   DONE;
6701   [(set_attr "jal" "indirect,direct")])
6703 (define_insn "call_value_split"
6704   [(set (match_operand 0 "register_operand" "")
6705         (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
6706               (match_operand 2 "" "")))
6707    (clobber (reg:SI RETURN_ADDR_REGNUM))
6708    (clobber (reg:SI 28))]
6709   "TARGET_SPLIT_CALLS"
6710   { return MIPS_CALL ("jal", operands, 1, 2); }
6711   [(set_attr "jal" "indirect,direct")
6712    (set_attr "jal_macro" "no")])
6714 ;; See call_internal_direct.
6715 (define_insn_and_split "call_value_internal_direct"
6716   [(set (match_operand 0 "register_operand")
6717         (call (mem:SI (match_operand 1 "const_call_insn_operand"))
6718               (match_operand 2)))
6719    (const_int 1)
6720    (clobber (reg:SI RETURN_ADDR_REGNUM))]
6721   ""
6722   { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1, -1); }
6723   "reload_completed && TARGET_SPLIT_CALLS"
6724   [(const_int 0)]
6726   mips_split_call (curr_insn,
6727                    gen_call_value_direct_split (operands[0], operands[1],
6728                                                 operands[2]));
6729   DONE;
6731   [(set_attr "jal" "direct")])
6733 (define_insn "call_value_direct_split"
6734   [(set (match_operand 0 "register_operand")
6735         (call (mem:SI (match_operand 1 "const_call_insn_operand"))
6736               (match_operand 2)))
6737    (const_int 1)
6738    (clobber (reg:SI RETURN_ADDR_REGNUM))
6739    (clobber (reg:SI 28))]
6740   "TARGET_SPLIT_CALLS"
6741   { return MIPS_CALL ("jal", operands, 1, -1); }
6742   [(set_attr "jal" "direct")
6743    (set_attr "jal_macro" "no")])
6745 ;; See comment for call_internal.
6746 (define_insn_and_split "call_value_multiple_internal"
6747   [(set (match_operand 0 "register_operand" "")
6748         (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
6749               (match_operand 2 "" "")))
6750    (set (match_operand 3 "register_operand" "")
6751         (call (mem:SI (match_dup 1))
6752               (match_dup 2)))
6753    (clobber (reg:SI RETURN_ADDR_REGNUM))]
6754   ""
6755   { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1, 2); }
6756   "reload_completed && TARGET_SPLIT_CALLS"
6757   [(const_int 0)]
6759   mips_split_call (curr_insn,
6760                    gen_call_value_multiple_split (operands[0], operands[1],
6761                                                   operands[2], operands[3]));
6762   DONE;
6764   [(set_attr "jal" "indirect,direct")])
6766 (define_insn "call_value_multiple_split"
6767   [(set (match_operand 0 "register_operand" "")
6768         (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
6769               (match_operand 2 "" "")))
6770    (set (match_operand 3 "register_operand" "")
6771         (call (mem:SI (match_dup 1))
6772               (match_dup 2)))
6773    (clobber (reg:SI RETURN_ADDR_REGNUM))
6774    (clobber (reg:SI 28))]
6775   "TARGET_SPLIT_CALLS"
6776   { return MIPS_CALL ("jal", operands, 1, 2); }
6777   [(set_attr "jal" "indirect,direct")
6778    (set_attr "jal_macro" "no")])
6780 ;; Call subroutine returning any type.
6782 (define_expand "untyped_call"
6783   [(parallel [(call (match_operand 0 "")
6784                     (const_int 0))
6785               (match_operand 1 "")
6786               (match_operand 2 "")])]
6787   ""
6789   int i;
6791   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
6793   for (i = 0; i < XVECLEN (operands[2], 0); i++)
6794     {
6795       rtx set = XVECEXP (operands[2], 0, i);
6796       mips_emit_move (SET_DEST (set), SET_SRC (set));
6797     }
6799   emit_insn (gen_blockage ());
6800   DONE;
6804 ;;  ....................
6806 ;;      MISC.
6808 ;;  ....................
6812 (define_insn "prefetch"
6813   [(prefetch (match_operand:QI 0 "address_operand" "ZD")
6814              (match_operand 1 "const_int_operand" "n")
6815              (match_operand 2 "const_int_operand" "n"))]
6816   "ISA_HAS_PREFETCH && TARGET_EXPLICIT_RELOCS"
6818   if (TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A)
6819     {
6820       /* Loongson 2[ef] and Loongson 3a use load to $0 for prefetching.  */
6821       if (TARGET_64BIT)
6822         return "ld\t$0,%a0";
6823       else
6824         return "lw\t$0,%a0";
6825     }
6826   operands[1] = mips_prefetch_cookie (operands[1], operands[2]);
6827   return "pref\t%1,%a0";
6829   [(set_attr "type" "prefetch")])
6831 (define_insn "*prefetch_indexed_<mode>"
6832   [(prefetch (plus:P (match_operand:P 0 "register_operand" "d")
6833                      (match_operand:P 1 "register_operand" "d"))
6834              (match_operand 2 "const_int_operand" "n")
6835              (match_operand 3 "const_int_operand" "n"))]
6836   "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6838   operands[2] = mips_prefetch_cookie (operands[2], operands[3]);
6839   return "prefx\t%2,%1(%0)";
6841   [(set_attr "type" "prefetchx")])
6843 (define_insn "nop"
6844   [(const_int 0)]
6845   ""
6846   "%(nop%)"
6847   [(set_attr "type"     "nop")
6848    (set_attr "mode"     "none")])
6850 ;; Like nop, but commented out when outside a .set noreorder block.
6851 (define_insn "hazard_nop"
6852   [(const_int 1)]
6853   ""
6854   {
6855     if (mips_noreorder.nesting_level > 0)
6856       return "nop";
6857     else
6858       return "#nop";
6859   }
6860   [(set_attr "type"     "nop")])
6862 ;; MIPS4 Conditional move instructions.
6864 (define_insn "*mov<GPR:mode>_on_<MOVECC:mode>"
6865   [(set (match_operand:GPR 0 "register_operand" "=d,d")
6866         (if_then_else:GPR
6867          (match_operator 4 "equality_operator"
6868                 [(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>")
6869                  (const_int 0)])
6870          (match_operand:GPR 2 "reg_or_0_operand" "dJ,0")
6871          (match_operand:GPR 3 "reg_or_0_operand" "0,dJ")))]
6872   "ISA_HAS_CONDMOVE"
6873   "@
6874     mov%T4\t%0,%z2,%1
6875     mov%t4\t%0,%z3,%1"
6876   [(set_attr "type" "condmove")
6877    (set_attr "mode" "<GPR:MODE>")])
6879 (define_insn "*mov<GPR:mode>_on_<GPR2:mode>_ne"
6880   [(set (match_operand:GPR 0 "register_operand" "=d,d")
6881        (if_then_else:GPR
6882         (match_operand:GPR2 1 "register_operand" "<GPR2:reg>,<GPR2:reg>")
6883         (match_operand:GPR 2 "reg_or_0_operand" "dJ,0")
6884         (match_operand:GPR 3 "reg_or_0_operand" "0,dJ")))]
6885   "ISA_HAS_CONDMOVE"
6886   "@
6887     movn\t%0,%z2,%1
6888     movz\t%0,%z3,%1"
6889   [(set_attr "type" "condmove")
6890    (set_attr "mode" "<GPR:MODE>")])
6892 (define_insn "*mov<SCALARF:mode>_on_<MOVECC:mode>"
6893   [(set (match_operand:SCALARF 0 "register_operand" "=f,f")
6894         (if_then_else:SCALARF
6895          (match_operator 4 "equality_operator"
6896                 [(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>")
6897                  (const_int 0)])
6898          (match_operand:SCALARF 2 "register_operand" "f,0")
6899          (match_operand:SCALARF 3 "register_operand" "0,f")))]
6900   "ISA_HAS_FP_CONDMOVE"
6901   "@
6902     mov%T4.<fmt>\t%0,%2,%1
6903     mov%t4.<fmt>\t%0,%3,%1"
6904   [(set_attr "type" "condmove")
6905    (set_attr "mode" "<SCALARF:MODE>")])
6907 ;; These are the main define_expand's used to make conditional moves.
6909 (define_expand "mov<mode>cc"
6910   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
6911    (set (match_operand:GPR 0 "register_operand")
6912         (if_then_else:GPR (match_dup 5)
6913                           (match_operand:GPR 2 "reg_or_0_operand")
6914                           (match_operand:GPR 3 "reg_or_0_operand")))]
6915   "ISA_HAS_CONDMOVE"
6917   mips_expand_conditional_move (operands);
6918   DONE;
6921 (define_expand "mov<mode>cc"
6922   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
6923    (set (match_operand:SCALARF 0 "register_operand")
6924         (if_then_else:SCALARF (match_dup 5)
6925                               (match_operand:SCALARF 2 "register_operand")
6926                               (match_operand:SCALARF 3 "register_operand")))]
6927   "ISA_HAS_FP_CONDMOVE"
6929   mips_expand_conditional_move (operands);
6930   DONE;
6934 ;;  ....................
6936 ;;      mips16 inline constant tables
6938 ;;  ....................
6941 (define_insn "consttable_tls_reloc"
6942   [(unspec_volatile [(match_operand 0 "tls_reloc_operand" "")
6943                      (match_operand 1 "const_int_operand" "")]
6944                     UNSPEC_CONSTTABLE_INT)]
6945   "TARGET_MIPS16_PCREL_LOADS"
6946   { return mips_output_tls_reloc_directive (&operands[0]); }
6947   [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
6949 (define_insn "consttable_int"
6950   [(unspec_volatile [(match_operand 0 "consttable_operand" "")
6951                      (match_operand 1 "const_int_operand" "")]
6952                     UNSPEC_CONSTTABLE_INT)]
6953   "TARGET_MIPS16"
6955   assemble_integer (mips_strip_unspec_address (operands[0]),
6956                     INTVAL (operands[1]),
6957                     BITS_PER_UNIT * INTVAL (operands[1]), 1);
6958   return "";
6960   [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
6962 (define_insn "consttable_float"
6963   [(unspec_volatile [(match_operand 0 "consttable_operand" "")]
6964                     UNSPEC_CONSTTABLE_FLOAT)]
6965   "TARGET_MIPS16"
6967   REAL_VALUE_TYPE d;
6969   gcc_assert (GET_CODE (operands[0]) == CONST_DOUBLE);
6970   REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
6971   assemble_real (d, GET_MODE (operands[0]),
6972                  GET_MODE_BITSIZE (GET_MODE (operands[0])));
6973   return "";
6975   [(set (attr "length")
6976         (symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))])
6978 (define_insn "align"
6979   [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)]
6980   ""
6981   ".align\t%0"
6982   [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))])
6984 (define_split
6985   [(match_operand 0 "small_data_pattern")]
6986   "reload_completed"
6987   [(match_dup 0)]
6988   { operands[0] = mips_rewrite_small_data (operands[0]); })
6991 ;;  ....................
6993 ;;      MIPS16e Save/Restore
6995 ;;  ....................
6998 (define_insn "*mips16e_save_restore"
6999   [(match_parallel 0 ""
7000        [(set (match_operand:SI 1 "register_operand")
7001              (plus:SI (match_dup 1)
7002                       (match_operand:SI 2 "const_int_operand")))])]
7003   "operands[1] == stack_pointer_rtx
7004    && mips16e_save_restore_pattern_p (operands[0], INTVAL (operands[2]), NULL)"
7005   { return mips16e_output_save_restore (operands[0], INTVAL (operands[2])); }
7006   [(set_attr "type" "arith")
7007    (set_attr "extended_mips16" "yes")])
7009 ;; Thread-Local Storage
7011 ;; The TLS base pointer is accessed via "rdhwr $3, $29".  No current
7012 ;; MIPS architecture defines this register, and no current
7013 ;; implementation provides it; instead, any OS which supports TLS is
7014 ;; expected to trap and emulate this instruction.  rdhwr is part of the
7015 ;; MIPS 32r2 specification, but we use it on any architecture because
7016 ;; we expect it to be emulated.  Use .set to force the assembler to
7017 ;; accept it.
7019 ;; We do not use a constraint to force the destination to be $3
7020 ;; because $3 can appear explicitly as a function return value.
7021 ;; If we leave the use of $3 implicit in the constraints until
7022 ;; reload, we may end up making a $3 return value live across
7023 ;; the instruction, leading to a spill failure when reloading it.
7024 (define_insn_and_split "tls_get_tp_<mode>"
7025   [(set (match_operand:P 0 "register_operand" "=d")
7026         (unspec:P [(const_int 0)] UNSPEC_TLS_GET_TP))
7027    (clobber (reg:P TLS_GET_TP_REGNUM))]
7028   "HAVE_AS_TLS && !TARGET_MIPS16"
7029   "#"
7030   "&& reload_completed"
7031   [(set (reg:P TLS_GET_TP_REGNUM)
7032         (unspec:P [(const_int 0)] UNSPEC_TLS_GET_TP))
7033    (set (match_dup 0) (reg:P TLS_GET_TP_REGNUM))]
7034   ""
7035   [(set_attr "type" "unknown")
7036    (set_attr "mode" "<MODE>")
7037    (set_attr "insn_count" "2")])
7039 (define_insn "*tls_get_tp_<mode>_split"
7040   [(set (reg:P TLS_GET_TP_REGNUM)
7041         (unspec:P [(const_int 0)] UNSPEC_TLS_GET_TP))]
7042   "HAVE_AS_TLS && !TARGET_MIPS16"
7043   ".set\tpush\;.set\tmips32r2\t\;rdhwr\t$3,$29\;.set\tpop"
7044   [(set_attr "type" "unknown")
7045    ; Since rdhwr always generates a trap for now, putting it in a delay
7046    ; slot would make the kernel's emulation of it much slower.
7047    (set_attr "can_delay" "no")
7048    (set_attr "mode" "<MODE>")])
7050 ;; In MIPS16 mode, the TLS base pointer is accessed by a
7051 ;; libgcc helper function __mips16_rdhwr(), as 'rdhwr' is not
7052 ;; accessible in MIPS16.
7054 ;; This is not represented as a call insn, to avoid the
7055 ;; unnecesarry clobbering of caller-save registers by a
7056 ;; function consisting only of: "rdhwr $3,$29; j $31; nop;"
7058 ;; A $25 clobber is added to cater for a $25 load stub added by the
7059 ;; linker to __mips16_rdhwr when the call is made from non-PIC code.
7061 (define_insn_and_split "tls_get_tp_mips16_<mode>"
7062   [(set (match_operand:P 0 "register_operand" "=d")
7063         (unspec:P [(match_operand:P 1 "call_insn_operand" "dS")]
7064                   UNSPEC_TLS_GET_TP))
7065    (clobber (reg:P TLS_GET_TP_REGNUM))
7066    (clobber (reg:P PIC_FUNCTION_ADDR_REGNUM))
7067    (clobber (reg:P RETURN_ADDR_REGNUM))]
7068   "HAVE_AS_TLS && TARGET_MIPS16"
7069   "#"
7070   "&& reload_completed"
7071   [(parallel [(set (reg:P TLS_GET_TP_REGNUM)
7072                    (unspec:P [(match_dup 1)] UNSPEC_TLS_GET_TP))
7073               (clobber (reg:P PIC_FUNCTION_ADDR_REGNUM))
7074               (clobber (reg:P RETURN_ADDR_REGNUM))])
7075    (set (match_dup 0) (reg:P TLS_GET_TP_REGNUM))]
7076   ""
7077   [(set_attr "type" "multi")
7078    (set_attr "insn_count" "4")
7079    (set_attr "mode" "<MODE>")])
7081 (define_insn "*tls_get_tp_mips16_call_<mode>"
7082   [(set (reg:P TLS_GET_TP_REGNUM)
7083         (unspec:P [(match_operand:P 0 "call_insn_operand" "dS")]
7084                   UNSPEC_TLS_GET_TP))
7085    (clobber (reg:P PIC_FUNCTION_ADDR_REGNUM))
7086    (clobber (reg:P RETURN_ADDR_REGNUM))]
7087   "HAVE_AS_TLS && TARGET_MIPS16"
7088   { return MIPS_CALL ("jal", operands, 0, -1); }
7089   [(set_attr "type" "call")
7090    (set_attr "insn_count" "3")
7091    (set_attr "mode" "<MODE>")])
7093 ;; Named pattern for expanding thread pointer reference.
7094 (define_expand "get_thread_pointer<mode>"
7095   [(match_operand:P 0 "register_operand" "=d")]
7096   "HAVE_AS_TLS"
7098   mips_expand_thread_pointer (operands[0]);
7099   DONE;
7102 ;; __builtin_mips_get_fcsr: move the FCSR into operand 0.
7103 (define_expand "mips_get_fcsr"
7104   [(set (match_operand:SI 0 "register_operand")
7105         (unspec_volatile [(const_int 0)] UNSPEC_GET_FCSR))]
7106   "TARGET_HARD_FLOAT_ABI"
7108   if (TARGET_MIPS16)
7109     {
7110       mips16_expand_get_fcsr (operands[0]);
7111       DONE;
7112     }
7115 (define_insn "*mips_get_fcsr"
7116   [(set (match_operand:SI 0 "register_operand" "=d")
7117         (unspec_volatile [(const_int 0)] UNSPEC_GET_FCSR))]
7118   "TARGET_HARD_FLOAT"
7119   "cfc1\t%0,$31")
7121 ;; See tls_get_tp_mips16_<mode> for why this form is used.
7122 (define_insn "mips_get_fcsr_mips16_<mode>"
7123   [(set (reg:SI GET_FCSR_REGNUM)
7124         (unspec:SI [(match_operand:P 0 "call_insn_operand" "dS")]
7125                    UNSPEC_GET_FCSR))
7126    (clobber (reg:P PIC_FUNCTION_ADDR_REGNUM))
7127    (clobber (reg:P RETURN_ADDR_REGNUM))]
7128   "TARGET_HARD_FLOAT_ABI && TARGET_MIPS16"
7129   { return MIPS_CALL ("jal", operands, 0, -1); }
7130   [(set_attr "type" "call")
7131    (set_attr "insn_count" "3")])
7133 ;; __builtin_mips_set_fcsr: move operand 0 into the FCSR.
7134 (define_expand "mips_set_fcsr"
7135   [(unspec_volatile [(match_operand:SI 0 "register_operand")]
7136                     UNSPEC_SET_FCSR)]
7137   "TARGET_HARD_FLOAT_ABI"
7139   if (TARGET_MIPS16)
7140     {
7141       mips16_expand_set_fcsr (operands[0]);
7142       DONE;
7143     }
7146 (define_insn "*mips_set_fcsr"
7147   [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")]
7148                     UNSPEC_SET_FCSR)]
7149   "TARGET_HARD_FLOAT"
7150   "ctc1\t%0,$31")
7152 ;; See tls_get_tp_mips16_<mode> for why this form is used.
7153 (define_insn "mips_set_fcsr_mips16_<mode>"
7154   [(unspec_volatile:SI [(match_operand:P 0 "call_insn_operand" "dS")
7155                         (reg:SI SET_FCSR_REGNUM)] UNSPEC_SET_FCSR)
7156    (clobber (reg:P PIC_FUNCTION_ADDR_REGNUM))
7157    (clobber (reg:P RETURN_ADDR_REGNUM))]
7158   "TARGET_HARD_FLOAT_ABI && TARGET_MIPS16"
7159   { return MIPS_CALL ("jal", operands, 0, -1); }
7160   [(set_attr "type" "call")
7161    (set_attr "insn_count" "3")])
7163 ;; Synchronization instructions.
7165 (include "sync.md")
7167 ; The MIPS Paired-Single Floating Point and MIPS-3D Instructions.
7169 (include "mips-ps-3d.md")
7171 ; The MIPS DSP Instructions.
7173 (include "mips-dsp.md")
7175 ; The MIPS DSP REV 2 Instructions.
7177 (include "mips-dspr2.md")
7179 ; MIPS fixed-point instructions.
7180 (include "mips-fixed.md")
7182 ; microMIPS patterns.
7183 (include "micromips.md")
7185 ; ST-Microelectronics Loongson-2E/2F-specific patterns.
7186 (include "loongson.md")
7188 (define_c_enum "unspec" [
7189   UNSPEC_ADDRESS_FIRST