PR target/56858
[official-gcc.git] / gcc / config / mips / mips.md
blob7e23bd210660dc3e23f0d1bf71dac23956f7ae8f
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
68   p5600
71 (define_c_enum "unspec" [
72   ;; Unaligned accesses.
73   UNSPEC_LOAD_LEFT
74   UNSPEC_LOAD_RIGHT
75   UNSPEC_STORE_LEFT
76   UNSPEC_STORE_RIGHT
78   ;; Integer operations that are too cumbersome to describe directly.
79   UNSPEC_WSBH
80   UNSPEC_DSBH
81   UNSPEC_DSHD
83   ;; Floating-point moves.
84   UNSPEC_LOAD_LOW
85   UNSPEC_LOAD_HIGH
86   UNSPEC_STORE_WORD
87   UNSPEC_MFHC1
88   UNSPEC_MTHC1
90   ;; Floating-point environment.
91   UNSPEC_GET_FCSR
92   UNSPEC_SET_FCSR
94   ;; HI/LO moves.
95   UNSPEC_MFHI
96   UNSPEC_MTHI
97   UNSPEC_SET_HILO
99   ;; GP manipulation.
100   UNSPEC_LOADGP
101   UNSPEC_COPYGP
102   UNSPEC_MOVE_GP
103   UNSPEC_POTENTIAL_CPRESTORE
104   UNSPEC_CPRESTORE
105   UNSPEC_RESTORE_GP
106   UNSPEC_EH_RETURN
107   UNSPEC_GP
108   UNSPEC_SET_GOT_VERSION
109   UNSPEC_UPDATE_GOT_VERSION
111   ;; Symbolic accesses.
112   UNSPEC_LOAD_CALL
113   UNSPEC_LOAD_GOT
114   UNSPEC_TLS_LDM
115   UNSPEC_TLS_GET_TP
116   UNSPEC_UNSHIFTED_HIGH
118   ;; MIPS16 constant pools.
119   UNSPEC_ALIGN
120   UNSPEC_CONSTTABLE_INT
121   UNSPEC_CONSTTABLE_FLOAT
123   ;; Blockage and synchronisation.
124   UNSPEC_BLOCKAGE
125   UNSPEC_CLEAR_HAZARD
126   UNSPEC_RDHWR
127   UNSPEC_SYNCI
128   UNSPEC_SYNC
130   ;; Cache manipulation.
131   UNSPEC_MIPS_CACHE
132   UNSPEC_R10K_CACHE_BARRIER
134   ;; Interrupt handling.
135   UNSPEC_ERET
136   UNSPEC_DERET
137   UNSPEC_DI
138   UNSPEC_EHB
139   UNSPEC_RDPGPR
140   UNSPEC_COP0
142   ;; Used in a call expression in place of args_size.  It's present for PIC
143   ;; indirect calls where it contains args_size and the function symbol.
144   UNSPEC_CALL_ATTR
146   ;; MIPS16 casesi jump table dispatch.
147   UNSPEC_CASESI_DISPATCH
149   ;; Stack checking.
150   UNSPEC_PROBE_STACK_RANGE
153 (define_constants
154   [(TLS_GET_TP_REGNUM           3)
155    (GET_FCSR_REGNUM             2)
156    (SET_FCSR_REGNUM             4)
157    (MIPS16_T_REGNUM             24)
158    (PIC_FUNCTION_ADDR_REGNUM    25)
159    (RETURN_ADDR_REGNUM          31)
160    (CPRESTORE_SLOT_REGNUM       76)
161    (GOT_VERSION_REGNUM          79)
163    ;; PIC long branch sequences are never longer than 100 bytes.
164    (MAX_PIC_BRANCH_LENGTH       100)
165   ]
168 (include "predicates.md")
169 (include "constraints.md")
171 ;; ....................
173 ;;      Attributes
175 ;; ....................
177 (define_attr "got" "unset,xgot_high,load"
178   (const_string "unset"))
180 ;; For jal instructions, this attribute is DIRECT when the target address
181 ;; is symbolic and INDIRECT when it is a register.
182 (define_attr "jal" "unset,direct,indirect"
183   (const_string "unset"))
185 ;; This attribute is YES if the instruction is a jal macro (not a
186 ;; real jal instruction).
188 ;; jal is always a macro for TARGET_CALL_CLOBBERED_GP because it includes
189 ;; an instruction to restore $gp.  Direct jals are also macros for
190 ;; !TARGET_ABSOLUTE_JUMPS because they first load the target address
191 ;; into a register.
192 (define_attr "jal_macro" "no,yes"
193   (cond [(eq_attr "jal" "direct")
194          (symbol_ref "(TARGET_CALL_CLOBBERED_GP || !TARGET_ABSOLUTE_JUMPS
195                        ? JAL_MACRO_YES : JAL_MACRO_NO)")
196          (eq_attr "jal" "indirect")
197          (symbol_ref "(TARGET_CALL_CLOBBERED_GP
198                        ? JAL_MACRO_YES : JAL_MACRO_NO)")]
199         (const_string "no")))
201 ;; Classification of moves, extensions and truncations.  Most values
202 ;; are as for "type" (see below) but there are also the following
203 ;; move-specific values:
205 ;; constN       move an N-constraint integer into a MIPS16 register
206 ;; sll0         "sll DEST,SRC,0", which on 64-bit targets is guaranteed
207 ;;              to produce a sign-extended DEST, even if SRC is not
208 ;;              properly sign-extended
209 ;; ext_ins      EXT, DEXT, INS or DINS instruction
210 ;; andi         a single ANDI instruction
211 ;; loadpool     move a constant into a MIPS16 register by loading it
212 ;;              from the pool
213 ;; shift_shift  a shift left followed by a shift right
215 ;; This attribute is used to determine the instruction's length and
216 ;; scheduling type.  For doubleword moves, the attribute always describes
217 ;; the split instructions; in some cases, it is more appropriate for the
218 ;; scheduling type to be "multi" instead.
219 (define_attr "move_type"
220   "unknown,load,fpload,store,fpstore,mtc,mfc,mtlo,mflo,imul,move,fmove,
221    const,constN,signext,ext_ins,logical,arith,sll0,andi,loadpool,
222    shift_shift"
223   (const_string "unknown"))
225 (define_attr "alu_type" "unknown,add,sub,not,nor,and,or,xor"
226   (const_string "unknown"))
228 ;; Main data type used by the insn
229 (define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF,FPSW"
230   (const_string "unknown"))
232 ;; True if the main data type is twice the size of a word.
233 (define_attr "dword_mode" "no,yes"
234   (cond [(and (eq_attr "mode" "DI,DF")
235               (not (match_test "TARGET_64BIT")))
236          (const_string "yes")
238          (and (eq_attr "mode" "TI,TF")
239               (match_test "TARGET_64BIT"))
240          (const_string "yes")]
241         (const_string "no")))
243 ;; Attributes describing a sync loop.  These loops have the form:
245 ;;       if (RELEASE_BARRIER == YES) sync
246 ;;    1: OLDVAL = *MEM
247 ;;       if ((OLDVAL & INCLUSIVE_MASK) != REQUIRED_OLDVAL) goto 2
248 ;;         CMP  = 0 [delay slot]
249 ;;       $TMP1 = OLDVAL & EXCLUSIVE_MASK
250 ;;       $TMP2 = INSN1 (OLDVAL, INSN1_OP2)
251 ;;       $TMP3 = INSN2 ($TMP2, INCLUSIVE_MASK)
252 ;;       $AT |= $TMP1 | $TMP3
253 ;;       if (!commit (*MEM = $AT)) goto 1.
254 ;;         if (INSN1 != MOVE && INSN1 != LI) NEWVAL = $TMP3 [delay slot]
255 ;;       CMP  = 1
256 ;;       if (ACQUIRE_BARRIER == YES) sync
257 ;;    2:
259 ;; where "$" values are temporaries and where the other values are
260 ;; specified by the attributes below.  Values are specified as operand
261 ;; numbers and insns are specified as enums.  If no operand number is
262 ;; specified, the following values are used instead:
264 ;;    - OLDVAL: $AT
265 ;;    - CMP: NONE
266 ;;    - NEWVAL: $AT
267 ;;    - INCLUSIVE_MASK: -1
268 ;;    - REQUIRED_OLDVAL: OLDVAL & INCLUSIVE_MASK
269 ;;    - EXCLUSIVE_MASK: 0
271 ;; MEM and INSN1_OP2 are required.
273 ;; Ideally, the operand attributes would be integers, with -1 meaning "none",
274 ;; but the gen* programs don't yet support that.
275 (define_attr "sync_mem" "none,0,1,2,3,4,5" (const_string "none"))
276 (define_attr "sync_oldval" "none,0,1,2,3,4,5" (const_string "none"))
277 (define_attr "sync_cmp" "none,0,1,2,3,4,5" (const_string "none"))
278 (define_attr "sync_newval" "none,0,1,2,3,4,5" (const_string "none"))
279 (define_attr "sync_inclusive_mask" "none,0,1,2,3,4,5" (const_string "none"))
280 (define_attr "sync_exclusive_mask" "none,0,1,2,3,4,5" (const_string "none"))
281 (define_attr "sync_required_oldval" "none,0,1,2,3,4,5" (const_string "none"))
282 (define_attr "sync_insn1_op2" "none,0,1,2,3,4,5" (const_string "none"))
283 (define_attr "sync_insn1" "move,li,addu,addiu,subu,and,andi,or,ori,xor,xori"
284   (const_string "move"))
285 (define_attr "sync_insn2" "nop,and,xor,not"
286   (const_string "nop"))
287 ;; Memory model specifier.
288 ;; "0"-"9" values specify the operand that stores the memory model value.
289 ;; "10" specifies MEMMODEL_ACQ_REL,
290 ;; "11" specifies MEMMODEL_ACQUIRE.
291 (define_attr "sync_memmodel" "" (const_int 10))
293 ;; Accumulator operand for madd patterns.
294 (define_attr "accum_in" "none,0,1,2,3,4,5" (const_string "none"))
296 ;; Classification of each insn.
297 ;; branch       conditional branch
298 ;; jump         unconditional jump
299 ;; call         unconditional call
300 ;; load         load instruction(s)
301 ;; fpload       floating point load
302 ;; fpidxload    floating point indexed load
303 ;; store        store instruction(s)
304 ;; fpstore      floating point store
305 ;; fpidxstore   floating point indexed store
306 ;; prefetch     memory prefetch (register + offset)
307 ;; prefetchx    memory indexed prefetch (register + register)
308 ;; condmove     conditional moves
309 ;; mtc          transfer to coprocessor
310 ;; mfc          transfer from coprocessor
311 ;; mthi         transfer to a hi register
312 ;; mtlo         transfer to a lo register
313 ;; mfhi         transfer from a hi register
314 ;; mflo         transfer from a lo register
315 ;; const        load constant
316 ;; arith        integer arithmetic instructions
317 ;; logical      integer logical instructions
318 ;; shift        integer shift instructions
319 ;; slt          set less than instructions
320 ;; signext      sign extend instructions
321 ;; clz          the clz and clo instructions
322 ;; pop          the pop instruction
323 ;; trap         trap if instructions
324 ;; imul         integer multiply 2 operands
325 ;; imul3        integer multiply 3 operands
326 ;; imul3nc      integer multiply 3 operands without clobbering HI/LO
327 ;; imadd        integer multiply-add
328 ;; idiv         integer divide 2 operands
329 ;; idiv3        integer divide 3 operands
330 ;; move         integer register move ({,D}ADD{,U} with rt = 0)
331 ;; fmove        floating point register move
332 ;; fadd         floating point add/subtract
333 ;; fmul         floating point multiply
334 ;; fmadd        floating point multiply-add
335 ;; fdiv         floating point divide
336 ;; frdiv        floating point reciprocal divide
337 ;; frdiv1       floating point reciprocal divide step 1
338 ;; frdiv2       floating point reciprocal divide step 2
339 ;; fabs         floating point absolute value
340 ;; fneg         floating point negation
341 ;; fcmp         floating point compare
342 ;; fcvt         floating point convert
343 ;; fsqrt        floating point square root
344 ;; frsqrt       floating point reciprocal square root
345 ;; frsqrt1      floating point reciprocal square root step1
346 ;; frsqrt2      floating point reciprocal square root step2
347 ;; dspmac       DSP MAC instructions not saturating the accumulator
348 ;; dspmacsat    DSP MAC instructions that saturate the accumulator
349 ;; accext       DSP accumulator extract instructions
350 ;; accmod       DSP accumulator modify instructions
351 ;; dspalu       DSP ALU instructions not saturating the result
352 ;; dspalusat    DSP ALU instructions that saturate the result
353 ;; multi        multiword sequence (or user asm statements)
354 ;; atomic       atomic memory update instruction
355 ;; syncloop     memory atomic operation implemented as a sync loop
356 ;; nop          no operation
357 ;; ghost        an instruction that produces no real code
358 ;; multimem     microMIPS multiword load and store
359 (define_attr "type"
360   "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,
361    prefetch,prefetchx,condmove,mtc,mfc,mthi,mtlo,mfhi,mflo,const,arith,logical,
362    shift,slt,signext,clz,pop,trap,imul,imul3,imul3nc,imadd,idiv,idiv3,move,
363    fmove,fadd,fmul,fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt,
364    frsqrt,frsqrt1,frsqrt2,dspmac,dspmacsat,accext,accmod,dspalu,dspalusat,
365    multi,atomic,syncloop,nop,ghost,multimem"
366   (cond [(eq_attr "jal" "!unset") (const_string "call")
367          (eq_attr "got" "load") (const_string "load")
369          (eq_attr "alu_type" "add,sub") (const_string "arith")
371          (eq_attr "alu_type" "not,nor,and,or,xor") (const_string "logical")
373          ;; If a doubleword move uses these expensive instructions,
374          ;; it is usually better to schedule them in the same way
375          ;; as the singleword form, rather than as "multi".
376          (eq_attr "move_type" "load") (const_string "load")
377          (eq_attr "move_type" "fpload") (const_string "fpload")
378          (eq_attr "move_type" "store") (const_string "store")
379          (eq_attr "move_type" "fpstore") (const_string "fpstore")
380          (eq_attr "move_type" "mtc") (const_string "mtc")
381          (eq_attr "move_type" "mfc") (const_string "mfc")
382          (eq_attr "move_type" "mtlo") (const_string "mtlo")
383          (eq_attr "move_type" "mflo") (const_string "mflo")
385          ;; These types of move are always single insns.
386          (eq_attr "move_type" "imul") (const_string "imul")
387          (eq_attr "move_type" "fmove") (const_string "fmove")
388          (eq_attr "move_type" "loadpool") (const_string "load")
389          (eq_attr "move_type" "signext") (const_string "signext")
390          (eq_attr "move_type" "ext_ins") (const_string "arith")
391          (eq_attr "move_type" "arith") (const_string "arith")
392          (eq_attr "move_type" "logical") (const_string "logical")
393          (eq_attr "move_type" "sll0") (const_string "shift")
394          (eq_attr "move_type" "andi") (const_string "logical")
396          ;; These types of move are always split.
397          (eq_attr "move_type" "constN,shift_shift")
398            (const_string "multi")
400          ;; These types of move are split for doubleword modes only.
401          (and (eq_attr "move_type" "move,const")
402               (eq_attr "dword_mode" "yes"))
403            (const_string "multi")
404          (eq_attr "move_type" "move") (const_string "move")
405          (eq_attr "move_type" "const") (const_string "const")
406          (eq_attr "sync_mem" "!none") (const_string "syncloop")]
407         (const_string "unknown")))
409 ;; Mode for conversion types (fcvt)
410 ;; I2S          integer to float single (SI/DI to SF)
411 ;; I2D          integer to float double (SI/DI to DF)
412 ;; S2I          float to integer (SF to SI/DI)
413 ;; D2I          float to integer (DF to SI/DI)
414 ;; D2S          double to float single
415 ;; S2D          float single to double
417 (define_attr "cnv_mode" "unknown,I2S,I2D,S2I,D2I,D2S,S2D" 
418   (const_string "unknown"))
420 ;; Is this an extended instruction in mips16 mode?
421 (define_attr "extended_mips16" "no,yes"
422   (if_then_else (ior ;; In general, constant-pool loads are extended
423                      ;; instructions.  We don't yet optimize for 16-bit
424                      ;; PC-relative references.
425                      (eq_attr "move_type" "sll0,loadpool")
426                      (eq_attr "jal" "direct")
427                      (eq_attr "got" "load"))
428                 (const_string "yes")
429                 (const_string "no")))
431 (define_attr "compression" "none,all,micromips"
432   (const_string "none"))
434 (define_attr "enabled" "no,yes"
435   (if_then_else (ior (eq_attr "compression" "all,none")
436                      (and (eq_attr "compression" "micromips")
437                           (match_test "TARGET_MICROMIPS")))
438                 (const_string "yes")
439                 (const_string "no")))
441 ;; The number of individual instructions that a non-branch pattern generates,
442 ;; using units of BASE_INSN_LENGTH.
443 (define_attr "insn_count" ""
444   (cond [;; "Ghost" instructions occupy no space.
445          (eq_attr "type" "ghost")
446          (const_int 0)
448          ;; Extended instructions count as 2.
449          (and (eq_attr "extended_mips16" "yes")
450               (match_test "TARGET_MIPS16"))
451          (const_int 2)
453          ;; A GOT load followed by an add of $gp.  This is not used for MIPS16.
454          (eq_attr "got" "xgot_high")
455          (const_int 2)
457          ;; SHIFT_SHIFTs are decomposed into two separate instructions.
458          ;; They are extended instructions on MIPS16 targets.
459          (eq_attr "move_type" "shift_shift")
460          (if_then_else (match_test "TARGET_MIPS16")
461                        (const_int 4)
462                        (const_int 2))
464          ;; Check for doubleword moves that are decomposed into two
465          ;; instructions.  The individual instructions are unextended
466          ;; MIPS16 ones.
467          (and (eq_attr "move_type" "mtc,mfc,mtlo,mflo,move")
468               (eq_attr "dword_mode" "yes"))
469          (const_int 2)
471          ;; Constants, loads and stores are handled by external routines.
472          (and (eq_attr "move_type" "const,constN")
473               (eq_attr "dword_mode" "yes"))
474          (symbol_ref "mips_split_const_insns (operands[1])")
475          (eq_attr "move_type" "const,constN")
476          (symbol_ref "mips_const_insns (operands[1])")
477          (eq_attr "move_type" "load,fpload")
478          (symbol_ref "mips_load_store_insns (operands[1], insn)")
479          (eq_attr "move_type" "store,fpstore")
480          (symbol_ref "mips_load_store_insns (operands[0], insn)
481                       + (TARGET_FIX_24K ? 1 : 0)")
483          ;; In the worst case, a call macro will take 8 instructions:
484          ;;
485          ;;     lui $25,%call_hi(FOO)
486          ;;     addu $25,$25,$28
487          ;;     lw $25,%call_lo(FOO)($25)
488          ;;     nop
489          ;;     jalr $25
490          ;;     nop
491          ;;     lw $gp,X($sp)
492          ;;     nop
493          (eq_attr "jal_macro" "yes")
494          (const_int 8)
496          ;; Various VR4120 errata require a nop to be inserted after a macc
497          ;; instruction.  The assembler does this for us, so account for
498          ;; the worst-case length here.
499          (and (eq_attr "type" "imadd")
500               (match_test "TARGET_FIX_VR4120"))
501          (const_int 2)
503          ;; VR4120 errata MD(4): if there are consecutive dmult instructions,
504          ;; the result of the second one is missed.  The assembler should work
505          ;; around this by inserting a nop after the first dmult.
506          (and (eq_attr "type" "imul,imul3")
507               (eq_attr "mode" "DI")
508               (match_test "TARGET_FIX_VR4120"))
509          (const_int 2)
511          (eq_attr "type" "idiv,idiv3")
512          (symbol_ref "mips_idiv_insns ()")
514          (not (eq_attr "sync_mem" "none"))
515          (symbol_ref "mips_sync_loop_insns (insn, operands)")]
516         (const_int 1)))
518 ;; Length of instruction in bytes.  The default is derived from "insn_count",
519 ;; but there are special cases for branches (which must be handled here)
520 ;; and for compressed single instructions.
521 (define_attr "length" ""
522    (cond [(and (eq_attr "compression" "micromips,all")
523                (eq_attr "dword_mode" "no")
524                (match_test "TARGET_MICROMIPS"))
525           (const_int 2)
527           ;; Direct microMIPS branch instructions have a range of
528           ;; [-0x10000,0xfffe], otherwise the range is [-0x20000,0x1fffc].
529           ;; If a branch is outside this range, we have a choice of two
530           ;; sequences.
531           ;;
532           ;; For PIC, an out-of-range branch like:
533           ;;
534           ;;    bne     r1,r2,target
535           ;;    dslot
536           ;;
537           ;; becomes the equivalent of:
538           ;;
539           ;;    beq     r1,r2,1f
540           ;;    dslot
541           ;;    la      $at,target
542           ;;    jr      $at
543           ;;    nop
544           ;; 1:
545           ;;
546           ;; The non-PIC case is similar except that we use a direct
547           ;; jump instead of an la/jr pair.  Since the target of this
548           ;; jump is an absolute 28-bit bit address (the other bits
549           ;; coming from the address of the delay slot) this form cannot
550           ;; cross a 256MB boundary.  We could provide the option of
551           ;; using la/jr in this case too, but we do not do so at
552           ;; present.
553           ;;
554           ;; The value we specify here does not account for the delay slot
555           ;; instruction, whose length is added separately.  If the RTL
556           ;; pattern has no explicit delay slot, mips_adjust_insn_length
557           ;; will add the length of the implicit nop.  The range of
558           ;; [-0x20000, 0x1fffc] from the address of the delay slot
559           ;; therefore translates to a range of:
560           ;;
561           ;;    [-(0x20000 - sizeof (branch)), 0x1fffc - sizeof (slot)]
562           ;; == [-0x1fffc, 0x1fff8]
563           ;;
564           ;; from the shorten_branches reference address.
565           (and (eq_attr "type" "branch")
566                (not (match_test "TARGET_MIPS16")))
567           (cond [;; Any variant can handle the 17-bit range.
568                  (and (le (minus (match_dup 0) (pc)) (const_int 65532))
569                       (le (minus (pc) (match_dup 0)) (const_int 65534)))
570                    (const_int 4)
572                  ;; The 18-bit range is OK other than for microMIPS.
573                  (and (not (match_test "TARGET_MICROMIPS"))
574                       (and (le (minus (match_dup 0) (pc)) (const_int 131064))
575                            (le (minus (pc) (match_dup 0)) (const_int 131068))))
576                    (const_int 4)
578                  ;; The non-PIC case: branch, first delay slot, and J.
579                  (match_test "TARGET_ABSOLUTE_JUMPS")
580                    (const_int 12)]
582                  ;; Use MAX_PIC_BRANCH_LENGTH as a (gross) overestimate.
583                  ;; mips_adjust_insn_length substitutes the correct length.
584                  ;;
585                  ;; Note that we can't simply use (symbol_ref ...) here
586                  ;; because genattrtab needs to know the maximum length
587                  ;; of an insn.
588                  (const_int MAX_PIC_BRANCH_LENGTH))
590           ;; An unextended MIPS16 branch has a range of [-0x100, 0xfe]
591           ;; from the address of the following instruction, which leads
592           ;; to a range of:
593           ;;
594           ;;    [-(0x100 - sizeof (branch)), 0xfe]
595           ;; == [-0xfe, 0xfe]
596           ;;
597           ;; from the shorten_branches reference address.  Extended branches
598           ;; likewise have a range of [-0x10000, 0xfffe] from the address
599           ;; of the following instruction, which leads to a range of:
600           ;;
601           ;;    [-(0x10000 - sizeof (branch)), 0xfffe]
602           ;; == [-0xfffc, 0xfffe]
603           ;;
604           ;; from the reference address.
605           ;;
606           ;; When a branch is out of range, mips_reorg splits it into a form
607           ;; that uses in-range branches.  There are four basic sequences:
608           ;;
609           ;; (1) Absolute addressing with a readable text segment
610           ;;     (32-bit addresses):
611           ;;
612           ;;     b... foo               2 bytes
613           ;;     move $1,$2             2 bytes
614           ;;     lw $2,label            2 bytes
615           ;;     jr $2                  2 bytes
616           ;;     move $2,$1             2 bytes
617           ;;     .align 2               0 or 2 bytes
618           ;; label:
619           ;;     .word target           4 bytes
620           ;; foo:
621           ;;                            (16 bytes in the worst case)
622           ;;
623           ;; (2) Absolute addressing with a readable text segment
624           ;;     (64-bit addresses):
625           ;;
626           ;;     b... foo               2 bytes
627           ;;     move $1,$2             2 bytes
628           ;;     ld $2,label            2 bytes
629           ;;     jr $2                  2 bytes
630           ;;     move $2,$1             2 bytes
631           ;;     .align 3               0 to 6 bytes
632           ;; label:
633           ;;     .dword target          8 bytes
634           ;; foo:
635           ;;                            (24 bytes in the worst case)
636           ;;
637           ;; (3) Absolute addressing without a readable text segment
638           ;;     (which requires 32-bit addresses at present):
639           ;;
640           ;;     b... foo               2 bytes
641           ;;     move $1,$2             2 bytes
642           ;;     lui $2,%hi(target)     4 bytes
643           ;;     sll $2,8               2 bytes
644           ;;     sll $2,8               2 bytes
645           ;;     addiu $2,%lo(target)   4 bytes
646           ;;     jr $2                  2 bytes
647           ;;     move $2,$1             2 bytes
648           ;; foo:
649           ;;                            (20 bytes)
650           ;;
651           ;; (4) PIC addressing (which requires 32-bit addresses at present):
652           ;;
653           ;;     b... foo               2 bytes
654           ;;     move $1,$2             2 bytes
655           ;;     lw $2,cprestore        0, 2 or 4 bytes
656           ;;     lw $2,%got(target)($2) 4 bytes
657           ;;     addiu $2,%lo(target)   4 bytes
658           ;;     jr $2                  2 bytes
659           ;;     move $2,$1             2 bytes
660           ;; foo:
661           ;;                            (20 bytes in the worst case)
662           (and (eq_attr "type" "branch")
663                (match_test "TARGET_MIPS16"))
664           (cond [(and (le (minus (match_dup 0) (pc)) (const_int 254))
665                       (le (minus (pc) (match_dup 0)) (const_int 254)))
666                  (const_int 2)
667                  (and (le (minus (match_dup 0) (pc)) (const_int 65534))
668                       (le (minus (pc) (match_dup 0)) (const_int 65532)))
669                  (const_int 4)
670                  (and (match_test "TARGET_ABICALLS")
671                       (not (match_test "TARGET_ABSOLUTE_ABICALLS")))
672                  (const_int 20)
673                  (match_test "Pmode == SImode")
674                  (const_int 16)
675                  ] (const_int 24))]
676          (symbol_ref "get_attr_insn_count (insn) * BASE_INSN_LENGTH")))
678 ;; Attribute describing the processor.
679 (define_enum_attr "cpu" "processor"
680   (const (symbol_ref "mips_tune")))
682 ;; The type of hardware hazard associated with this instruction.
683 ;; DELAY means that the next instruction cannot read the result
684 ;; of this one.  HILO means that the next two instructions cannot
685 ;; write to HI or LO.
686 (define_attr "hazard" "none,delay,hilo"
687   (cond [(and (eq_attr "type" "load,fpload,fpidxload")
688               (match_test "ISA_HAS_LOAD_DELAY"))
689          (const_string "delay")
691          (and (eq_attr "type" "mfc,mtc")
692               (match_test "ISA_HAS_XFER_DELAY"))
693          (const_string "delay")
695          (and (eq_attr "type" "fcmp")
696               (match_test "ISA_HAS_FCMP_DELAY"))
697          (const_string "delay")
699          ;; The r4000 multiplication patterns include an mflo instruction.
700          (and (eq_attr "type" "imul")
701               (match_test "TARGET_FIX_R4000"))
702          (const_string "hilo")
704          (and (eq_attr "type" "mfhi,mflo")
705               (not (match_test "ISA_HAS_HILO_INTERLOCKS")))
706          (const_string "hilo")]
707         (const_string "none")))
709 ;; Can the instruction be put into a delay slot?
710 (define_attr "can_delay" "no,yes"
711   (if_then_else (and (eq_attr "type" "!branch,call,jump")
712                      (eq_attr "hazard" "none")
713                      (match_test "get_attr_insn_count (insn) == 1"))
714                 (const_string "yes")
715                 (const_string "no")))
717 ;; Attribute defining whether or not we can use the branch-likely
718 ;; instructions.
719 (define_attr "branch_likely" "no,yes"
720   (if_then_else (match_test "GENERATE_BRANCHLIKELY")
721                 (const_string "yes")
722                 (const_string "no")))
724 ;; True if an instruction might assign to hi or lo when reloaded.
725 ;; This is used by the TUNE_MACC_CHAINS code.
726 (define_attr "may_clobber_hilo" "no,yes"
727   (if_then_else (eq_attr "type" "imul,imul3,imadd,idiv,mthi,mtlo")
728                 (const_string "yes")
729                 (const_string "no")))
731 ;; Describe a user's asm statement.
732 (define_asm_attributes
733   [(set_attr "type" "multi")
734    (set_attr "can_delay" "no")])
736 ;; This mode iterator allows 32-bit and 64-bit GPR patterns to be generated
737 ;; from the same template.
738 (define_mode_iterator GPR [SI (DI "TARGET_64BIT")])
740 ;; A copy of GPR that can be used when a pattern has two independent
741 ;; modes.
742 (define_mode_iterator GPR2 [SI (DI "TARGET_64BIT")])
744 (define_mode_iterator MOVEP1 [SI SF])
745 (define_mode_iterator MOVEP2 [SI SF])
747 ;; This mode iterator allows :HILO to be used as the mode of the
748 ;; concatenated HI and LO registers.
749 (define_mode_iterator HILO [(DI "!TARGET_64BIT") (TI "TARGET_64BIT")])
751 ;; This mode iterator allows :P to be used for patterns that operate on
752 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
753 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
755 ;; This mode iterator allows :MOVECC to be used anywhere that a
756 ;; conditional-move-type condition is needed.
757 (define_mode_iterator MOVECC [SI (DI "TARGET_64BIT")
758                               (CC "TARGET_HARD_FLOAT
759                                    && !TARGET_LOONGSON_2EF
760                                    && !TARGET_MIPS5900")])
762 ;; 32-bit integer moves for which we provide move patterns.
763 (define_mode_iterator IMOVE32
764   [SI
765    (V2HI "TARGET_DSP")
766    (V4QI "TARGET_DSP")
767    (V2HQ "TARGET_DSP")
768    (V2UHQ "TARGET_DSP")
769    (V2HA "TARGET_DSP")
770    (V2UHA "TARGET_DSP")
771    (V4QQ "TARGET_DSP")
772    (V4UQQ "TARGET_DSP")])
774 ;; 64-bit modes for which we provide move patterns.
775 (define_mode_iterator MOVE64
776   [DI DF
777    (V2SF "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT")
778    (V2SI "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS")
779    (V4HI "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS")
780    (V8QI "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS")])
782 ;; 128-bit modes for which we provide move patterns on 64-bit targets.
783 (define_mode_iterator MOVE128 [TI TF])
785 ;; This mode iterator allows the QI and HI extension patterns to be
786 ;; defined from the same template.
787 (define_mode_iterator SHORT [QI HI])
789 ;; Likewise the 64-bit truncate-and-shift patterns.
790 (define_mode_iterator SUBDI [QI HI SI])
792 ;; This mode iterator allows :ANYF to be used wherever a scalar or vector
793 ;; floating-point mode is allowed.
794 (define_mode_iterator ANYF [(SF "TARGET_HARD_FLOAT")
795                             (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
796                             (V2SF "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT")])
798 ;; Like ANYF, but only applies to scalar modes.
799 (define_mode_iterator SCALARF [(SF "TARGET_HARD_FLOAT")
800                                (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")])
802 ;; A floating-point mode for which moves involving FPRs may need to be split.
803 (define_mode_iterator SPLITF
804   [(DF "!TARGET_64BIT && TARGET_DOUBLE_FLOAT")
805    (DI "!TARGET_64BIT && TARGET_DOUBLE_FLOAT")
806    (V2SF "!TARGET_64BIT && TARGET_PAIRED_SINGLE_FLOAT")
807    (V2SI "!TARGET_64BIT && TARGET_LOONGSON_VECTORS")
808    (V4HI "!TARGET_64BIT && TARGET_LOONGSON_VECTORS")
809    (V8QI "!TARGET_64BIT && TARGET_LOONGSON_VECTORS")
810    (TF "TARGET_64BIT && TARGET_FLOAT64")])
812 ;; In GPR templates, a string like "<d>subu" will expand to "subu" in the
813 ;; 32-bit version and "dsubu" in the 64-bit version.
814 (define_mode_attr d [(SI "") (DI "d")
815                      (QQ "") (HQ "") (SQ "") (DQ "d")
816                      (UQQ "") (UHQ "") (USQ "") (UDQ "d")
817                      (HA "") (SA "") (DA "d")
818                      (UHA "") (USA "") (UDA "d")])
820 ;; Same as d but upper-case.
821 (define_mode_attr D [(SI "") (DI "D")
822                      (QQ "") (HQ "") (SQ "") (DQ "D")
823                      (UQQ "") (UHQ "") (USQ "") (UDQ "D")
824                      (HA "") (SA "") (DA "D")
825                      (UHA "") (USA "") (UDA "D")])
827 ;; This attribute gives the length suffix for a load or store instruction.
828 ;; The same suffixes work for zero and sign extensions.
829 (define_mode_attr size [(QI "b") (HI "h") (SI "w") (DI "d")])
830 (define_mode_attr SIZE [(QI "B") (HI "H") (SI "W") (DI "D")])
832 ;; This attributes gives the mode mask of a SHORT.
833 (define_mode_attr mask [(QI "0x00ff") (HI "0xffff")])
835 ;; Mode attributes for GPR loads.
836 (define_mode_attr load [(SI "lw") (DI "ld")])
837 ;; Instruction names for stores.
838 (define_mode_attr store [(QI "sb") (HI "sh") (SI "sw") (DI "sd")])
840 ;; Similarly for MIPS IV indexed FPR loads and stores.
841 (define_mode_attr loadx [(SF "lwxc1") (DF "ldxc1") (V2SF "ldxc1")])
842 (define_mode_attr storex [(SF "swxc1") (DF "sdxc1") (V2SF "sdxc1")])
844 ;; The unextended ranges of the MIPS16 addiu and daddiu instructions
845 ;; are different.  Some forms of unextended addiu have an 8-bit immediate
846 ;; field but the equivalent daddiu has only a 5-bit field.
847 (define_mode_attr si8_di5 [(SI "8") (DI "5")])
849 ;; This attribute gives the best constraint to use for registers of
850 ;; a given mode.
851 (define_mode_attr reg [(SI "d") (DI "d") (CC "z")])
853 ;; This attribute gives the format suffix for floating-point operations.
854 (define_mode_attr fmt [(SF "s") (DF "d") (V2SF "ps")])
856 ;; This attribute gives the upper-case mode name for one unit of a
857 ;; floating-point mode.
858 (define_mode_attr UNITMODE [(SF "SF") (DF "DF") (V2SF "SF")])
860 ;; This attribute gives the integer mode that has the same size as a
861 ;; fixed-point mode.
862 (define_mode_attr IMODE [(QQ "QI") (HQ "HI") (SQ "SI") (DQ "DI")
863                          (UQQ "QI") (UHQ "HI") (USQ "SI") (UDQ "DI")
864                          (HA "HI") (SA "SI") (DA "DI")
865                          (UHA "HI") (USA "SI") (UDA "DI")
866                          (V4UQQ "SI") (V2UHQ "SI") (V2UHA "SI")
867                          (V2HQ "SI") (V2HA "SI")])
869 ;; This attribute gives the integer mode that has half the size of
870 ;; the controlling mode.
871 (define_mode_attr HALFMODE [(DF "SI") (DI "SI") (V2SF "SI")
872                             (V2SI "SI") (V4HI "SI") (V8QI "SI")
873                             (TF "DI")])
875 ;; This attribute works around the early SB-1 rev2 core "F2" erratum:
877 ;; In certain cases, div.s and div.ps may have a rounding error
878 ;; and/or wrong inexact flag.
880 ;; Therefore, we only allow div.s if not working around SB-1 rev2
881 ;; errata or if a slight loss of precision is OK.
882 (define_mode_attr divide_condition
883   [DF (SF "!TARGET_FIX_SB1 || flag_unsafe_math_optimizations")
884    (V2SF "TARGET_SB1 && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)")])
886 ;; This attribute gives the conditions under which SQRT.fmt instructions
887 ;; can be used.
888 (define_mode_attr sqrt_condition
889   [(SF "!ISA_MIPS1") (DF "!ISA_MIPS1") (V2SF "TARGET_SB1")])
891 ;; This code iterator allows signed and unsigned widening multiplications
892 ;; to use the same template.
893 (define_code_iterator any_extend [sign_extend zero_extend])
895 ;; This code iterator allows the two right shift instructions to be
896 ;; generated from the same template.
897 (define_code_iterator any_shiftrt [ashiftrt lshiftrt])
899 ;; This code iterator allows the three shift instructions to be generated
900 ;; from the same template.
901 (define_code_iterator any_shift [ashift ashiftrt lshiftrt])
903 ;; This code iterator allows unsigned and signed division to be generated
904 ;; from the same template.
905 (define_code_iterator any_div [div udiv])
907 ;; This code iterator allows unsigned and signed modulus to be generated
908 ;; from the same template.
909 (define_code_iterator any_mod [mod umod])
911 ;; This code iterator allows all native floating-point comparisons to be
912 ;; generated from the same template.
913 (define_code_iterator fcond [unordered uneq unlt unle eq lt le])
915 ;; This code iterator is used for comparisons that can be implemented
916 ;; by swapping the operands.
917 (define_code_iterator swapped_fcond [ge gt unge ungt])
919 ;; Equality operators.
920 (define_code_iterator equality_op [eq ne])
922 ;; These code iterators allow the signed and unsigned scc operations to use
923 ;; the same template.
924 (define_code_iterator any_gt [gt gtu])
925 (define_code_iterator any_ge [ge geu])
926 (define_code_iterator any_lt [lt ltu])
927 (define_code_iterator any_le [le leu])
929 (define_code_iterator any_return [return simple_return])
931 ;; <u> expands to an empty string when doing a signed operation and
932 ;; "u" when doing an unsigned operation.
933 (define_code_attr u [(sign_extend "") (zero_extend "u")
934                      (div "") (udiv "u")
935                      (mod "") (umod "u")
936                      (gt "") (gtu "u")
937                      (ge "") (geu "u")
938                      (lt "") (ltu "u")
939                      (le "") (leu "u")])
941 ;; <U> is like <u> except uppercase.
942 (define_code_attr U [(sign_extend "") (zero_extend "U")])
944 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
945 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
947 ;; <optab> expands to the name of the optab for a particular code.
948 (define_code_attr optab [(ashift "ashl")
949                          (ashiftrt "ashr")
950                          (lshiftrt "lshr")
951                          (ior "ior")
952                          (xor "xor")
953                          (and "and")
954                          (plus "add")
955                          (minus "sub")
956                          (return "return")
957                          (simple_return "simple_return")])
959 ;; <insn> expands to the name of the insn that implements a particular code.
960 (define_code_attr insn [(ashift "sll")
961                         (ashiftrt "sra")
962                         (lshiftrt "srl")
963                         (ior "or")
964                         (xor "xor")
965                         (and "and")
966                         (plus "addu")
967                         (minus "subu")])
969 ;; <immediate_insn> expands to the name of the insn that implements
970 ;; a particular code to operate on immediate values.
971 (define_code_attr immediate_insn [(ior "ori")
972                                   (xor "xori")
973                                   (and "andi")])
975 (define_code_attr shift_compression [(ashift "micromips")
976                                      (lshiftrt "micromips")
977                                      (ashiftrt "none")])
979 ;; <fcond> is the c.cond.fmt condition associated with a particular code.
980 (define_code_attr fcond [(unordered "un")
981                          (uneq "ueq")
982                          (unlt "ult")
983                          (unle "ule")
984                          (eq "eq")
985                          (lt "lt")
986                          (le "le")])
988 ;; Similar, but for swapped conditions.
989 (define_code_attr swapped_fcond [(ge "le")
990                                  (gt "lt")
991                                  (unge "ule")
992                                  (ungt "ult")])
994 ;; The value of the bit when the branch is taken for branch_bit patterns.
995 ;; Comparison is always against zero so this depends on the operator.
996 (define_code_attr bbv [(eq "0") (ne "1")])
998 ;; This is the inverse value of bbv.
999 (define_code_attr bbinv [(eq "1") (ne "0")])
1001 ;; .........................
1003 ;;      Branch, call and jump delay slots
1005 ;; .........................
1007 (define_delay (and (eq_attr "type" "branch")
1008                    (not (match_test "TARGET_MIPS16"))
1009                    (eq_attr "branch_likely" "yes"))
1010   [(eq_attr "can_delay" "yes")
1011    (nil)
1012    (eq_attr "can_delay" "yes")])
1014 ;; Branches that don't have likely variants do not annul on false.
1015 (define_delay (and (eq_attr "type" "branch")
1016                    (not (match_test "TARGET_MIPS16"))
1017                    (eq_attr "branch_likely" "no"))
1018   [(eq_attr "can_delay" "yes")
1019    (nil)
1020    (nil)])
1022 (define_delay (eq_attr "type" "jump")
1023   [(eq_attr "can_delay" "yes")
1024    (nil)
1025    (nil)])
1027 (define_delay (and (eq_attr "type" "call")
1028                    (eq_attr "jal_macro" "no"))
1029   [(eq_attr "can_delay" "yes")
1030    (nil)
1031    (nil)])
1033 ;; Pipeline descriptions.
1035 ;; generic.md provides a fallback for processors without a specific
1036 ;; pipeline description.  It is derived from the old define_function_unit
1037 ;; version and uses the "alu" and "imuldiv" units declared below.
1039 ;; Some of the processor-specific files are also derived from old
1040 ;; define_function_unit descriptions and simply override the parts of
1041 ;; generic.md that don't apply.  The other processor-specific files
1042 ;; are self-contained.
1043 (define_automaton "alu,imuldiv")
1045 (define_cpu_unit "alu" "alu")
1046 (define_cpu_unit "imuldiv" "imuldiv")
1048 ;; Ghost instructions produce no real code and introduce no hazards.
1049 ;; They exist purely to express an effect on dataflow.
1050 (define_insn_reservation "ghost" 0
1051   (eq_attr "type" "ghost")
1052   "nothing")
1054 (include "p5600.md")
1055 (include "4k.md")
1056 (include "5k.md")
1057 (include "20kc.md")
1058 (include "24k.md")
1059 (include "74k.md")
1060 (include "3000.md")
1061 (include "4000.md")
1062 (include "4100.md")
1063 (include "4130.md")
1064 (include "4300.md")
1065 (include "4600.md")
1066 (include "5000.md")
1067 (include "5400.md")
1068 (include "5500.md")
1069 (include "6000.md")
1070 (include "7000.md")
1071 (include "9000.md")
1072 (include "10000.md")
1073 (include "loongson2ef.md")
1074 (include "loongson3a.md")
1075 (include "octeon.md")
1076 (include "sb1.md")
1077 (include "sr71k.md")
1078 (include "xlr.md")
1079 (include "xlp.md")
1080 (include "generic.md")
1083 ;;  ....................
1085 ;;      CONDITIONAL TRAPS
1087 ;;  ....................
1090 (define_insn "trap"
1091   [(trap_if (const_int 1) (const_int 0))]
1092   ""
1094   if (ISA_HAS_COND_TRAP)
1095     return "teq\t$0,$0";
1096   else if (TARGET_MIPS16)
1097     return "break 0";
1098   else
1099     return "break";
1101   [(set_attr "type" "trap")])
1103 (define_expand "ctrap<mode>4"
1104   [(trap_if (match_operator 0 "comparison_operator"
1105                             [(match_operand:GPR 1 "reg_or_0_operand")
1106                              (match_operand:GPR 2 "arith_operand")])
1107             (match_operand 3 "const_0_operand"))]
1108   "ISA_HAS_COND_TRAP"
1110   mips_expand_conditional_trap (operands[0]);
1111   DONE;
1114 (define_insn "*conditional_trap<mode>"
1115   [(trap_if (match_operator:GPR 0 "trap_comparison_operator"
1116                                 [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
1117                                  (match_operand:GPR 2 "arith_operand" "dI")])
1118             (const_int 0))]
1119   "ISA_HAS_COND_TRAP"
1120   "t%C0\t%z1,%2"
1121   [(set_attr "type" "trap")])
1124 ;;  ....................
1126 ;;      ADDITION
1128 ;;  ....................
1131 (define_insn "add<mode>3"
1132   [(set (match_operand:ANYF 0 "register_operand" "=f")
1133         (plus:ANYF (match_operand:ANYF 1 "register_operand" "f")
1134                    (match_operand:ANYF 2 "register_operand" "f")))]
1135   ""
1136   "add.<fmt>\t%0,%1,%2"
1137   [(set_attr "type" "fadd")
1138    (set_attr "mode" "<UNITMODE>")])
1140 (define_expand "add<mode>3"
1141   [(set (match_operand:GPR 0 "register_operand")
1142         (plus:GPR (match_operand:GPR 1 "register_operand")
1143                   (match_operand:GPR 2 "arith_operand")))]
1144   "")
1146 (define_insn "*add<mode>3"
1147   [(set (match_operand:GPR 0 "register_operand" "=!u,d,!u,!u,!ks,!d,d")
1148         (plus:GPR (match_operand:GPR 1 "register_operand" "!u,d,!u,!ks,!ks,0,d")
1149                   (match_operand:GPR 2 "arith_operand" "!u,d,Uead,Uuw6,Uesp,Usb4,Q")))]
1150   "!TARGET_MIPS16"
1152   if (which_alternative == 0 
1153       || which_alternative == 1)
1154     return "<d>addu\t%0,%1,%2";
1155   else
1156     return "<d>addiu\t%0,%1,%2";
1158   [(set_attr "alu_type" "add")
1159    (set_attr "compression" "micromips,*,micromips,micromips,micromips,micromips,*")
1160    (set_attr "mode" "<MODE>")])
1162 (define_insn "*add<mode>3_mips16"
1163   [(set (match_operand:GPR 0 "register_operand" "=ks,ks,d,d,d,d,d,d,d")
1164         (plus:GPR (match_operand:GPR 1 "register_operand" "ks,ks,ks,ks,0,0,d,d,d")
1165                   (match_operand:GPR 2 "arith_operand" "Usd8,Q,Uuw<si8_di5>,Q,Usb<si8_di5>,Q,Usb4,O,d")))]
1166   "TARGET_MIPS16"
1167   "@
1168     <d>addiu\t%0,%2
1169     <d>addiu\t%0,%2
1170     <d>addiu\t%0,%1,%2
1171     <d>addiu\t%0,%1,%2
1172     <d>addiu\t%0,%2
1173     <d>addiu\t%0,%2
1174     <d>addiu\t%0,%1,%2
1175     <d>addiu\t%0,%1,%2
1176     <d>addu\t%0,%1,%2"
1177   [(set_attr "alu_type" "add")
1178    (set_attr "mode" "<MODE>")
1179    (set_attr "extended_mips16" "no,yes,no,yes,no,yes,no,yes,no")])
1181 ;; On the mips16, we can sometimes split an add of a constant which is
1182 ;; a 4 byte instruction into two adds which are both 2 byte
1183 ;; instructions.  There are two cases: one where we are adding a
1184 ;; constant plus a register to another register, and one where we are
1185 ;; simply adding a constant to a register.
1187 (define_split
1188   [(set (match_operand:SI 0 "d_operand")
1189         (plus:SI (match_dup 0)
1190                  (match_operand:SI 1 "const_int_operand")))]
1191   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
1192    && ((INTVAL (operands[1]) > 0x7f
1193         && INTVAL (operands[1]) <= 0x7f + 0x7f)
1194        || (INTVAL (operands[1]) < - 0x80
1195            && INTVAL (operands[1]) >= - 0x80 - 0x80))"
1196   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
1197    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
1199   HOST_WIDE_INT val = INTVAL (operands[1]);
1201   if (val >= 0)
1202     {
1203       operands[1] = GEN_INT (0x7f);
1204       operands[2] = GEN_INT (val - 0x7f);
1205     }
1206   else
1207     {
1208       operands[1] = GEN_INT (- 0x80);
1209       operands[2] = GEN_INT (val + 0x80);
1210     }
1213 (define_split
1214   [(set (match_operand:SI 0 "d_operand")
1215         (plus:SI (match_operand:SI 1 "d_operand")
1216                  (match_operand:SI 2 "const_int_operand")))]
1217   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
1218    && REGNO (operands[0]) != REGNO (operands[1])
1219    && ((INTVAL (operands[2]) > 0x7
1220         && INTVAL (operands[2]) <= 0x7 + 0x7f)
1221        || (INTVAL (operands[2]) < - 0x8
1222            && INTVAL (operands[2]) >= - 0x8 - 0x80))"
1223   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
1224    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
1226   HOST_WIDE_INT val = INTVAL (operands[2]);
1228   if (val >= 0)
1229     {
1230       operands[2] = GEN_INT (0x7);
1231       operands[3] = GEN_INT (val - 0x7);
1232     }
1233   else
1234     {
1235       operands[2] = GEN_INT (- 0x8);
1236       operands[3] = GEN_INT (val + 0x8);
1237     }
1240 (define_split
1241   [(set (match_operand:DI 0 "d_operand")
1242         (plus:DI (match_dup 0)
1243                  (match_operand:DI 1 "const_int_operand")))]
1244   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1245    && ((INTVAL (operands[1]) > 0xf
1246         && INTVAL (operands[1]) <= 0xf + 0xf)
1247        || (INTVAL (operands[1]) < - 0x10
1248            && INTVAL (operands[1]) >= - 0x10 - 0x10))"
1249   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
1250    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
1252   HOST_WIDE_INT val = INTVAL (operands[1]);
1254   if (val >= 0)
1255     {
1256       operands[1] = GEN_INT (0xf);
1257       operands[2] = GEN_INT (val - 0xf);
1258     }
1259   else
1260     {
1261       operands[1] = GEN_INT (- 0x10);
1262       operands[2] = GEN_INT (val + 0x10);
1263     }
1266 (define_split
1267   [(set (match_operand:DI 0 "d_operand")
1268         (plus:DI (match_operand:DI 1 "d_operand")
1269                  (match_operand:DI 2 "const_int_operand")))]
1270   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1271    && REGNO (operands[0]) != REGNO (operands[1])
1272    && ((INTVAL (operands[2]) > 0x7
1273         && INTVAL (operands[2]) <= 0x7 + 0xf)
1274        || (INTVAL (operands[2]) < - 0x8
1275            && INTVAL (operands[2]) >= - 0x8 - 0x10))"
1276   [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
1277    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
1279   HOST_WIDE_INT val = INTVAL (operands[2]);
1281   if (val >= 0)
1282     {
1283       operands[2] = GEN_INT (0x7);
1284       operands[3] = GEN_INT (val - 0x7);
1285     }
1286   else
1287     {
1288       operands[2] = GEN_INT (- 0x8);
1289       operands[3] = GEN_INT (val + 0x8);
1290     }
1293 (define_insn "*addsi3_extended"
1294   [(set (match_operand:DI 0 "register_operand" "=d,d")
1295         (sign_extend:DI
1296              (plus:SI (match_operand:SI 1 "register_operand" "d,d")
1297                       (match_operand:SI 2 "arith_operand" "d,Q"))))]
1298   "TARGET_64BIT && !TARGET_MIPS16"
1299   "@
1300     addu\t%0,%1,%2
1301     addiu\t%0,%1,%2"
1302   [(set_attr "alu_type" "add")
1303    (set_attr "mode" "SI")])
1305 ;; Split this insn so that the addiu splitters can have a crack at it.
1306 ;; Use a conservative length estimate until the split.
1307 (define_insn_and_split "*addsi3_extended_mips16"
1308   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1309         (sign_extend:DI
1310              (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1311                       (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
1312   "TARGET_64BIT && TARGET_MIPS16"
1313   "#"
1314   "&& reload_completed"
1315   [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))]
1316   { operands[3] = gen_lowpart (SImode, operands[0]); }
1317   [(set_attr "alu_type" "add")
1318    (set_attr "mode" "SI")
1319    (set_attr "extended_mips16" "yes")])
1321 ;; Combiner patterns for unsigned byte-add.
1323 (define_insn "*baddu_si_eb"
1324   [(set (match_operand:SI 0 "register_operand" "=d")
1325         (zero_extend:SI
1326          (subreg:QI
1327           (plus:SI (match_operand:SI 1 "register_operand" "d")
1328                    (match_operand:SI 2 "register_operand" "d")) 3)))]
1329   "ISA_HAS_BADDU && BYTES_BIG_ENDIAN"
1330   "baddu\\t%0,%1,%2"
1331   [(set_attr "alu_type" "add")])
1333 (define_insn "*baddu_si_el"
1334   [(set (match_operand:SI 0 "register_operand" "=d")
1335         (zero_extend:SI
1336          (subreg:QI
1337           (plus:SI (match_operand:SI 1 "register_operand" "d")
1338                    (match_operand:SI 2 "register_operand" "d")) 0)))]
1339   "ISA_HAS_BADDU && !BYTES_BIG_ENDIAN"
1340   "baddu\\t%0,%1,%2"
1341   [(set_attr "alu_type" "add")])
1343 (define_insn "*baddu_di<mode>"
1344   [(set (match_operand:GPR 0 "register_operand" "=d")
1345         (zero_extend:GPR
1346          (truncate:QI
1347           (plus:DI (match_operand:DI 1 "register_operand" "d")
1348                    (match_operand:DI 2 "register_operand" "d")))))]
1349   "ISA_HAS_BADDU && TARGET_64BIT"
1350   "baddu\\t%0,%1,%2"
1351   [(set_attr "alu_type" "add")])
1354 ;;  ....................
1356 ;;      SUBTRACTION
1358 ;;  ....................
1361 (define_insn "sub<mode>3"
1362   [(set (match_operand:ANYF 0 "register_operand" "=f")
1363         (minus:ANYF (match_operand:ANYF 1 "register_operand" "f")
1364                     (match_operand:ANYF 2 "register_operand" "f")))]
1365   ""
1366   "sub.<fmt>\t%0,%1,%2"
1367   [(set_attr "type" "fadd")
1368    (set_attr "mode" "<UNITMODE>")])
1370 (define_insn "sub<mode>3"
1371   [(set (match_operand:GPR 0 "register_operand" "=!u,d")
1372         (minus:GPR (match_operand:GPR 1 "register_operand" "!u,d")
1373                    (match_operand:GPR 2 "register_operand" "!u,d")))]
1374   ""
1375   "<d>subu\t%0,%1,%2"
1376   [(set_attr "alu_type" "sub")
1377    (set_attr "compression" "micromips,*")
1378    (set_attr "mode" "<MODE>")])
1380 (define_insn "*subsi3_extended"
1381   [(set (match_operand:DI 0 "register_operand" "=d")
1382         (sign_extend:DI
1383             (minus:SI (match_operand:SI 1 "register_operand" "d")
1384                       (match_operand:SI 2 "register_operand" "d"))))]
1385   "TARGET_64BIT"
1386   "subu\t%0,%1,%2"
1387   [(set_attr "alu_type" "sub")
1388    (set_attr "mode" "DI")])
1391 ;;  ....................
1393 ;;      MULTIPLICATION
1395 ;;  ....................
1398 (define_expand "mul<mode>3"
1399   [(set (match_operand:SCALARF 0 "register_operand")
1400         (mult:SCALARF (match_operand:SCALARF 1 "register_operand")
1401                       (match_operand:SCALARF 2 "register_operand")))]
1402   ""
1403   "")
1405 (define_insn "*mul<mode>3"
1406   [(set (match_operand:SCALARF 0 "register_operand" "=f")
1407         (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
1408                       (match_operand:SCALARF 2 "register_operand" "f")))]
1409   "!TARGET_4300_MUL_FIX"
1410   "mul.<fmt>\t%0,%1,%2"
1411   [(set_attr "type" "fmul")
1412    (set_attr "mode" "<MODE>")])
1414 ;; Early VR4300 silicon has a CPU bug where multiplies with certain
1415 ;; operands may corrupt immediately following multiplies. This is a
1416 ;; simple fix to insert NOPs.
1418 (define_insn "*mul<mode>3_r4300"
1419   [(set (match_operand:SCALARF 0 "register_operand" "=f")
1420         (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
1421                       (match_operand:SCALARF 2 "register_operand" "f")))]
1422   "TARGET_4300_MUL_FIX"
1423   "mul.<fmt>\t%0,%1,%2\;nop"
1424   [(set_attr "type" "fmul")
1425    (set_attr "mode" "<MODE>")
1426    (set_attr "insn_count" "2")])
1428 (define_insn "mulv2sf3"
1429   [(set (match_operand:V2SF 0 "register_operand" "=f")
1430         (mult:V2SF (match_operand:V2SF 1 "register_operand" "f")
1431                    (match_operand:V2SF 2 "register_operand" "f")))]
1432   "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
1433   "mul.ps\t%0,%1,%2"
1434   [(set_attr "type" "fmul")
1435    (set_attr "mode" "SF")])
1437 ;; The original R4000 has a cpu bug.  If a double-word or a variable
1438 ;; shift executes while an integer multiplication is in progress, the
1439 ;; shift may give an incorrect result.  Avoid this by keeping the mflo
1440 ;; with the mult on the R4000.
1442 ;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
1443 ;; (also valid for MIPS R4000MC processors):
1445 ;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
1446 ;;      this errata description.
1447 ;;      The following code sequence causes the R4000 to incorrectly
1448 ;;      execute the Double Shift Right Arithmetic 32 (dsra32)
1449 ;;      instruction.  If the dsra32 instruction is executed during an
1450 ;;      integer multiply, the dsra32 will only shift by the amount in
1451 ;;      specified in the instruction rather than the amount plus 32
1452 ;;      bits.
1453 ;;      instruction 1:          mult    rs,rt           integer multiply
1454 ;;      instruction 2-12:       dsra32  rd,rt,rs        doubleword shift
1455 ;;                                                      right arithmetic + 32
1456 ;;      Workaround: A dsra32 instruction placed after an integer
1457 ;;      multiply should not be one of the 11 instructions after the
1458 ;;      multiply instruction."
1460 ;; and:
1462 ;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
1463 ;;      the following description.
1464 ;;      All extended shifts (shift by n+32) and variable shifts (32 and
1465 ;;      64-bit versions) may produce incorrect results under the
1466 ;;      following conditions:
1467 ;;      1) An integer multiply is currently executing
1468 ;;      2) These types of shift instructions are executed immediately
1469 ;;         following an integer divide instruction.
1470 ;;      Workaround:
1471 ;;      1) Make sure no integer multiply is running wihen these
1472 ;;         instruction are executed.  If this cannot be predicted at
1473 ;;         compile time, then insert a "mfhi" to R0 instruction
1474 ;;         immediately after the integer multiply instruction.  This
1475 ;;         will cause the integer multiply to complete before the shift
1476 ;;         is executed.
1477 ;;      2) Separate integer divide and these two classes of shift
1478 ;;         instructions by another instruction or a noop."
1480 ;; These processors have PRId values of 0x00004220 and 0x00004300,
1481 ;; respectively.
1483 (define_expand "mul<mode>3"
1484   [(set (match_operand:GPR 0 "register_operand")
1485         (mult:GPR (match_operand:GPR 1 "register_operand")
1486                   (match_operand:GPR 2 "register_operand")))]
1487   "ISA_HAS_<D>MULT"
1489   rtx lo;
1491   if (TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A)
1492     emit_insn (gen_mul<mode>3_mul3_loongson (operands[0], operands[1],
1493                                              operands[2]));
1494   else if (ISA_HAS_<D>MUL3)
1495     emit_insn (gen_mul<mode>3_mul3 (operands[0], operands[1], operands[2]));
1496   else if (TARGET_MIPS16)
1497     {
1498       lo = gen_rtx_REG (<MODE>mode, LO_REGNUM);
1499       emit_insn (gen_mul<mode>3_internal (lo, operands[1], operands[2]));
1500       emit_move_insn (operands[0], lo);
1501     }
1502   else if (TARGET_FIX_R4000)
1503     emit_insn (gen_mul<mode>3_r4000 (operands[0], operands[1], operands[2]));
1504   else
1505     emit_insn
1506       (gen_mul<mode>3_internal (operands[0], operands[1], operands[2]));
1507   DONE;
1510 (define_insn "mul<mode>3_mul3_loongson"
1511   [(set (match_operand:GPR 0 "register_operand" "=d")
1512         (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1513                   (match_operand:GPR 2 "register_operand" "d")))]
1514   "TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A"
1516   if (TARGET_LOONGSON_2EF)
1517     return "<d>multu.g\t%0,%1,%2";
1518   else
1519     return "gs<d>multu\t%0,%1,%2";
1521   [(set_attr "type" "imul3nc")
1522    (set_attr "mode" "<MODE>")])
1524 (define_insn "mul<mode>3_mul3"
1525   [(set (match_operand:GPR 0 "register_operand" "=d,l")
1526         (mult:GPR (match_operand:GPR 1 "register_operand" "d,d")
1527                   (match_operand:GPR 2 "register_operand" "d,d")))
1528    (clobber (match_scratch:GPR 3 "=l,X"))]
1529   "ISA_HAS_<D>MUL3"
1531   if (which_alternative == 1)
1532     return "<d>mult\t%1,%2";
1533   if (<MODE>mode == SImode && (TARGET_MIPS3900 || TARGET_MIPS5900))
1534     return "mult\t%0,%1,%2";
1535   return "<d>mul\t%0,%1,%2";
1537   [(set_attr "type" "imul3,imul")
1538    (set_attr "mode" "<MODE>")])
1540 ;; If a register gets allocated to LO, and we spill to memory, the reload
1541 ;; will include a move from LO to a GPR.  Merge it into the multiplication
1542 ;; if it can set the GPR directly.
1544 ;; Operand 0: LO
1545 ;; Operand 1: GPR (1st multiplication operand)
1546 ;; Operand 2: GPR (2nd multiplication operand)
1547 ;; Operand 3: GPR (destination)
1548 (define_peephole2
1549   [(parallel
1550        [(set (match_operand:SI 0 "lo_operand")
1551              (mult:SI (match_operand:SI 1 "d_operand")
1552                       (match_operand:SI 2 "d_operand")))
1553         (clobber (scratch:SI))])
1554    (set (match_operand:SI 3 "d_operand")
1555         (match_dup 0))]
1556   "ISA_HAS_MUL3 && peep2_reg_dead_p (2, operands[0])"
1557   [(parallel
1558        [(set (match_dup 3)
1559              (mult:SI (match_dup 1)
1560                       (match_dup 2)))
1561         (clobber (match_dup 0))])])
1563 (define_insn "mul<mode>3_internal"
1564   [(set (match_operand:GPR 0 "muldiv_target_operand" "=l")
1565         (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1566                   (match_operand:GPR 2 "register_operand" "d")))]
1567   "ISA_HAS_<D>MULT && !TARGET_FIX_R4000"
1568   "<d>mult\t%1,%2"
1569   [(set_attr "type" "imul")
1570    (set_attr "mode" "<MODE>")])
1572 (define_insn "mul<mode>3_r4000"
1573   [(set (match_operand:GPR 0 "register_operand" "=d")
1574         (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1575                   (match_operand:GPR 2 "register_operand" "d")))
1576    (clobber (match_scratch:GPR 3 "=l"))]
1577   "ISA_HAS_<D>MULT && TARGET_FIX_R4000"
1578   "<d>mult\t%1,%2\;mflo\t%0"
1579   [(set_attr "type" "imul")
1580    (set_attr "mode" "<MODE>")
1581    (set_attr "insn_count" "2")])
1583 ;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
1584 ;; of "mult; mflo".  They have the same latency, but the first form gives
1585 ;; us an extra cycle to compute the operands.
1587 ;; Operand 0: LO
1588 ;; Operand 1: GPR (1st multiplication operand)
1589 ;; Operand 2: GPR (2nd multiplication operand)
1590 ;; Operand 3: GPR (destination)
1591 (define_peephole2
1592   [(set (match_operand:SI 0 "lo_operand")
1593         (mult:SI (match_operand:SI 1 "d_operand")
1594                  (match_operand:SI 2 "d_operand")))
1595    (set (match_operand:SI 3 "d_operand")
1596         (match_dup 0))]
1597   "ISA_HAS_MACC && !ISA_HAS_MUL3"
1598   [(set (match_dup 0)
1599         (const_int 0))
1600    (parallel
1601        [(set (match_dup 0)
1602              (plus:SI (mult:SI (match_dup 1)
1603                                (match_dup 2))
1604                       (match_dup 0)))
1605         (set (match_dup 3)
1606              (plus:SI (mult:SI (match_dup 1)
1607                                (match_dup 2))
1608                       (match_dup 0)))])])
1610 ;; Multiply-accumulate patterns
1612 ;; This pattern is first matched by combine, which tries to use the
1613 ;; pattern wherever it can.  We don't know until later whether it
1614 ;; is actually profitable to use MADD over a "MUL; ADDIU" sequence,
1615 ;; so we need to keep both options open.
1617 ;; The second alternative has a "?" marker because it is generally
1618 ;; one instruction more costly than the first alternative.  This "?"
1619 ;; marker is enough to convey the relative costs to the register
1620 ;; allocator.
1622 ;; However, reload counts reloads of operands 4 and 5 in the same way as
1623 ;; reloads of the other operands, even though operands 4 and 5 need no
1624 ;; copy instructions.  Reload therefore thinks that the second alternative
1625 ;; is two reloads more costly than the first.  We add "*?*?" to the first
1626 ;; alternative as a counterweight.
1628 ;; LRA simulates reload but the cost of reloading scratches is lower
1629 ;; than of the classic reload. For the time being, removing the counterweight
1630 ;; for LRA is more profitable.
1631 (define_insn "*mul_acc_si"
1632   [(set (match_operand:SI 0 "register_operand" "=l*?*?,l,d?")
1633         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1634                           (match_operand:SI 2 "register_operand" "d,d,d"))
1635                  (match_operand:SI 3 "register_operand" "0,0,d")))
1636    (clobber (match_scratch:SI 4 "=X,X,l"))
1637    (clobber (match_scratch:SI 5 "=X,X,&d"))]
1638   "GENERATE_MADD_MSUB && !TARGET_MIPS16"
1639   "@
1640     madd\t%1,%2
1641     madd\t%1,%2
1642     #"
1643   [(set_attr "type"     "imadd")
1644    (set_attr "accum_in" "3")
1645    (set_attr "mode"     "SI")
1646    (set_attr "insn_count" "1,1,2")
1647    (set (attr "enabled")
1648         (cond [(and (eq_attr "alternative" "0")
1649                     (match_test "!mips_lra_flag"))
1650                   (const_string "yes")
1651                (and (eq_attr "alternative" "1")
1652                     (match_test "mips_lra_flag"))
1653                   (const_string "yes")
1654                (eq_attr "alternative" "2")
1655                   (const_string "yes")]
1656               (const_string "no")))])
1658 ;; The same idea applies here.  The middle alternative needs one less
1659 ;; clobber than the final alternative, so we add "*?" as a counterweight.
1660 (define_insn "*mul_acc_si_r3900"
1661   [(set (match_operand:SI 0 "register_operand" "=l*?*?,l,d*?,d?")
1662         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d,d")
1663                           (match_operand:SI 2 "register_operand" "d,d,d,d"))
1664                  (match_operand:SI 3 "register_operand" "0,0,l,d")))
1665    (clobber (match_scratch:SI 4 "=X,X,3,l"))
1666    (clobber (match_scratch:SI 5 "=X,X,X,&d"))]
1667   "TARGET_MIPS3900 && !TARGET_MIPS16"
1668   "@
1669     madd\t%1,%2
1670     madd\t%1,%2
1671     madd\t%0,%1,%2
1672     #"
1673   [(set_attr "type"     "imadd")
1674    (set_attr "accum_in" "3")
1675    (set_attr "mode"     "SI")
1676    (set_attr "insn_count" "1,1,1,2")
1677    (set (attr "enabled")
1678         (cond [(and (eq_attr "alternative" "0")
1679                     (match_test "!mips_lra_flag"))
1680                   (const_string "yes")
1681                (and (eq_attr "alternative" "1")
1682                     (match_test "mips_lra_flag"))
1683                   (const_string "yes")
1684                (eq_attr "alternative" "2,3")
1685                   (const_string "yes")]
1686               (const_string "no")))])
1688 ;; Split *mul_acc_si if both the source and destination accumulator
1689 ;; values are GPRs.
1690 (define_split
1691   [(set (match_operand:SI 0 "d_operand")
1692         (plus:SI (mult:SI (match_operand:SI 1 "d_operand")
1693                           (match_operand:SI 2 "d_operand"))
1694                  (match_operand:SI 3 "d_operand")))
1695    (clobber (match_operand:SI 4 "lo_operand"))
1696    (clobber (match_operand:SI 5 "d_operand"))]
1697   "reload_completed"
1698   [(parallel [(set (match_dup 5)
1699                    (mult:SI (match_dup 1) (match_dup 2)))
1700               (clobber (match_dup 4))])
1701    (set (match_dup 0) (plus:SI (match_dup 5) (match_dup 3)))]
1702   "")
1704 (define_insn "*macc"
1705   [(set (match_operand:SI 0 "register_operand" "=l,d")
1706         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1707                           (match_operand:SI 2 "register_operand" "d,d"))
1708                  (match_operand:SI 3 "register_operand" "0,l")))
1709    (clobber (match_scratch:SI 4 "=X,3"))]
1710   "ISA_HAS_MACC"
1712   if (which_alternative == 1)
1713     return "macc\t%0,%1,%2";
1714   else if (TARGET_MIPS5500)
1715     return "madd\t%1,%2";
1716   else
1717     /* The VR4130 assumes that there is a two-cycle latency between a macc
1718        that "writes" to $0 and an instruction that reads from it.  We avoid
1719        this by assigning to $1 instead.  */
1720     return "%[macc\t%@,%1,%2%]";
1722   [(set_attr "type" "imadd")
1723    (set_attr "accum_in" "3")
1724    (set_attr "mode" "SI")])
1726 (define_insn "*msac"
1727   [(set (match_operand:SI 0 "register_operand" "=l,d")
1728         (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1729                   (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1730                            (match_operand:SI 3 "register_operand" "d,d"))))
1731    (clobber (match_scratch:SI 4 "=X,1"))]
1732   "ISA_HAS_MSAC"
1734   if (which_alternative == 1)
1735     return "msac\t%0,%2,%3";
1736   else if (TARGET_MIPS5500)
1737     return "msub\t%2,%3";
1738   else
1739     return "msac\t$0,%2,%3";
1741   [(set_attr "type"     "imadd")
1742    (set_attr "accum_in" "1")
1743    (set_attr "mode"     "SI")])
1745 ;; An msac-like instruction implemented using negation and a macc.
1746 (define_insn_and_split "*msac_using_macc"
1747   [(set (match_operand:SI 0 "register_operand" "=l,d")
1748         (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1749                   (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1750                            (match_operand:SI 3 "register_operand" "d,d"))))
1751    (clobber (match_scratch:SI 4 "=X,1"))
1752    (clobber (match_scratch:SI 5 "=d,d"))]
1753   "ISA_HAS_MACC && !ISA_HAS_MSAC"
1754   "#"
1755   "&& reload_completed"
1756   [(set (match_dup 5)
1757         (neg:SI (match_dup 3)))
1758    (parallel
1759        [(set (match_dup 0)
1760              (plus:SI (mult:SI (match_dup 2)
1761                                (match_dup 5))
1762                       (match_dup 1)))
1763         (clobber (match_dup 4))])]
1764   ""
1765   [(set_attr "type"     "imadd")
1766    (set_attr "accum_in" "1")
1767    (set_attr "insn_count" "2")])
1769 ;; Patterns generated by the define_peephole2 below.
1771 (define_insn "*macc2"
1772   [(set (match_operand:SI 0 "muldiv_target_operand" "=l")
1773         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1774                           (match_operand:SI 2 "register_operand" "d"))
1775                  (match_dup 0)))
1776    (set (match_operand:SI 3 "register_operand" "=d")
1777         (plus:SI (mult:SI (match_dup 1)
1778                           (match_dup 2))
1779                  (match_dup 0)))]
1780   "ISA_HAS_MACC && reload_completed"
1781   "macc\t%3,%1,%2"
1782   [(set_attr "type"     "imadd")
1783    (set_attr "accum_in" "0")
1784    (set_attr "mode"     "SI")])
1786 (define_insn "*msac2"
1787   [(set (match_operand:SI 0 "muldiv_target_operand" "=l")
1788         (minus:SI (match_dup 0)
1789                   (mult:SI (match_operand:SI 1 "register_operand" "d")
1790                            (match_operand:SI 2 "register_operand" "d"))))
1791    (set (match_operand:SI 3 "register_operand" "=d")
1792         (minus:SI (match_dup 0)
1793                   (mult:SI (match_dup 1)
1794                            (match_dup 2))))]
1795   "ISA_HAS_MSAC && reload_completed"
1796   "msac\t%3,%1,%2"
1797   [(set_attr "type"     "imadd")
1798    (set_attr "accum_in" "0")
1799    (set_attr "mode"     "SI")])
1801 ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1802 ;; Similarly msac.
1804 ;; Operand 0: LO
1805 ;; Operand 1: macc/msac
1806 ;; Operand 2: GPR (destination)
1807 (define_peephole2
1808   [(parallel
1809        [(set (match_operand:SI 0 "lo_operand")
1810              (match_operand:SI 1 "macc_msac_operand"))
1811         (clobber (scratch:SI))])
1812    (set (match_operand:SI 2 "d_operand")
1813         (match_dup 0))]
1814   ""
1815   [(parallel [(set (match_dup 0)
1816                    (match_dup 1))
1817               (set (match_dup 2)
1818                    (match_dup 1))])])
1820 ;; When we have a three-address multiplication instruction, it should
1821 ;; be faster to do a separate multiply and add, rather than moving
1822 ;; something into LO in order to use a macc instruction.
1824 ;; This peephole needs a scratch register to cater for the case when one
1825 ;; of the multiplication operands is the same as the destination.
1827 ;; Operand 0: GPR (scratch)
1828 ;; Operand 1: LO
1829 ;; Operand 2: GPR (addend)
1830 ;; Operand 3: GPR (destination)
1831 ;; Operand 4: macc/msac
1832 ;; Operand 5: new multiplication
1833 ;; Operand 6: new addition/subtraction
1834 (define_peephole2
1835   [(match_scratch:SI 0 "d")
1836    (set (match_operand:SI 1 "lo_operand")
1837         (match_operand:SI 2 "d_operand"))
1838    (match_dup 0)
1839    (parallel
1840        [(set (match_operand:SI 3 "d_operand")
1841              (match_operand:SI 4 "macc_msac_operand"))
1842         (clobber (match_dup 1))])]
1843   "ISA_HAS_MUL3 && peep2_reg_dead_p (2, operands[1])"
1844   [(parallel [(set (match_dup 0)
1845                    (match_dup 5))
1846               (clobber (match_dup 1))])
1847    (set (match_dup 3)
1848         (match_dup 6))]
1850   operands[5] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1851   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1852                                 operands[2], operands[0]);
1855 ;; Same as above, except LO is the initial target of the macc.
1857 ;; Operand 0: GPR (scratch)
1858 ;; Operand 1: LO
1859 ;; Operand 2: GPR (addend)
1860 ;; Operand 3: macc/msac
1861 ;; Operand 4: GPR (destination)
1862 ;; Operand 5: new multiplication
1863 ;; Operand 6: new addition/subtraction
1864 (define_peephole2
1865   [(match_scratch:SI 0 "d")
1866    (set (match_operand:SI 1 "lo_operand")
1867         (match_operand:SI 2 "d_operand"))
1868    (match_dup 0)
1869    (parallel
1870        [(set (match_dup 1)
1871              (match_operand:SI 3 "macc_msac_operand"))
1872         (clobber (scratch:SI))])
1873    (match_dup 0)
1874    (set (match_operand:SI 4 "d_operand")
1875         (match_dup 1))]
1876   "ISA_HAS_MUL3 && peep2_reg_dead_p (3, operands[1])"
1877   [(parallel [(set (match_dup 0)
1878                    (match_dup 5))
1879               (clobber (match_dup 1))])
1880    (set (match_dup 4)
1881         (match_dup 6))]
1883   operands[5] = XEXP (operands[3], GET_CODE (operands[3]) == PLUS ? 0 : 1);
1884   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
1885                                 operands[2], operands[0]);
1888 ;; See the comment above *mul_add_si for details.
1889 (define_insn "*mul_sub_si"
1890   [(set (match_operand:SI 0 "register_operand" "=l*?*?,l,d?")
1891         (minus:SI (match_operand:SI 1 "register_operand" "0,0,d")
1892                   (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1893                            (match_operand:SI 3 "register_operand" "d,d,d"))))
1894    (clobber (match_scratch:SI 4 "=X,X,l"))
1895    (clobber (match_scratch:SI 5 "=X,X,&d"))]
1896   "GENERATE_MADD_MSUB"
1897   "@
1898    msub\t%2,%3
1899    msub\t%2,%3
1900    #"
1901   [(set_attr "type"     "imadd")
1902    (set_attr "accum_in" "1")
1903    (set_attr "mode"     "SI")
1904    (set_attr "insn_count" "1,1,2")
1905    (set (attr "enabled")
1906         (cond [(and (eq_attr "alternative" "0")
1907                     (match_test "!mips_lra_flag"))
1908                   (const_string "yes")
1909                (and (eq_attr "alternative" "1")
1910                     (match_test "mips_lra_flag"))
1911                   (const_string "yes")
1912                (eq_attr "alternative" "2")
1913                   (const_string "yes")]
1914               (const_string "no")))])
1916 ;; Split *mul_sub_si if both the source and destination accumulator
1917 ;; values are GPRs.
1918 (define_split
1919   [(set (match_operand:SI 0 "d_operand")
1920         (minus:SI (match_operand:SI 1 "d_operand")
1921                   (mult:SI (match_operand:SI 2 "d_operand")
1922                            (match_operand:SI 3 "d_operand"))))
1923    (clobber (match_operand:SI 4 "lo_operand"))
1924    (clobber (match_operand:SI 5 "d_operand"))]
1925   "reload_completed"
1926   [(parallel [(set (match_dup 5)
1927                    (mult:SI (match_dup 2) (match_dup 3)))
1928               (clobber (match_dup 4))])
1929    (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 5)))]
1930   "")
1932 (define_insn "*muls"
1933   [(set (match_operand:SI 0 "register_operand" "=l,d")
1934         (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1935                          (match_operand:SI 2 "register_operand" "d,d"))))
1936    (clobber (match_scratch:SI 3 "=X,l"))]
1937   "ISA_HAS_MULS"
1938   "@
1939    muls\t$0,%1,%2
1940    muls\t%0,%1,%2"
1941   [(set_attr "type"     "imul,imul3")
1942    (set_attr "mode"     "SI")])
1944 (define_expand "<u>mulsidi3"
1945   [(set (match_operand:DI 0 "register_operand")
1946         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1947                  (any_extend:DI (match_operand:SI 2 "register_operand"))))]
1948   "mips_mulsidi3_gen_fn (<CODE>) != NULL"
1950   mulsidi3_gen_fn fn = mips_mulsidi3_gen_fn (<CODE>);
1951   emit_insn (fn (operands[0], operands[1], operands[2]));
1952   DONE;
1955 (define_expand "<u>mulsidi3_32bit_mips16"
1956   [(set (match_operand:DI 0 "register_operand")
1957         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1958                  (any_extend:DI (match_operand:SI 2 "register_operand"))))]
1959   "!TARGET_64BIT && TARGET_MIPS16"
1961   rtx hilo;
1963   hilo = gen_rtx_REG (DImode, MD_REG_FIRST);
1964   emit_insn (gen_<u>mulsidi3_32bit (hilo, operands[1], operands[2]));
1965   emit_move_insn (operands[0], hilo);
1966   DONE;
1969 ;; As well as being named patterns, these instructions are used by the
1970 ;; __builtin_mips_mult<u>() functions.  We must always make those functions
1971 ;; available if !TARGET_64BIT && ISA_HAS_DSP.
1972 (define_insn "<u>mulsidi3_32bit"
1973   [(set (match_operand:DI 0 "muldiv_target_operand" "=ka")
1974         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1975                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1976   "!TARGET_64BIT && (!TARGET_FIX_R4000 || ISA_HAS_DSP)"
1978   if (ISA_HAS_DSP_MULT)
1979     return "mult<u>\t%q0,%1,%2";
1980   else
1981     return "mult<u>\t%1,%2";
1983   [(set_attr "type" "imul")
1984    (set_attr "mode" "SI")])
1986 (define_insn "<u>mulsidi3_32bit_r4000"
1987   [(set (match_operand:DI 0 "register_operand" "=d")
1988         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1989                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1990    (clobber (match_scratch:DI 3 "=x"))]
1991   "!TARGET_64BIT && TARGET_FIX_R4000 && !ISA_HAS_DSP"
1992   "mult<u>\t%1,%2\;mflo\t%L0\;mfhi\t%M0"
1993   [(set_attr "type" "imul")
1994    (set_attr "mode" "SI")
1995    (set_attr "insn_count" "3")])
1997 (define_insn_and_split "<u>mulsidi3_64bit"
1998   [(set (match_operand:DI 0 "register_operand" "=d")
1999         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2000                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
2001    (clobber (match_scratch:TI 3 "=x"))
2002    (clobber (match_scratch:DI 4 "=d"))]
2003   "TARGET_64BIT && !TARGET_FIX_R4000 && !ISA_HAS_DMUL3 && !TARGET_MIPS16"
2004   "#"
2005   "&& reload_completed"
2006   [(const_int 0)]
2008   emit_insn (gen_<u>mulsidi3_64bit_split (operands[0], operands[1],
2009                                           operands[2], operands[4]));
2010   DONE;
2012   [(set_attr "type" "imul")
2013    (set_attr "mode" "SI")
2014    (set (attr "insn_count")
2015         (if_then_else (match_test "ISA_HAS_EXT_INS")
2016                       (const_int 4)
2017                       (const_int 7)))])
2019 (define_expand "<u>mulsidi3_64bit_mips16"
2020   [(set (match_operand:DI 0 "register_operand")
2021         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
2022                  (any_extend:DI (match_operand:SI 2 "register_operand"))))]
2023   "TARGET_64BIT && TARGET_MIPS16"
2025   emit_insn (gen_<u>mulsidi3_64bit_split (operands[0], operands[1],
2026                                           operands[2], gen_reg_rtx (DImode)));
2027   DONE;
2030 (define_expand "<u>mulsidi3_64bit_split"
2031   [(set (match_operand:DI 0 "register_operand")
2032         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
2033                  (any_extend:DI (match_operand:SI 2 "register_operand"))))
2034    (clobber (match_operand:DI 3 "register_operand"))]
2035   ""
2037   rtx hilo;
2039   hilo = gen_rtx_REG (TImode, MD_REG_FIRST);
2040   emit_insn (gen_<u>mulsidi3_64bit_hilo (hilo, operands[1], operands[2]));
2042   emit_move_insn (operands[0], gen_rtx_REG (DImode, LO_REGNUM));
2043   emit_insn (gen_mfhidi_ti (operands[3], hilo));
2045   if (ISA_HAS_EXT_INS)
2046     emit_insn (gen_insvdi (operands[0], GEN_INT (32), GEN_INT (32),
2047                            operands[3]));
2048   else
2049     {
2050       /* Zero-extend the low part.  */
2051       mips_emit_binary (ASHIFT, operands[0], operands[0], GEN_INT (32));
2052       mips_emit_binary (LSHIFTRT, operands[0], operands[0], GEN_INT (32));
2054       /* Shift the high part into place.  */
2055       mips_emit_binary (ASHIFT, operands[3], operands[3], GEN_INT (32));
2057       /* OR the two halves together.  */
2058       mips_emit_binary (IOR, operands[0], operands[0], operands[3]);
2059     }
2060   DONE;
2063 (define_insn "<u>mulsidi3_64bit_hilo"
2064   [(set (match_operand:TI 0 "muldiv_target_operand" "=x")
2065         (unspec:TI
2066           [(mult:DI
2067              (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2068              (any_extend:DI (match_operand:SI 2 "register_operand" "d")))]
2069           UNSPEC_SET_HILO))]
2070   "TARGET_64BIT && !TARGET_FIX_R4000"
2071   "mult<u>\t%1,%2"
2072   [(set_attr "type" "imul")
2073    (set_attr "mode" "SI")])
2075 ;; See comment before the ISA_HAS_DMUL3 case in mips_mulsidi3_gen_fn.
2076 (define_insn "mulsidi3_64bit_dmul"
2077   [(set (match_operand:DI 0 "register_operand" "=d")
2078         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2079                  (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
2080    (clobber (match_scratch:DI 3 "=l"))]
2081   "ISA_HAS_DMUL3"
2082   "dmul\t%0,%1,%2"
2083   [(set_attr "type" "imul3")
2084    (set_attr "mode" "DI")])
2086 ;; Widening multiply with negation.
2087 (define_insn "*muls<u>_di"
2088   [(set (match_operand:DI 0 "muldiv_target_operand" "=x")
2089         (neg:DI
2090          (mult:DI
2091           (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2092           (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
2093   "!TARGET_64BIT && ISA_HAS_MULS"
2094   "muls<u>\t$0,%1,%2"
2095   [(set_attr "type" "imul")
2096    (set_attr "mode" "SI")])
2098 ;; As well as being named patterns, these instructions are used by the
2099 ;; __builtin_mips_msub<u>() functions.  We must always make those functions
2100 ;; available if !TARGET_64BIT && ISA_HAS_DSP.
2102 ;; This leads to a slight inconsistency.  We honor any tuning overrides
2103 ;; in GENERATE_MADD_MSUB for -mno-dsp, but always ignore them for -mdsp,
2104 ;; even if !ISA_HAS_DSP_MULT.
2105 (define_insn "<u>msubsidi4"
2106   [(set (match_operand:DI 0 "muldiv_target_operand" "=ka")
2107         (minus:DI
2108            (match_operand:DI 3 "muldiv_target_operand" "0")
2109            (mult:DI
2110               (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2111               (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
2112   "!TARGET_64BIT && (ISA_HAS_MSAC || GENERATE_MADD_MSUB || ISA_HAS_DSP)"
2114   if (ISA_HAS_DSP_MULT)
2115     return "msub<u>\t%q0,%1,%2";
2116   else if (TARGET_MIPS5500 || GENERATE_MADD_MSUB)
2117     return "msub<u>\t%1,%2";
2118   else
2119     return "msac<u>\t$0,%1,%2";
2121   [(set_attr "type" "imadd")
2122    (set_attr "accum_in" "3")
2123    (set_attr "mode" "SI")])
2125 ;; _highpart patterns
2127 (define_expand "<su>mulsi3_highpart"
2128   [(set (match_operand:SI 0 "register_operand")
2129         (truncate:SI
2130          (lshiftrt:DI
2131           (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
2132                    (any_extend:DI (match_operand:SI 2 "register_operand")))
2133           (const_int 32))))]
2134   ""
2136   if (ISA_HAS_MULHI)
2137     emit_insn (gen_<su>mulsi3_highpart_mulhi_internal (operands[0],
2138                                                        operands[1],
2139                                                        operands[2]));
2140   else if (TARGET_MIPS16)
2141     emit_insn (gen_<su>mulsi3_highpart_split (operands[0], operands[1],
2142                                               operands[2]));
2143   else
2144     emit_insn (gen_<su>mulsi3_highpart_internal (operands[0], operands[1],
2145                                                  operands[2]));
2146   DONE;
2149 (define_insn_and_split "<su>mulsi3_highpart_internal"
2150   [(set (match_operand:SI 0 "register_operand" "=d")
2151         (truncate:SI
2152          (lshiftrt:DI
2153           (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2154                    (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
2155           (const_int 32))))
2156    (clobber (match_scratch:SI 3 "=l"))]
2157   "!ISA_HAS_MULHI && !TARGET_MIPS16"
2158   { return TARGET_FIX_R4000 ? "mult<u>\t%1,%2\n\tmfhi\t%0" : "#"; }
2159   "&& reload_completed && !TARGET_FIX_R4000"
2160   [(const_int 0)]
2162   emit_insn (gen_<su>mulsi3_highpart_split (operands[0], operands[1],
2163                                             operands[2]));
2164   DONE;
2166   [(set_attr "type" "imul")
2167    (set_attr "mode" "SI")
2168    (set_attr "insn_count" "2")])
2170 (define_expand "<su>mulsi3_highpart_split"
2171   [(set (match_operand:SI 0 "register_operand")
2172         (truncate:SI
2173          (lshiftrt:DI
2174           (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
2175                    (any_extend:DI (match_operand:SI 2 "register_operand")))
2176           (const_int 32))))]
2177   ""
2179   rtx hilo;
2181   if (TARGET_64BIT)
2182     {
2183       hilo = gen_rtx_REG (TImode, MD_REG_FIRST);
2184       emit_insn (gen_<u>mulsidi3_64bit_hilo (hilo, operands[1], operands[2]));
2185       emit_insn (gen_mfhisi_ti (operands[0], hilo));
2186     }
2187   else
2188     {
2189       hilo = gen_rtx_REG (DImode, MD_REG_FIRST);
2190       emit_insn (gen_<u>mulsidi3_32bit (hilo, operands[1], operands[2]));
2191       emit_insn (gen_mfhisi_di (operands[0], hilo));
2192     }
2193   DONE;
2196 (define_insn "<su>mulsi3_highpart_mulhi_internal"
2197   [(set (match_operand:SI 0 "register_operand" "=d")
2198         (truncate:SI
2199          (lshiftrt:DI
2200           (mult:DI
2201            (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2202            (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
2203           (const_int 32))))
2204    (clobber (match_scratch:SI 3 "=l"))]
2205   "ISA_HAS_MULHI"
2206   "mulhi<u>\t%0,%1,%2"
2207   [(set_attr "type" "imul3")
2208    (set_attr "mode" "SI")])
2210 (define_insn "*<su>mulsi3_highpart_neg_mulhi_internal"
2211   [(set (match_operand:SI 0 "register_operand" "=d")
2212         (truncate:SI
2213          (lshiftrt:DI
2214           (neg:DI
2215            (mult:DI
2216             (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2217             (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
2218           (const_int 32))))
2219    (clobber (match_scratch:SI 3 "=l"))]
2220   "ISA_HAS_MULHI"
2221   "mulshi<u>\t%0,%1,%2"
2222   [(set_attr "type" "imul3")
2223    (set_attr "mode" "SI")])
2225 ;; Disable unsigned multiplication for -mfix-vr4120.  This is for VR4120
2226 ;; errata MD(0), which says that dmultu does not always produce the
2227 ;; correct result.
2228 (define_expand "<su>muldi3_highpart"
2229   [(set (match_operand:DI 0 "register_operand")
2230         (truncate:DI
2231          (lshiftrt:TI
2232           (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
2233                    (any_extend:TI (match_operand:DI 2 "register_operand")))
2234           (const_int 64))))]
2235   "ISA_HAS_DMULT && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
2237   if (TARGET_MIPS16)
2238     emit_insn (gen_<su>muldi3_highpart_split (operands[0], operands[1],
2239                                               operands[2]));
2240   else
2241     emit_insn (gen_<su>muldi3_highpart_internal (operands[0], operands[1],
2242                                                  operands[2]));
2243   DONE;
2246 (define_insn_and_split "<su>muldi3_highpart_internal"
2247   [(set (match_operand:DI 0 "register_operand" "=d")
2248         (truncate:DI
2249          (lshiftrt:TI
2250           (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
2251                    (any_extend:TI (match_operand:DI 2 "register_operand" "d")))
2252           (const_int 64))))
2253    (clobber (match_scratch:DI 3 "=l"))]
2254   "ISA_HAS_DMULT
2255    && !TARGET_MIPS16
2256    && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
2257   { return TARGET_FIX_R4000 ? "dmult<u>\t%1,%2\n\tmfhi\t%0" : "#"; }
2258   "&& reload_completed && !TARGET_FIX_R4000"
2259   [(const_int 0)]
2261   emit_insn (gen_<su>muldi3_highpart_split (operands[0], operands[1],
2262                                             operands[2]));
2263   DONE;
2265   [(set_attr "type" "imul")
2266    (set_attr "mode" "DI")
2267    (set_attr "insn_count" "2")])
2269 (define_expand "<su>muldi3_highpart_split"
2270   [(set (match_operand:DI 0 "register_operand")
2271         (truncate:DI
2272          (lshiftrt:TI
2273           (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
2274                    (any_extend:TI (match_operand:DI 2 "register_operand")))
2275           (const_int 64))))]
2276   ""
2278   rtx hilo;
2280   hilo = gen_rtx_REG (TImode, MD_REG_FIRST);
2281   emit_insn (gen_<u>mulditi3_internal (hilo, operands[1], operands[2]));
2282   emit_insn (gen_mfhidi_ti (operands[0], hilo));
2283   DONE;
2286 (define_expand "<u>mulditi3"
2287   [(set (match_operand:TI 0 "register_operand")
2288         (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
2289                  (any_extend:TI (match_operand:DI 2 "register_operand"))))]
2290   "ISA_HAS_DMULT && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
2292   rtx hilo;
2294   if (TARGET_MIPS16)
2295     {
2296       hilo = gen_rtx_REG (TImode, MD_REG_FIRST);
2297       emit_insn (gen_<u>mulditi3_internal (hilo, operands[1], operands[2]));
2298       emit_move_insn (operands[0], hilo);
2299     }
2300   else if (TARGET_FIX_R4000)
2301     emit_insn (gen_<u>mulditi3_r4000 (operands[0], operands[1], operands[2]));
2302   else
2303     emit_insn (gen_<u>mulditi3_internal (operands[0], operands[1],
2304                                          operands[2]));
2305   DONE;
2308 (define_insn "<u>mulditi3_internal"
2309   [(set (match_operand:TI 0 "muldiv_target_operand" "=x")
2310         (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
2311                  (any_extend:TI (match_operand:DI 2 "register_operand" "d"))))]
2312   "ISA_HAS_DMULT
2313    && !TARGET_FIX_R4000
2314    && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
2315   "dmult<u>\t%1,%2"
2316   [(set_attr "type" "imul")
2317    (set_attr "mode" "DI")])
2319 (define_insn "<u>mulditi3_r4000"
2320   [(set (match_operand:TI 0 "register_operand" "=d")
2321         (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
2322                  (any_extend:TI (match_operand:DI 2 "register_operand" "d"))))
2323    (clobber (match_scratch:TI 3 "=x"))]
2324   "ISA_HAS_DMULT
2325    && TARGET_FIX_R4000
2326    && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
2327   "dmult<u>\t%1,%2\;mflo\t%L0\;mfhi\t%M0"
2328   [(set_attr "type" "imul")
2329    (set_attr "mode" "DI")
2330    (set_attr "insn_count" "3")])
2332 ;; The R4650 supports a 32-bit multiply/ 64-bit accumulate
2333 ;; instruction.  The HI/LO registers are used as a 64-bit accumulator.
2335 (define_insn "madsi"
2336   [(set (match_operand:SI 0 "register_operand" "+l")
2337         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
2338                           (match_operand:SI 2 "register_operand" "d"))
2339                  (match_dup 0)))]
2340   "TARGET_MAD"
2341   "mad\t%1,%2"
2342   [(set_attr "type"     "imadd")
2343    (set_attr "accum_in" "0")
2344    (set_attr "mode"     "SI")])
2346 ;; See the comment above <u>msubsidi4 for the relationship between
2347 ;; ISA_HAS_DSP and ISA_HAS_DSP_MULT.
2348 (define_insn "<u>maddsidi4"
2349   [(set (match_operand:DI 0 "muldiv_target_operand" "=ka")
2350         (plus:DI
2351          (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2352                   (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
2353          (match_operand:DI 3 "muldiv_target_operand" "0")))]
2354   "(TARGET_MAD || ISA_HAS_MACC || GENERATE_MADD_MSUB || ISA_HAS_DSP)
2355    && !TARGET_64BIT"
2357   if (TARGET_MAD)
2358     return "mad<u>\t%1,%2";
2359   else if (ISA_HAS_DSP_MULT)
2360     return "madd<u>\t%q0,%1,%2";
2361   else if (GENERATE_MADD_MSUB || TARGET_MIPS5500)
2362     return "madd<u>\t%1,%2";
2363   else
2364     /* See comment in *macc.  */
2365     return "%[macc<u>\t%@,%1,%2%]";
2367   [(set_attr "type" "imadd")
2368    (set_attr "accum_in" "3")
2369    (set_attr "mode" "SI")])
2371 ;; Floating point multiply accumulate instructions.
2373 (define_insn "*madd4<mode>"
2374   [(set (match_operand:ANYF 0 "register_operand" "=f")
2375         (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
2376                               (match_operand:ANYF 2 "register_operand" "f"))
2377                    (match_operand:ANYF 3 "register_operand" "f")))]
2378   "ISA_HAS_FP_MADD4_MSUB4 && TARGET_FUSED_MADD"
2379   "madd.<fmt>\t%0,%3,%1,%2"
2380   [(set_attr "type" "fmadd")
2381    (set_attr "accum_in" "3")
2382    (set_attr "mode" "<UNITMODE>")])
2384 (define_insn "*madd3<mode>"
2385   [(set (match_operand:ANYF 0 "register_operand" "=f")
2386         (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
2387                               (match_operand:ANYF 2 "register_operand" "f"))
2388                    (match_operand:ANYF 3 "register_operand" "0")))]
2389   "ISA_HAS_FP_MADD3_MSUB3 && TARGET_FUSED_MADD"
2390   "madd.<fmt>\t%0,%1,%2"
2391   [(set_attr "type" "fmadd")
2392    (set_attr "accum_in" "3")
2393    (set_attr "mode" "<UNITMODE>")])
2395 (define_insn "*msub4<mode>"
2396   [(set (match_operand:ANYF 0 "register_operand" "=f")
2397         (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
2398                                (match_operand:ANYF 2 "register_operand" "f"))
2399                     (match_operand:ANYF 3 "register_operand" "f")))]
2400   "ISA_HAS_FP_MADD4_MSUB4 && TARGET_FUSED_MADD"
2401   "msub.<fmt>\t%0,%3,%1,%2"
2402   [(set_attr "type" "fmadd")
2403    (set_attr "accum_in" "3")
2404    (set_attr "mode" "<UNITMODE>")])
2406 (define_insn "*msub3<mode>"
2407   [(set (match_operand:ANYF 0 "register_operand" "=f")
2408         (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
2409                                (match_operand:ANYF 2 "register_operand" "f"))
2410                     (match_operand:ANYF 3 "register_operand" "0")))]
2411   "ISA_HAS_FP_MADD3_MSUB3 && TARGET_FUSED_MADD"
2412   "msub.<fmt>\t%0,%1,%2"
2413   [(set_attr "type" "fmadd")
2414    (set_attr "accum_in" "3")
2415    (set_attr "mode" "<UNITMODE>")])
2417 (define_insn "*nmadd4<mode>"
2418   [(set (match_operand:ANYF 0 "register_operand" "=f")
2419         (neg:ANYF (plus:ANYF
2420                    (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
2421                               (match_operand:ANYF 2 "register_operand" "f"))
2422                    (match_operand:ANYF 3 "register_operand" "f"))))]
2423   "ISA_HAS_NMADD4_NMSUB4
2424    && TARGET_FUSED_MADD
2425    && HONOR_SIGNED_ZEROS (<MODE>mode)
2426    && !HONOR_NANS (<MODE>mode)"
2427   "nmadd.<fmt>\t%0,%3,%1,%2"
2428   [(set_attr "type" "fmadd")
2429    (set_attr "accum_in" "3")
2430    (set_attr "mode" "<UNITMODE>")])
2432 (define_insn "*nmadd3<mode>"
2433   [(set (match_operand:ANYF 0 "register_operand" "=f")
2434         (neg:ANYF (plus:ANYF
2435                    (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
2436                               (match_operand:ANYF 2 "register_operand" "f"))
2437                    (match_operand:ANYF 3 "register_operand" "0"))))]
2438   "ISA_HAS_NMADD3_NMSUB3
2439    && TARGET_FUSED_MADD
2440    && HONOR_SIGNED_ZEROS (<MODE>mode)
2441    && !HONOR_NANS (<MODE>mode)"
2442   "nmadd.<fmt>\t%0,%1,%2"
2443   [(set_attr "type" "fmadd")
2444    (set_attr "accum_in" "3")
2445    (set_attr "mode" "<UNITMODE>")])
2447 (define_insn "*nmadd4<mode>_fastmath"
2448   [(set (match_operand:ANYF 0 "register_operand" "=f")
2449         (minus:ANYF
2450          (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
2451                     (match_operand:ANYF 2 "register_operand" "f"))
2452          (match_operand:ANYF 3 "register_operand" "f")))]
2453   "ISA_HAS_NMADD4_NMSUB4
2454    && TARGET_FUSED_MADD
2455    && !HONOR_SIGNED_ZEROS (<MODE>mode)
2456    && !HONOR_NANS (<MODE>mode)"
2457   "nmadd.<fmt>\t%0,%3,%1,%2"
2458   [(set_attr "type" "fmadd")
2459    (set_attr "accum_in" "3")
2460    (set_attr "mode" "<UNITMODE>")])
2462 (define_insn "*nmadd3<mode>_fastmath"
2463   [(set (match_operand:ANYF 0 "register_operand" "=f")
2464         (minus:ANYF
2465          (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
2466                     (match_operand:ANYF 2 "register_operand" "f"))
2467          (match_operand:ANYF 3 "register_operand" "0")))]
2468   "ISA_HAS_NMADD3_NMSUB3
2469    && TARGET_FUSED_MADD
2470    && !HONOR_SIGNED_ZEROS (<MODE>mode)
2471    && !HONOR_NANS (<MODE>mode)"
2472   "nmadd.<fmt>\t%0,%1,%2"
2473   [(set_attr "type" "fmadd")
2474    (set_attr "accum_in" "3")
2475    (set_attr "mode" "<UNITMODE>")])
2477 (define_insn "*nmsub4<mode>"
2478   [(set (match_operand:ANYF 0 "register_operand" "=f")
2479         (neg:ANYF (minus:ANYF
2480                    (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
2481                               (match_operand:ANYF 3 "register_operand" "f"))
2482                    (match_operand:ANYF 1 "register_operand" "f"))))]
2483   "ISA_HAS_NMADD4_NMSUB4
2484    && TARGET_FUSED_MADD
2485    && HONOR_SIGNED_ZEROS (<MODE>mode)
2486    && !HONOR_NANS (<MODE>mode)"
2487   "nmsub.<fmt>\t%0,%1,%2,%3"
2488   [(set_attr "type" "fmadd")
2489    (set_attr "accum_in" "1")
2490    (set_attr "mode" "<UNITMODE>")])
2492 (define_insn "*nmsub3<mode>"
2493   [(set (match_operand:ANYF 0 "register_operand" "=f")
2494         (neg:ANYF (minus:ANYF
2495                    (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
2496                               (match_operand:ANYF 3 "register_operand" "f"))
2497                    (match_operand:ANYF 1 "register_operand" "0"))))]
2498   "ISA_HAS_NMADD3_NMSUB3
2499    && TARGET_FUSED_MADD
2500    && HONOR_SIGNED_ZEROS (<MODE>mode)
2501    && !HONOR_NANS (<MODE>mode)"
2502   "nmsub.<fmt>\t%0,%1,%2"
2503   [(set_attr "type" "fmadd")
2504    (set_attr "accum_in" "1")
2505    (set_attr "mode" "<UNITMODE>")])
2507 (define_insn "*nmsub4<mode>_fastmath"
2508   [(set (match_operand:ANYF 0 "register_operand" "=f")
2509         (minus:ANYF
2510          (match_operand:ANYF 1 "register_operand" "f")
2511          (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
2512                     (match_operand:ANYF 3 "register_operand" "f"))))]
2513   "ISA_HAS_NMADD4_NMSUB4
2514    && TARGET_FUSED_MADD
2515    && !HONOR_SIGNED_ZEROS (<MODE>mode)
2516    && !HONOR_NANS (<MODE>mode)"
2517   "nmsub.<fmt>\t%0,%1,%2,%3"
2518   [(set_attr "type" "fmadd")
2519    (set_attr "accum_in" "1")
2520    (set_attr "mode" "<UNITMODE>")])
2522 (define_insn "*nmsub3<mode>_fastmath"
2523   [(set (match_operand:ANYF 0 "register_operand" "=f")
2524         (minus:ANYF
2525          (match_operand:ANYF 1 "register_operand" "f")
2526          (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
2527                     (match_operand:ANYF 3 "register_operand" "0"))))]
2528   "ISA_HAS_NMADD3_NMSUB3
2529    && TARGET_FUSED_MADD
2530    && !HONOR_SIGNED_ZEROS (<MODE>mode)
2531    && !HONOR_NANS (<MODE>mode)"
2532   "nmsub.<fmt>\t%0,%1,%2"
2533   [(set_attr "type" "fmadd")
2534    (set_attr "accum_in" "1")
2535    (set_attr "mode" "<UNITMODE>")])
2538 ;;  ....................
2540 ;;      DIVISION and REMAINDER
2542 ;;  ....................
2545 (define_expand "div<mode>3"
2546   [(set (match_operand:ANYF 0 "register_operand")
2547         (div:ANYF (match_operand:ANYF 1 "reg_or_1_operand")
2548                   (match_operand:ANYF 2 "register_operand")))]
2549   "<divide_condition>"
2551   if (const_1_operand (operands[1], <MODE>mode))
2552     if (!(ISA_HAS_FP_RECIP_RSQRT (<MODE>mode)
2553           && flag_unsafe_math_optimizations))
2554       operands[1] = force_reg (<MODE>mode, operands[1]);
2557 ;; These patterns work around the early SB-1 rev2 core "F1" erratum:
2559 ;; If an mfc1 or dmfc1 happens to access the floating point register
2560 ;; file at the same time a long latency operation (div, sqrt, recip,
2561 ;; sqrt) iterates an intermediate result back through the floating
2562 ;; point register file bypass, then instead returning the correct
2563 ;; register value the mfc1 or dmfc1 operation returns the intermediate
2564 ;; result of the long latency operation.
2566 ;; The workaround is to insert an unconditional 'mov' from/to the
2567 ;; long latency op destination register.
2569 (define_insn "*div<mode>3"
2570   [(set (match_operand:ANYF 0 "register_operand" "=f")
2571         (div:ANYF (match_operand:ANYF 1 "register_operand" "f")
2572                   (match_operand:ANYF 2 "register_operand" "f")))]
2573   "<divide_condition>"
2575   if (TARGET_FIX_SB1)
2576     return "div.<fmt>\t%0,%1,%2\;mov.<fmt>\t%0,%0";
2577   else
2578     return "div.<fmt>\t%0,%1,%2";
2580   [(set_attr "type" "fdiv")
2581    (set_attr "mode" "<UNITMODE>")
2582    (set (attr "insn_count")
2583         (if_then_else (match_test "TARGET_FIX_SB1")
2584                       (const_int 2)
2585                       (const_int 1)))])
2587 (define_insn "*recip<mode>3"
2588   [(set (match_operand:ANYF 0 "register_operand" "=f")
2589         (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
2590                   (match_operand:ANYF 2 "register_operand" "f")))]
2591   "ISA_HAS_FP_RECIP_RSQRT (<MODE>mode) && flag_unsafe_math_optimizations"
2593   if (TARGET_FIX_SB1)
2594     return "recip.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
2595   else
2596     return "recip.<fmt>\t%0,%2";
2598   [(set_attr "type" "frdiv")
2599    (set_attr "mode" "<UNITMODE>")
2600    (set (attr "insn_count")
2601         (if_then_else (match_test "TARGET_FIX_SB1")
2602                       (const_int 2)
2603                       (const_int 1)))])
2605 ;; VR4120 errata MD(A1): signed division instructions do not work correctly
2606 ;; with negative operands.  We use special libgcc functions instead.
2607 (define_expand "divmod<mode>4"
2608   [(parallel
2609      [(set (match_operand:GPR 0 "register_operand")
2610            (div:GPR (match_operand:GPR 1 "register_operand")
2611                     (match_operand:GPR 2 "register_operand")))
2612       (set (match_operand:GPR 3 "register_operand")
2613            (mod:GPR (match_dup 1)
2614                     (match_dup 2)))])]
2615   "ISA_HAS_<D>DIV && !TARGET_FIX_VR4120"
2617   if (TARGET_MIPS16)
2618     {
2619       rtx lo = gen_rtx_REG (<MODE>mode, LO_REGNUM);
2620       emit_insn (gen_divmod<mode>4_mips16 (operands[0], operands[1],
2621                                            operands[2], operands[3], lo));
2622       DONE;
2623     }
2626 (define_insn_and_split "*divmod<mode>4"
2627   [(set (match_operand:GPR 0 "register_operand" "=l")
2628         (div:GPR (match_operand:GPR 1 "register_operand" "d")
2629                  (match_operand:GPR 2 "register_operand" "d")))
2630    (set (match_operand:GPR 3 "register_operand" "=d")
2631         (mod:GPR (match_dup 1)
2632                  (match_dup 2)))]
2633   "ISA_HAS_<D>DIV && !TARGET_FIX_VR4120 && !TARGET_MIPS16"
2634   "#"
2635   "&& reload_completed"
2636   [(const_int 0)]
2638   emit_insn (gen_divmod<mode>4_split (operands[3], operands[1], operands[2]));
2639   DONE;
2641  [(set_attr "type" "idiv")
2642   (set_attr "mode" "<MODE>")
2643   (set_attr "insn_count" "2")])
2645 ;; Expand generates divmod instructions for individual division and modulus
2646 ;; operations.  We then rely on CSE to reuse earlier divmods where possible.
2647 ;; This means that, when generating MIPS16 code, it is better not to expose
2648 ;; the fixed LO register until after CSE has finished.  However, it's still
2649 ;; better to split before register allocation, so that we don't allocate
2650 ;; one of the scarce MIPS16 registers to an unused result.
2651 (define_insn_and_split "divmod<mode>4_mips16"
2652   [(set (match_operand:GPR 0 "register_operand" "=d")
2653         (div:GPR (match_operand:GPR 1 "register_operand" "d")
2654                  (match_operand:GPR 2 "register_operand" "d")))
2655    (set (match_operand:GPR 3 "register_operand" "=d")
2656         (mod:GPR (match_dup 1)
2657                  (match_dup 2)))
2658    (clobber (match_operand:GPR 4 "lo_operand" "=l"))]
2659   "ISA_HAS_<D>DIV && !TARGET_FIX_VR4120 && TARGET_MIPS16"
2660   "#"
2661   "&& cse_not_expected"
2662   [(const_int 0)]
2664   emit_insn (gen_divmod<mode>4_split (operands[3], operands[1], operands[2]));
2665   emit_move_insn (operands[0], operands[4]);
2666   DONE;
2668  [(set_attr "type" "idiv")
2669   (set_attr "mode" "<MODE>")
2670   (set_attr "insn_count" "3")])
2672 (define_expand "udivmod<mode>4"
2673   [(parallel
2674      [(set (match_operand:GPR 0 "register_operand")
2675            (udiv:GPR (match_operand:GPR 1 "register_operand")
2676                      (match_operand:GPR 2 "register_operand")))
2677       (set (match_operand:GPR 3 "register_operand")
2678            (umod:GPR (match_dup 1)
2679                      (match_dup 2)))])]
2680   "ISA_HAS_<D>DIV && !TARGET_FIX_VR4120"
2682   if (TARGET_MIPS16)
2683     {
2684       rtx lo = gen_rtx_REG (<MODE>mode, LO_REGNUM);
2685       emit_insn (gen_udivmod<mode>4_mips16 (operands[0], operands[1],
2686                                             operands[2], operands[3], lo));
2687       DONE;
2688     }
2691 (define_insn_and_split "*udivmod<mode>4"
2692   [(set (match_operand:GPR 0 "register_operand" "=l")
2693         (udiv:GPR (match_operand:GPR 1 "register_operand" "d")
2694                   (match_operand:GPR 2 "register_operand" "d")))
2695    (set (match_operand:GPR 3 "register_operand" "=d")
2696         (umod:GPR (match_dup 1)
2697                   (match_dup 2)))]
2698   "ISA_HAS_<D>DIV && !TARGET_MIPS16"
2699   "#"
2700   "reload_completed"
2701   [(const_int 0)]
2703   emit_insn (gen_udivmod<mode>4_split (operands[3], operands[1], operands[2]));
2704   DONE;
2706   [(set_attr "type" "idiv")
2707    (set_attr "mode" "<MODE>")
2708    (set_attr "insn_count" "2")])
2710 ;; See the comment above "divmod<mode>4_mips16" for the split timing.
2711 (define_insn_and_split "udivmod<mode>4_mips16"
2712   [(set (match_operand:GPR 0 "register_operand" "=d")
2713         (udiv:GPR (match_operand:GPR 1 "register_operand" "d")
2714                   (match_operand:GPR 2 "register_operand" "d")))
2715    (set (match_operand:GPR 3 "register_operand" "=d")
2716         (umod:GPR (match_dup 1)
2717                   (match_dup 2)))
2718    (clobber (match_operand:GPR 4 "lo_operand" "=l"))]
2719   "ISA_HAS_<D>DIV && TARGET_MIPS16"
2720   "#"
2721   "cse_not_expected"
2722   [(const_int 0)]
2724   emit_insn (gen_udivmod<mode>4_split (operands[3], operands[1], operands[2]));
2725   emit_move_insn (operands[0], operands[4]);
2726   DONE;
2728   [(set_attr "type" "idiv")
2729    (set_attr "mode" "<MODE>")
2730    (set_attr "insn_count" "3")])
2732 (define_expand "<u>divmod<mode>4_split"
2733   [(set (match_operand:GPR 0 "register_operand")
2734         (any_mod:GPR (match_operand:GPR 1 "register_operand")
2735                      (match_operand:GPR 2 "register_operand")))]
2736   ""
2738   rtx hilo;
2740   if (TARGET_64BIT)
2741     {
2742       hilo = gen_rtx_REG (TImode, MD_REG_FIRST);
2743       emit_insn (gen_<u>divmod<mode>4_hilo_ti (hilo, operands[1],
2744                                                operands[2]));
2745       emit_insn (gen_mfhi<mode>_ti (operands[0], hilo));
2746     }
2747   else
2748     {
2749       hilo = gen_rtx_REG (DImode, MD_REG_FIRST);
2750       emit_insn (gen_<u>divmod<mode>4_hilo_di (hilo, operands[1],
2751                                                operands[2]));
2752       emit_insn (gen_mfhi<mode>_di (operands[0], hilo));
2753     }
2754   DONE;
2757 (define_insn "<u>divmod<GPR:mode>4_hilo_<HILO:mode>"
2758   [(set (match_operand:HILO 0 "muldiv_target_operand" "=x")
2759         (unspec:HILO
2760           [(any_div:GPR (match_operand:GPR 1 "register_operand" "d")
2761                         (match_operand:GPR 2 "register_operand" "d"))]
2762           UNSPEC_SET_HILO))]
2763   "ISA_HAS_<GPR:D>DIV"
2764   { return mips_output_division ("<GPR:d>div<u>\t%.,%1,%2", operands); }
2765   [(set_attr "type" "idiv")
2766    (set_attr "mode" "<GPR:MODE>")])
2769 ;;  ....................
2771 ;;      SQUARE ROOT
2773 ;;  ....................
2775 ;; These patterns work around the early SB-1 rev2 core "F1" erratum (see
2776 ;; "*div[sd]f3" comment for details).
2778 (define_insn "sqrt<mode>2"
2779   [(set (match_operand:ANYF 0 "register_operand" "=f")
2780         (sqrt:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2781   "<sqrt_condition>"
2783   if (TARGET_FIX_SB1)
2784     return "sqrt.<fmt>\t%0,%1\;mov.<fmt>\t%0,%0";
2785   else
2786     return "sqrt.<fmt>\t%0,%1";
2788   [(set_attr "type" "fsqrt")
2789    (set_attr "mode" "<UNITMODE>")
2790    (set (attr "insn_count")
2791         (if_then_else (match_test "TARGET_FIX_SB1")
2792                       (const_int 2)
2793                       (const_int 1)))])
2795 (define_insn "*rsqrt<mode>a"
2796   [(set (match_operand:ANYF 0 "register_operand" "=f")
2797         (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
2798                   (sqrt:ANYF (match_operand:ANYF 2 "register_operand" "f"))))]
2799   "ISA_HAS_FP_RECIP_RSQRT (<MODE>mode) && flag_unsafe_math_optimizations"
2801   if (TARGET_FIX_SB1)
2802     return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
2803   else
2804     return "rsqrt.<fmt>\t%0,%2";
2806   [(set_attr "type" "frsqrt")
2807    (set_attr "mode" "<UNITMODE>")
2808    (set (attr "insn_count")
2809         (if_then_else (match_test "TARGET_FIX_SB1")
2810                       (const_int 2)
2811                       (const_int 1)))])
2813 (define_insn "*rsqrt<mode>b"
2814   [(set (match_operand:ANYF 0 "register_operand" "=f")
2815         (sqrt:ANYF (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
2816                              (match_operand:ANYF 2 "register_operand" "f"))))]
2817   "ISA_HAS_FP_RECIP_RSQRT (<MODE>mode) && flag_unsafe_math_optimizations"
2819   if (TARGET_FIX_SB1)
2820     return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
2821   else
2822     return "rsqrt.<fmt>\t%0,%2";
2824   [(set_attr "type" "frsqrt")
2825    (set_attr "mode" "<UNITMODE>")
2826    (set (attr "insn_count")
2827         (if_then_else (match_test "TARGET_FIX_SB1")
2828                       (const_int 2)
2829                       (const_int 1)))])
2832 ;;  ....................
2834 ;;      ABSOLUTE VALUE
2836 ;;  ....................
2838 ;; Do not use the integer abs macro instruction, since that signals an
2839 ;; exception on -2147483648 (sigh).
2841 ;; The "legacy" (as opposed to "2008") form of ABS.fmt is an arithmetic
2842 ;; instruction that treats all NaN inputs as invalid; it does not clear
2843 ;; their sign bit.  We therefore can't use that form if the signs of
2844 ;; NaNs matter.
2846 (define_insn "abs<mode>2"
2847   [(set (match_operand:ANYF 0 "register_operand" "=f")
2848         (abs:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2849   "mips_abs == MIPS_IEEE_754_2008 || !HONOR_NANS (<MODE>mode)"
2850   "abs.<fmt>\t%0,%1"
2851   [(set_attr "type" "fabs")
2852    (set_attr "mode" "<UNITMODE>")])
2855 ;;  ...................
2857 ;;  Count leading zeroes.
2859 ;;  ...................
2862 (define_insn "clz<mode>2"
2863   [(set (match_operand:GPR 0 "register_operand" "=d")
2864         (clz:GPR (match_operand:GPR 1 "register_operand" "d")))]
2865   "ISA_HAS_CLZ_CLO"
2866   "<d>clz\t%0,%1"
2867   [(set_attr "type" "clz")
2868    (set_attr "mode" "<MODE>")])
2871 ;;  ...................
2873 ;;  Count number of set bits.
2875 ;;  ...................
2878 (define_insn "popcount<mode>2"
2879   [(set (match_operand:GPR 0 "register_operand" "=d")
2880         (popcount:GPR (match_operand:GPR 1 "register_operand" "d")))]
2881   "ISA_HAS_POP"
2882   "<d>pop\t%0,%1"
2883   [(set_attr "type" "pop")
2884    (set_attr "mode" "<MODE>")])
2886 ;; The POP instruction is special as it does not take into account the upper
2887 ;; 32bits and is documented that way.
2888 (define_insn "*popcountdi2_trunc"
2889   [(set (match_operand:SI 0 "register_operand" "=d")
2890        (popcount:SI (truncate:SI (match_operand:DI 1 "register_operand" "d"))))]
2891   "ISA_HAS_POP && TARGET_64BIT"
2892   "pop\t%0,%1"
2893   [(set_attr "type" "pop")
2894    (set_attr "mode" "SI")])
2897 ;;  ....................
2899 ;;      NEGATION and ONE'S COMPLEMENT
2901 ;;  ....................
2903 (define_insn "negsi2"
2904   [(set (match_operand:SI 0 "register_operand" "=d")
2905         (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2906   ""
2908   if (TARGET_MIPS16)
2909     return "neg\t%0,%1";
2910   else
2911     return "subu\t%0,%.,%1";
2913   [(set_attr "alu_type" "sub")
2914    (set_attr "mode"     "SI")])
2916 (define_insn "negdi2"
2917   [(set (match_operand:DI 0 "register_operand" "=d")
2918         (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2919   "TARGET_64BIT && !TARGET_MIPS16"
2920   "dsubu\t%0,%.,%1"
2921   [(set_attr "alu_type" "sub")
2922    (set_attr "mode"     "DI")])
2924 ;; The "legacy" (as opposed to "2008") form of NEG.fmt is an arithmetic
2925 ;; instruction that treats all NaN inputs as invalid; it does not flip
2926 ;; their sign bit.  We therefore can't use that form if the signs of
2927 ;; NaNs matter.
2929 (define_insn "neg<mode>2"
2930   [(set (match_operand:ANYF 0 "register_operand" "=f")
2931         (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2932   "mips_abs == MIPS_IEEE_754_2008 || !HONOR_NANS (<MODE>mode)"
2933   "neg.<fmt>\t%0,%1"
2934   [(set_attr "type" "fneg")
2935    (set_attr "mode" "<UNITMODE>")])
2937 (define_insn "one_cmpl<mode>2"
2938   [(set (match_operand:GPR 0 "register_operand" "=!u,d")
2939         (not:GPR (match_operand:GPR 1 "register_operand" "!u,d")))]
2940   ""
2942   if (TARGET_MIPS16)
2943     return "not\t%0,%1";
2944   else
2945     return "nor\t%0,%.,%1";
2947   [(set_attr "alu_type" "not")
2948    (set_attr "compression" "micromips,*")
2949    (set_attr "mode" "<MODE>")])
2952 ;;  ....................
2954 ;;      LOGICAL
2956 ;;  ....................
2959 ;; Many of these instructions use trivial define_expands, because we
2960 ;; want to use a different set of constraints when TARGET_MIPS16.
2962 (define_expand "and<mode>3"
2963   [(set (match_operand:GPR 0 "register_operand")
2964         (and:GPR (match_operand:GPR 1 "register_operand")
2965                  (match_operand:GPR 2 "and_reg_operand")))])
2967 ;; The middle-end is not allowed to convert ANDing with 0xffff_ffff into a
2968 ;; zero_extendsidi2 because of TRULY_NOOP_TRUNCATION, so handle these here.
2969 ;; Note that this variant does not trigger for SI mode because we require
2970 ;; a 64-bit HOST_WIDE_INT and 0xffff_ffff wouldn't be a canonical
2971 ;; sign-extended SImode value.
2973 ;; These are possible combinations for operand 1 and 2.  The table
2974 ;; includes both MIPS and MIPS16 cases.  (r=register, mem=memory,
2975 ;; 16=MIPS16, x=match, S=split):
2977 ;;     \ op1    r/EXT   r/!EXT  mem   r/16   mem/16
2978 ;;  op2
2980 ;;  andi           x     x
2981 ;;  0xff           x     x       x             x
2982 ;;  0xffff         x     x       x             x
2983 ;;  0xffff_ffff    x     S       x     S       x
2984 ;;  low-bitmask    x
2985 ;;  register       x     x
2986 ;;  register =op1                      x
2988 (define_insn "*and<mode>3"
2989   [(set (match_operand:GPR 0 "register_operand" "=d,d,d,!u,d,d,d,!u,d")
2990         (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "o,o,W,!u,d,d,d,0,d")
2991                  (match_operand:GPR 2 "and_operand" "Yb,Yh,Yw,Uean,K,Yx,Yw,!u,d")))]
2992   "!TARGET_MIPS16 && and_operands_ok (<MODE>mode, operands[1], operands[2])"
2994   int len;
2996   switch (which_alternative)
2997     {
2998     case 0:
2999       operands[1] = gen_lowpart (QImode, operands[1]);
3000       return "lbu\t%0,%1";
3001     case 1:
3002       operands[1] = gen_lowpart (HImode, operands[1]);
3003       return "lhu\t%0,%1";
3004     case 2:
3005       operands[1] = gen_lowpart (SImode, operands[1]);
3006       return "lwu\t%0,%1";
3007     case 3:
3008     case 4:
3009       return "andi\t%0,%1,%x2";
3010     case 5:
3011       len = low_bitmask_len (<MODE>mode, INTVAL (operands[2]));
3012       operands[2] = GEN_INT (len);
3013       return "<d>ext\t%0,%1,0,%2";
3014     case 6:
3015       return "#";
3016     case 7:
3017     case 8:
3018       return "and\t%0,%1,%2";
3019     default:
3020       gcc_unreachable ();
3021     }
3023   [(set_attr "move_type" "load,load,load,andi,andi,ext_ins,shift_shift,logical,logical")
3024    (set_attr "compression" "*,*,*,micromips,*,*,*,micromips,*")
3025    (set_attr "mode" "<MODE>")])
3027 (define_insn "*and<mode>3_mips16"
3028   [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d")
3029         (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "%W,W,W,d,0")
3030                  (match_operand:GPR 2 "and_operand" "Yb,Yh,Yw,Yw,d")))]
3031   "TARGET_MIPS16 && and_operands_ok (<MODE>mode, operands[1], operands[2])"
3033   switch (which_alternative)
3034     {
3035     case 0:
3036       operands[1] = gen_lowpart (QImode, operands[1]);
3037       return "lbu\t%0,%1";
3038     case 1:
3039       operands[1] = gen_lowpart (HImode, operands[1]);
3040       return "lhu\t%0,%1";
3041     case 2:
3042       operands[1] = gen_lowpart (SImode, operands[1]);
3043       return "lwu\t%0,%1";
3044     case 3:
3045       return "#";
3046     case 4:
3047       return "and\t%0,%2";
3048     default:
3049       gcc_unreachable ();
3050     }
3052   [(set_attr "move_type" "load,load,load,shift_shift,logical")
3053    (set_attr "mode" "<MODE>")])
3055 (define_expand "ior<mode>3"
3056   [(set (match_operand:GPR 0 "register_operand")
3057         (ior:GPR (match_operand:GPR 1 "register_operand")
3058                  (match_operand:GPR 2 "uns_arith_operand")))]
3059   ""
3061   if (TARGET_MIPS16)
3062     operands[2] = force_reg (<MODE>mode, operands[2]);
3065 (define_insn "*ior<mode>3"
3066   [(set (match_operand:GPR 0 "register_operand" "=!u,d,d")
3067         (ior:GPR (match_operand:GPR 1 "register_operand" "%0,d,d")
3068                  (match_operand:GPR 2 "uns_arith_operand" "!u,d,K")))]
3069   "!TARGET_MIPS16"
3070   "@
3071    or\t%0,%1,%2
3072    or\t%0,%1,%2
3073    ori\t%0,%1,%x2"
3074   [(set_attr "alu_type" "or")
3075    (set_attr "compression" "micromips,*,*")
3076    (set_attr "mode" "<MODE>")])
3078 (define_insn "*ior<mode>3_mips16"
3079   [(set (match_operand:GPR 0 "register_operand" "=d")
3080         (ior:GPR (match_operand:GPR 1 "register_operand" "%0")
3081                  (match_operand:GPR 2 "register_operand" "d")))]
3082   "TARGET_MIPS16"
3083   "or\t%0,%2"
3084   [(set_attr "alu_type" "or")
3085    (set_attr "mode" "<MODE>")])
3087 (define_expand "xor<mode>3"
3088   [(set (match_operand:GPR 0 "register_operand")
3089         (xor:GPR (match_operand:GPR 1 "register_operand")
3090                  (match_operand:GPR 2 "uns_arith_operand")))]
3091   ""
3092   "")
3094 (define_insn "*xor<mode>3"
3095   [(set (match_operand:GPR 0 "register_operand" "=!u,d,d")
3096         (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d")
3097                  (match_operand:GPR 2 "uns_arith_operand" "!u,d,K")))]
3098   "!TARGET_MIPS16"
3099   "@
3100    xor\t%0,%1,%2
3101    xor\t%0,%1,%2
3102    xori\t%0,%1,%x2"
3103   [(set_attr "alu_type" "xor")
3104    (set_attr "compression" "micromips,*,*")
3105    (set_attr "mode" "<MODE>")])
3107 (define_insn "*xor<mode>3_mips16"
3108   [(set (match_operand:GPR 0 "register_operand" "=d,t,t,t")
3109         (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d,d")
3110                  (match_operand:GPR 2 "uns_arith_operand" "d,Uub8,K,d")))]
3111   "TARGET_MIPS16"
3112   "@
3113    xor\t%0,%2
3114    cmpi\t%1,%2
3115    cmpi\t%1,%2
3116    cmp\t%1,%2"
3117   [(set_attr "alu_type" "xor")
3118    (set_attr "mode" "<MODE>")
3119    (set_attr "extended_mips16" "no,no,yes,no")])
3121 (define_insn "*nor<mode>3"
3122   [(set (match_operand:GPR 0 "register_operand" "=d")
3123         (and:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
3124                  (not:GPR (match_operand:GPR 2 "register_operand" "d"))))]
3125   "!TARGET_MIPS16"
3126   "nor\t%0,%1,%2"
3127   [(set_attr "alu_type" "nor")
3128    (set_attr "mode" "<MODE>")])
3131 ;;  ....................
3133 ;;      TRUNCATION
3135 ;;  ....................
3139 (define_insn "truncdfsf2"
3140   [(set (match_operand:SF 0 "register_operand" "=f")
3141         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3142   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3143   "cvt.s.d\t%0,%1"
3144   [(set_attr "type"     "fcvt")
3145    (set_attr "cnv_mode" "D2S")   
3146    (set_attr "mode"     "SF")])
3148 ;; Integer truncation patterns.  Truncating SImode values to smaller
3149 ;; modes is a no-op, as it is for most other GCC ports.  Truncating
3150 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
3151 ;; need to make sure that the lower 32 bits are properly sign-extended
3152 ;; (see TRULY_NOOP_TRUNCATION).  Truncating DImode values into modes
3153 ;; smaller than SImode is equivalent to two separate truncations:
3155 ;;                        A       B
3156 ;;    DI ---> HI  ==  DI ---> SI ---> HI
3157 ;;    DI ---> QI  ==  DI ---> SI ---> QI
3159 ;; Step A needs a real instruction but step B does not.
3161 (define_insn "truncdi<mode>2"
3162   [(set (match_operand:SUBDI 0 "nonimmediate_operand" "=d,m")
3163         (truncate:SUBDI (match_operand:DI 1 "register_operand" "d,d")))]
3164   "TARGET_64BIT"
3165   "@
3166     sll\t%0,%1,0
3167     <store>\t%1,%0"
3168   [(set_attr "move_type" "sll0,store")
3169    (set_attr "mode" "SI")])
3171 ;; Combiner patterns to optimize shift/truncate combinations.
3173 (define_insn "*ashr_trunc<mode>"
3174   [(set (match_operand:SUBDI 0 "register_operand" "=d")
3175         (truncate:SUBDI
3176           (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
3177                        (match_operand:DI 2 "const_arith_operand" ""))))]
3178   "TARGET_64BIT && !TARGET_MIPS16 && IN_RANGE (INTVAL (operands[2]), 32, 63)"
3179   "dsra\t%0,%1,%2"
3180   [(set_attr "type" "shift")
3181    (set_attr "mode" "<MODE>")])
3183 (define_insn "*lshr32_trunc<mode>"
3184   [(set (match_operand:SUBDI 0 "register_operand" "=d")
3185         (truncate:SUBDI
3186           (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
3187                        (const_int 32))))]
3188   "TARGET_64BIT && !TARGET_MIPS16"
3189   "dsra\t%0,%1,32"
3190   [(set_attr "type" "shift")
3191    (set_attr "mode" "<MODE>")])
3193 ;; Logical shift by more than 32 results in proper SI values so truncation is
3194 ;; removed by the middle end.  Note that a logical shift by 32 is handled by
3195 ;; the previous pattern.
3196 (define_insn "*<optab>_trunc<mode>_exts"
3197   [(set (match_operand:SUBDI 0 "register_operand" "=d")
3198         (truncate:SUBDI
3199          (any_shiftrt:DI (match_operand:DI 1 "register_operand" "d")
3200                          (match_operand:DI 2 "const_arith_operand" ""))))]
3201   "ISA_HAS_EXTS && TARGET_64BIT && UINTVAL (operands[2]) < 32"
3202   "exts\t%0,%1,%2,31"
3203   [(set_attr "type" "arith")
3204    (set_attr "mode" "<MODE>")])
3207 ;;  ....................
3209 ;;      ZERO EXTENSION
3211 ;;  ....................
3213 ;; Extension insns.
3215 (define_expand "zero_extendsidi2"
3216   [(set (match_operand:DI 0 "register_operand")
3217         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3218   "TARGET_64BIT")
3220 (define_insn_and_split "*zero_extendsidi2"
3221   [(set (match_operand:DI 0 "register_operand" "=d,d")
3222         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,W")))]
3223   "TARGET_64BIT && !ISA_HAS_EXT_INS"
3224   "@
3225    #
3226    lwu\t%0,%1"
3227   "&& reload_completed && REG_P (operands[1])"
3228   [(set (match_dup 0)
3229         (ashift:DI (match_dup 1) (const_int 32)))
3230    (set (match_dup 0)
3231         (lshiftrt:DI (match_dup 0) (const_int 32)))]
3232   { operands[1] = gen_lowpart (DImode, operands[1]); }
3233   [(set_attr "move_type" "shift_shift,load")
3234    (set_attr "mode" "DI")])
3236 (define_insn "*zero_extendsidi2_dext"
3237   [(set (match_operand:DI 0 "register_operand" "=d,d")
3238         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,W")))]
3239   "TARGET_64BIT && ISA_HAS_EXT_INS"
3240   "@
3241    dext\t%0,%1,0,32
3242    lwu\t%0,%1"
3243   [(set_attr "move_type" "arith,load")
3244    (set_attr "mode" "DI")])
3246 ;; See the comment before the *and<mode>3 pattern why this is generated by
3247 ;; combine.
3249 (define_split
3250   [(set (match_operand:DI 0 "register_operand")
3251         (and:DI (match_operand:DI 1 "register_operand")
3252                 (const_int 4294967295)))]
3253   "TARGET_64BIT && !ISA_HAS_EXT_INS && reload_completed"
3254   [(set (match_dup 0)
3255         (ashift:DI (match_dup 1) (const_int 32)))
3256    (set (match_dup 0)
3257         (lshiftrt:DI (match_dup 0) (const_int 32)))])
3259 (define_expand "zero_extend<SHORT:mode><GPR:mode>2"
3260   [(set (match_operand:GPR 0 "register_operand")
3261         (zero_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
3262   ""
3264   if (TARGET_MIPS16 && !GENERATE_MIPS16E
3265       && !memory_operand (operands[1], <SHORT:MODE>mode))
3266     {
3267       emit_insn (gen_and<GPR:mode>3 (operands[0],
3268                                      gen_lowpart (<GPR:MODE>mode, operands[1]),
3269                                      force_reg (<GPR:MODE>mode,
3270                                                 GEN_INT (<SHORT:mask>))));
3271       DONE;
3272     }
3275 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2"
3276   [(set (match_operand:GPR 0 "register_operand" "=!u,d,d")
3277         (zero_extend:GPR
3278              (match_operand:SHORT 1 "nonimmediate_operand" "!u,d,m")))]
3279   "!TARGET_MIPS16"
3280   "@
3281    andi\t%0,%1,<SHORT:mask>
3282    andi\t%0,%1,<SHORT:mask>
3283    l<SHORT:size>u\t%0,%1"
3284   [(set_attr "move_type" "andi,andi,load")
3285    (set_attr "compression" "micromips,*,*")
3286    (set_attr "mode" "<GPR:MODE>")])
3288 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16e"
3289   [(set (match_operand:GPR 0 "register_operand" "=d")
3290         (zero_extend:GPR (match_operand:SHORT 1 "register_operand" "0")))]
3291   "GENERATE_MIPS16E"
3292   "ze<SHORT:size>\t%0"
3293   ;; This instruction is effectively a special encoding of ANDI.
3294   [(set_attr "move_type" "andi")
3295    (set_attr "mode" "<GPR:MODE>")])
3297 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16"
3298   [(set (match_operand:GPR 0 "register_operand" "=d")
3299         (zero_extend:GPR (match_operand:SHORT 1 "memory_operand" "m")))]
3300   "TARGET_MIPS16"
3301   "l<SHORT:size>u\t%0,%1"
3302   [(set_attr "move_type" "load")
3303    (set_attr "mode" "<GPR:MODE>")])
3305 (define_expand "zero_extendqihi2"
3306   [(set (match_operand:HI 0 "register_operand")
3307         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3308   ""
3310   if (TARGET_MIPS16 && !memory_operand (operands[1], QImode))
3311     {
3312       emit_insn (gen_zero_extendqisi2 (gen_lowpart (SImode, operands[0]),
3313                                        operands[1]));
3314       DONE;
3315     }
3318 (define_insn "*zero_extendqihi2"
3319   [(set (match_operand:HI 0 "register_operand" "=d,d")
3320         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3321   "!TARGET_MIPS16"
3322   "@
3323    andi\t%0,%1,0x00ff
3324    lbu\t%0,%1"
3325   [(set_attr "move_type" "andi,load")
3326    (set_attr "mode" "HI")])
3328 (define_insn "*zero_extendqihi2_mips16"
3329   [(set (match_operand:HI 0 "register_operand" "=d")
3330         (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3331   "TARGET_MIPS16"
3332   "lbu\t%0,%1"
3333   [(set_attr "move_type" "load")
3334    (set_attr "mode" "HI")])
3336 ;; Combiner patterns to optimize truncate/zero_extend combinations.
3338 (define_insn "*zero_extend<GPR:mode>_trunc<SHORT:mode>"
3339   [(set (match_operand:GPR 0 "register_operand" "=d")
3340         (zero_extend:GPR
3341             (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
3342   "TARGET_64BIT && !TARGET_MIPS16"
3344   operands[2] = GEN_INT (GET_MODE_MASK (<SHORT:MODE>mode));
3345   return "andi\t%0,%1,%x2";
3347   [(set_attr "alu_type" "and")
3348    (set_attr "mode" "<GPR:MODE>")])
3350 (define_insn "*zero_extendhi_truncqi"
3351   [(set (match_operand:HI 0 "register_operand" "=d")
3352         (zero_extend:HI
3353             (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
3354   "TARGET_64BIT && !TARGET_MIPS16"
3355   "andi\t%0,%1,0xff"
3356   [(set_attr "alu_type" "and")
3357    (set_attr "mode" "HI")])
3360 ;;  ....................
3362 ;;      SIGN EXTENSION
3364 ;;  ....................
3366 ;; Extension insns.
3367 ;; Those for integer source operand are ordered widest source type first.
3369 ;; When TARGET_64BIT, all SImode integer and accumulator registers
3370 ;; should already be in sign-extended form (see TRULY_NOOP_TRUNCATION
3371 ;; and truncdisi2).  We can therefore get rid of register->register
3372 ;; instructions if we constrain the source to be in the same register as
3373 ;; the destination.
3375 ;; Only the pre-reload scheduler sees the type of the register alternatives;
3376 ;; we split them into nothing before the post-reload scheduler runs.
3377 ;; These alternatives therefore have type "move" in order to reflect
3378 ;; what happens if the two pre-reload operands cannot be tied, and are
3379 ;; instead allocated two separate GPRs.  We don't distinguish between
3380 ;; the GPR and LO cases because we don't usually know during pre-reload
3381 ;; scheduling whether an operand will be LO or not.
3382 (define_insn_and_split "extendsidi2"
3383   [(set (match_operand:DI 0 "register_operand" "=d,l,d")
3384         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,0,m")))]
3385   "TARGET_64BIT"
3386   "@
3387    #
3388    #
3389    lw\t%0,%1"
3390   "&& reload_completed && register_operand (operands[1], VOIDmode)"
3391   [(const_int 0)]
3393   emit_note (NOTE_INSN_DELETED);
3394   DONE;
3396   [(set_attr "move_type" "move,move,load")
3397    (set_attr "mode" "DI")])
3399 (define_expand "extend<SHORT:mode><GPR:mode>2"
3400   [(set (match_operand:GPR 0 "register_operand")
3401         (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
3402   "")
3404 (define_insn "*extend<SHORT:mode><GPR:mode>2_mips16e"
3405   [(set (match_operand:GPR 0 "register_operand" "=d,d")
3406         (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand" "0,m")))]
3407   "GENERATE_MIPS16E"
3408   "@
3409    se<SHORT:size>\t%0
3410    l<SHORT:size>\t%0,%1"
3411   [(set_attr "move_type" "signext,load")
3412    (set_attr "mode" "<GPR:MODE>")])
3414 (define_insn_and_split "*extend<SHORT:mode><GPR:mode>2"
3415   [(set (match_operand:GPR 0 "register_operand" "=d,d")
3416         (sign_extend:GPR
3417              (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
3418   "!ISA_HAS_SEB_SEH && !GENERATE_MIPS16E"
3419   "@
3420    #
3421    l<SHORT:size>\t%0,%1"
3422   "&& reload_completed && REG_P (operands[1])"
3423   [(set (match_dup 0) (ashift:GPR (match_dup 1) (match_dup 2)))
3424    (set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))]
3426   operands[1] = gen_lowpart (<GPR:MODE>mode, operands[1]);
3427   operands[2] = GEN_INT (GET_MODE_BITSIZE (<GPR:MODE>mode)
3428                          - GET_MODE_BITSIZE (<SHORT:MODE>mode));
3430   [(set_attr "move_type" "shift_shift,load")
3431    (set_attr "mode" "<GPR:MODE>")])
3433 (define_insn "*extend<SHORT:mode><GPR:mode>2_se<SHORT:size>"
3434   [(set (match_operand:GPR 0 "register_operand" "=d,d")
3435         (sign_extend:GPR
3436              (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
3437   "ISA_HAS_SEB_SEH"
3438   "@
3439    se<SHORT:size>\t%0,%1
3440    l<SHORT:size>\t%0,%1"
3441   [(set_attr "move_type" "signext,load")
3442    (set_attr "mode" "<GPR:MODE>")])
3444 (define_expand "extendqihi2"
3445   [(set (match_operand:HI 0 "register_operand")
3446         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3447   "")
3449 (define_insn "*extendqihi2_mips16e"
3450   [(set (match_operand:HI 0 "register_operand" "=d,d")
3451         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,m")))]
3452   "GENERATE_MIPS16E"
3453   "@
3454    seb\t%0
3455    lb\t%0,%1"
3456   [(set_attr "move_type" "signext,load")
3457    (set_attr "mode" "SI")])
3459 (define_insn_and_split "*extendqihi2"
3460   [(set (match_operand:HI 0 "register_operand" "=d,d")
3461         (sign_extend:HI
3462              (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3463   "!ISA_HAS_SEB_SEH && !GENERATE_MIPS16E"
3464   "@
3465    #
3466    lb\t%0,%1"
3467   "&& reload_completed && REG_P (operands[1])"
3468   [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
3469    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
3471   operands[0] = gen_lowpart (SImode, operands[0]);
3472   operands[1] = gen_lowpart (SImode, operands[1]);
3473   operands[2] = GEN_INT (GET_MODE_BITSIZE (SImode)
3474                          - GET_MODE_BITSIZE (QImode));
3476   [(set_attr "move_type" "shift_shift,load")
3477    (set_attr "mode" "SI")])
3479 (define_insn "*extendqihi2_seb"
3480   [(set (match_operand:HI 0 "register_operand" "=d,d")
3481         (sign_extend:HI
3482              (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3483   "ISA_HAS_SEB_SEH"
3484   "@
3485    seb\t%0,%1
3486    lb\t%0,%1"
3487   [(set_attr "move_type" "signext,load")
3488    (set_attr "mode" "SI")])
3490 ;; Combiner patterns for truncate/sign_extend combinations.  The SI versions
3491 ;; use the shift/truncate patterns.
3493 (define_insn_and_split "*extenddi_truncate<mode>"
3494   [(set (match_operand:DI 0 "register_operand" "=d")
3495         (sign_extend:DI
3496             (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
3497   "TARGET_64BIT && !TARGET_MIPS16 && !ISA_HAS_EXTS"
3498   "#"
3499   "&& reload_completed"
3500   [(set (match_dup 2)
3501         (ashift:DI (match_dup 1)
3502                    (match_dup 3)))
3503    (set (match_dup 0)
3504         (ashiftrt:DI (match_dup 2)
3505                      (match_dup 3)))]
3507   operands[2] = gen_lowpart (DImode, operands[0]);
3508   operands[3] = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (<MODE>mode));
3510   [(set_attr "move_type" "shift_shift")
3511    (set_attr "mode" "DI")])
3513 (define_insn_and_split "*extendsi_truncate<mode>"
3514   [(set (match_operand:SI 0 "register_operand" "=d")
3515         (sign_extend:SI
3516             (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
3517   "TARGET_64BIT && !TARGET_MIPS16 && !ISA_HAS_EXTS"
3518   "#"
3519   "&& reload_completed"
3520   [(set (match_dup 2)
3521         (ashift:DI (match_dup 1)
3522                    (match_dup 3)))
3523    (set (match_dup 0)
3524         (truncate:SI (ashiftrt:DI (match_dup 2)
3525                                   (match_dup 3))))]
3527   operands[2] = gen_lowpart (DImode, operands[0]);
3528   operands[3] = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (<MODE>mode));
3530   [(set_attr "move_type" "shift_shift")
3531    (set_attr "mode" "SI")])
3533 (define_insn_and_split "*extendhi_truncateqi"
3534   [(set (match_operand:HI 0 "register_operand" "=d")
3535         (sign_extend:HI
3536             (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
3537   "TARGET_64BIT && !TARGET_MIPS16 && !ISA_HAS_EXTS"
3538   "#"
3539   "&& reload_completed"
3540   [(set (match_dup 2)
3541         (ashift:DI (match_dup 1)
3542                    (const_int 56)))
3543    (set (match_dup 0)
3544         (truncate:HI (ashiftrt:DI (match_dup 2)
3545                                   (const_int 56))))]
3547   operands[2] = gen_lowpart (DImode, operands[0]);
3549   [(set_attr "move_type" "shift_shift")
3550    (set_attr "mode" "SI")])
3552 (define_insn "*extend<GPR:mode>_truncate<SHORT:mode>_exts"
3553   [(set (match_operand:GPR 0 "register_operand" "=d")
3554         (sign_extend:GPR
3555             (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
3556   "TARGET_64BIT && !TARGET_MIPS16 && ISA_HAS_EXTS"
3558   operands[2] = GEN_INT (GET_MODE_BITSIZE (<SHORT:MODE>mode));
3559   return "exts\t%0,%1,0,%m2";
3561   [(set_attr "type" "arith")
3562    (set_attr "mode" "<GPR:MODE>")])
3564 (define_insn "*extendhi_truncateqi_exts"
3565   [(set (match_operand:HI 0 "register_operand" "=d")
3566         (sign_extend:HI
3567             (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
3568   "TARGET_64BIT && !TARGET_MIPS16 && ISA_HAS_EXTS"
3569   "exts\t%0,%1,0,7"
3570   [(set_attr "type" "arith")
3571    (set_attr "mode" "SI")])
3573 (define_insn "extendsfdf2"
3574   [(set (match_operand:DF 0 "register_operand" "=f")
3575         (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
3576   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3577   "cvt.d.s\t%0,%1"
3578   [(set_attr "type"     "fcvt")
3579    (set_attr "cnv_mode" "S2D")   
3580    (set_attr "mode"     "DF")])
3583 ;;  ....................
3585 ;;      CONVERSIONS
3587 ;;  ....................
3589 (define_expand "fix_truncdfsi2"
3590   [(set (match_operand:SI 0 "register_operand")
3591         (fix:SI (match_operand:DF 1 "register_operand")))]
3592   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3594   if (!ISA_HAS_TRUNC_W)
3595     {
3596       emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
3597       DONE;
3598     }
3601 (define_insn "fix_truncdfsi2_insn"
3602   [(set (match_operand:SI 0 "register_operand" "=f")
3603         (fix:SI (match_operand:DF 1 "register_operand" "f")))]
3604   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
3605   "trunc.w.d %0,%1"
3606   [(set_attr "type"     "fcvt")
3607    (set_attr "mode"     "DF")
3608    (set_attr "cnv_mode" "D2I")])
3610 (define_insn "fix_truncdfsi2_macro"
3611   [(set (match_operand:SI 0 "register_operand" "=f")
3612         (fix:SI (match_operand:DF 1 "register_operand" "f")))
3613    (clobber (match_scratch:DF 2 "=d"))]
3614   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
3616   if (mips_nomacro.nesting_level > 0)
3617     return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
3618   else
3619     return "trunc.w.d %0,%1,%2";
3621   [(set_attr "type"     "fcvt")
3622    (set_attr "mode"     "DF")
3623    (set_attr "cnv_mode" "D2I")
3624    (set_attr "insn_count" "9")])
3626 (define_expand "fix_truncsfsi2"
3627   [(set (match_operand:SI 0 "register_operand")
3628         (fix:SI (match_operand:SF 1 "register_operand")))]
3629   "TARGET_HARD_FLOAT"
3631   if (!ISA_HAS_TRUNC_W)
3632     {
3633       emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
3634       DONE;
3635     }
3638 (define_insn "fix_truncsfsi2_insn"
3639   [(set (match_operand:SI 0 "register_operand" "=f")
3640         (fix:SI (match_operand:SF 1 "register_operand" "f")))]
3641   "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
3642   "trunc.w.s %0,%1"
3643   [(set_attr "type"     "fcvt")
3644    (set_attr "mode"     "SF")
3645    (set_attr "cnv_mode" "S2I")])
3647 (define_insn "fix_truncsfsi2_macro"
3648   [(set (match_operand:SI 0 "register_operand" "=f")
3649         (fix:SI (match_operand:SF 1 "register_operand" "f")))
3650    (clobber (match_scratch:SF 2 "=d"))]
3651   "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
3653   if (mips_nomacro.nesting_level > 0)
3654     return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
3655   else
3656     return "trunc.w.s %0,%1,%2";
3658   [(set_attr "type"     "fcvt")
3659    (set_attr "mode"     "SF")
3660    (set_attr "cnv_mode" "S2I")
3661    (set_attr "insn_count" "9")])
3664 (define_insn "fix_truncdfdi2"
3665   [(set (match_operand:DI 0 "register_operand" "=f")
3666         (fix:DI (match_operand:DF 1 "register_operand" "f")))]
3667   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3668   "trunc.l.d %0,%1"
3669   [(set_attr "type"     "fcvt")
3670    (set_attr "mode"     "DF")
3671    (set_attr "cnv_mode" "D2I")])
3674 (define_insn "fix_truncsfdi2"
3675   [(set (match_operand:DI 0 "register_operand" "=f")
3676         (fix:DI (match_operand:SF 1 "register_operand" "f")))]
3677   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3678   "trunc.l.s %0,%1"
3679   [(set_attr "type"     "fcvt")
3680    (set_attr "mode"     "SF")
3681    (set_attr "cnv_mode" "S2I")])
3684 (define_insn "floatsidf2"
3685   [(set (match_operand:DF 0 "register_operand" "=f")
3686         (float:DF (match_operand:SI 1 "register_operand" "f")))]
3687   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3688   "cvt.d.w\t%0,%1"
3689   [(set_attr "type"     "fcvt")
3690    (set_attr "mode"     "DF")
3691    (set_attr "cnv_mode" "I2D")])
3694 (define_insn "floatdidf2"
3695   [(set (match_operand:DF 0 "register_operand" "=f")
3696         (float:DF (match_operand:DI 1 "register_operand" "f")))]
3697   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3698   "cvt.d.l\t%0,%1"
3699   [(set_attr "type"     "fcvt")
3700    (set_attr "mode"     "DF")
3701    (set_attr "cnv_mode" "I2D")])
3704 (define_insn "floatsisf2"
3705   [(set (match_operand:SF 0 "register_operand" "=f")
3706         (float:SF (match_operand:SI 1 "register_operand" "f")))]
3707   "TARGET_HARD_FLOAT"
3708   "cvt.s.w\t%0,%1"
3709   [(set_attr "type"     "fcvt")
3710    (set_attr "mode"     "SF")
3711    (set_attr "cnv_mode" "I2S")])
3714 (define_insn "floatdisf2"
3715   [(set (match_operand:SF 0 "register_operand" "=f")
3716         (float:SF (match_operand:DI 1 "register_operand" "f")))]
3717   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3718   "cvt.s.l\t%0,%1"
3719   [(set_attr "type"     "fcvt")
3720    (set_attr "mode"     "SF")
3721    (set_attr "cnv_mode" "I2S")])
3724 (define_expand "fixuns_truncdfsi2"
3725   [(set (match_operand:SI 0 "register_operand")
3726         (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
3727   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3729   rtx reg1 = gen_reg_rtx (DFmode);
3730   rtx reg2 = gen_reg_rtx (DFmode);
3731   rtx reg3 = gen_reg_rtx (SImode);
3732   rtx label1 = gen_label_rtx ();
3733   rtx label2 = gen_label_rtx ();
3734   rtx test;
3735   REAL_VALUE_TYPE offset;
3737   real_2expN (&offset, 31, DFmode);
3739   if (reg1)                     /* Turn off complaints about unreached code.  */
3740     {
3741       mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3742       do_pending_stack_adjust ();
3744       test = gen_rtx_GE (VOIDmode, operands[1], reg1);
3745       emit_jump_insn (gen_cbranchdf4 (test, operands[1], reg1, label1));
3747       emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
3748       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3749                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
3750       emit_barrier ();
3752       emit_label (label1);
3753       mips_emit_move (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3754       mips_emit_move (reg3, GEN_INT (trunc_int_for_mode
3755                                      (BITMASK_HIGH, SImode)));
3757       emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
3758       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3760       emit_label (label2);
3762       /* Allow REG_NOTES to be set on last insn (labels don't have enough
3763          fields, and can't be used for REG_NOTES anyway).  */
3764       emit_use (stack_pointer_rtx);
3765       DONE;
3766     }
3770 (define_expand "fixuns_truncdfdi2"
3771   [(set (match_operand:DI 0 "register_operand")
3772         (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
3773   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3775   rtx reg1 = gen_reg_rtx (DFmode);
3776   rtx reg2 = gen_reg_rtx (DFmode);
3777   rtx reg3 = gen_reg_rtx (DImode);
3778   rtx label1 = gen_label_rtx ();
3779   rtx label2 = gen_label_rtx ();
3780   rtx test;
3781   REAL_VALUE_TYPE offset;
3783   real_2expN (&offset, 63, DFmode);
3785   mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3786   do_pending_stack_adjust ();
3788   test = gen_rtx_GE (VOIDmode, operands[1], reg1);
3789   emit_jump_insn (gen_cbranchdf4 (test, operands[1], reg1, label1));
3791   emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
3792   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3793                                gen_rtx_LABEL_REF (VOIDmode, label2)));
3794   emit_barrier ();
3796   emit_label (label1);
3797   mips_emit_move (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3798   mips_emit_move (reg3, GEN_INT (BITMASK_HIGH));
3799   emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3801   emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
3802   emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3804   emit_label (label2);
3806   /* Allow REG_NOTES to be set on last insn (labels don't have enough
3807      fields, and can't be used for REG_NOTES anyway).  */
3808   emit_use (stack_pointer_rtx);
3809   DONE;
3813 (define_expand "fixuns_truncsfsi2"
3814   [(set (match_operand:SI 0 "register_operand")
3815         (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
3816   "TARGET_HARD_FLOAT"
3818   rtx reg1 = gen_reg_rtx (SFmode);
3819   rtx reg2 = gen_reg_rtx (SFmode);
3820   rtx reg3 = gen_reg_rtx (SImode);
3821   rtx label1 = gen_label_rtx ();
3822   rtx label2 = gen_label_rtx ();
3823   rtx test;
3824   REAL_VALUE_TYPE offset;
3826   real_2expN (&offset, 31, SFmode);
3828   mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3829   do_pending_stack_adjust ();
3831   test = gen_rtx_GE (VOIDmode, operands[1], reg1);
3832   emit_jump_insn (gen_cbranchsf4 (test, operands[1], reg1, label1));
3834   emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
3835   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3836                                gen_rtx_LABEL_REF (VOIDmode, label2)));
3837   emit_barrier ();
3839   emit_label (label1);
3840   mips_emit_move (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3841   mips_emit_move (reg3, GEN_INT (trunc_int_for_mode
3842                                  (BITMASK_HIGH, SImode)));
3844   emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
3845   emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3847   emit_label (label2);
3849   /* Allow REG_NOTES to be set on last insn (labels don't have enough
3850      fields, and can't be used for REG_NOTES anyway).  */
3851   emit_use (stack_pointer_rtx);
3852   DONE;
3856 (define_expand "fixuns_truncsfdi2"
3857   [(set (match_operand:DI 0 "register_operand")
3858         (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
3859   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3861   rtx reg1 = gen_reg_rtx (SFmode);
3862   rtx reg2 = gen_reg_rtx (SFmode);
3863   rtx reg3 = gen_reg_rtx (DImode);
3864   rtx label1 = gen_label_rtx ();
3865   rtx label2 = gen_label_rtx ();
3866   rtx test;
3867   REAL_VALUE_TYPE offset;
3869   real_2expN (&offset, 63, SFmode);
3871   mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3872   do_pending_stack_adjust ();
3874   test = gen_rtx_GE (VOIDmode, operands[1], reg1);
3875   emit_jump_insn (gen_cbranchsf4 (test, operands[1], reg1, label1));
3877   emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
3878   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3879                                gen_rtx_LABEL_REF (VOIDmode, label2)));
3880   emit_barrier ();
3882   emit_label (label1);
3883   mips_emit_move (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3884   mips_emit_move (reg3, GEN_INT (BITMASK_HIGH));
3885   emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3887   emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
3888   emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3890   emit_label (label2);
3892   /* Allow REG_NOTES to be set on last insn (labels don't have enough
3893      fields, and can't be used for REG_NOTES anyway).  */
3894   emit_use (stack_pointer_rtx);
3895   DONE;
3899 ;;  ....................
3901 ;;      DATA MOVEMENT
3903 ;;  ....................
3905 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
3907 (define_expand "extvmisalign<mode>"
3908   [(set (match_operand:GPR 0 "register_operand")
3909         (sign_extract:GPR (match_operand:BLK 1 "memory_operand")
3910                           (match_operand 2 "const_int_operand")
3911                           (match_operand 3 "const_int_operand")))]
3912   "!TARGET_MIPS16"
3914   if (mips_expand_ext_as_unaligned_load (operands[0], operands[1],
3915                                          INTVAL (operands[2]),
3916                                          INTVAL (operands[3]),
3917                                          /*unsigned=*/ false))
3918     DONE;
3919   else
3920     FAIL;
3923 (define_expand "extv<mode>"
3924   [(set (match_operand:GPR 0 "register_operand")
3925         (sign_extract:GPR (match_operand:GPR 1 "register_operand")
3926                           (match_operand 2 "const_int_operand")
3927                           (match_operand 3 "const_int_operand")))]
3928   "ISA_HAS_EXTS"
3930   if (UINTVAL (operands[2]) > 32)
3931     FAIL;
3934 (define_insn "*extv<mode>"
3935   [(set (match_operand:GPR 0 "register_operand" "=d")
3936         (sign_extract:GPR (match_operand:GPR 1 "register_operand" "d")
3937                           (match_operand 2 "const_int_operand" "")
3938                           (match_operand 3 "const_int_operand" "")))]
3939   "ISA_HAS_EXTS && UINTVAL (operands[2]) <= 32"
3940   "exts\t%0,%1,%3,%m2"
3941   [(set_attr "type"     "arith")
3942    (set_attr "mode"     "<MODE>")])
3944 (define_expand "extzvmisalign<mode>"
3945   [(set (match_operand:GPR 0 "register_operand")
3946         (zero_extract:GPR (match_operand:BLK 1 "memory_operand")
3947                           (match_operand 2 "const_int_operand")
3948                           (match_operand 3 "const_int_operand")))]
3949   "!TARGET_MIPS16"
3951   if (mips_expand_ext_as_unaligned_load (operands[0], operands[1],
3952                                          INTVAL (operands[2]),
3953                                          INTVAL (operands[3]),
3954                                          /*unsigned=*/ true))
3955     DONE;
3956   else
3957     FAIL;
3960 (define_expand "extzv<mode>"
3961   [(set (match_operand:GPR 0 "register_operand")
3962         (zero_extract:GPR (match_operand:GPR 1 "register_operand")
3963                           (match_operand 2 "const_int_operand")
3964                           (match_operand 3 "const_int_operand")))]
3965   ""
3967   if (!mips_use_ins_ext_p (operands[1], INTVAL (operands[2]),
3968                            INTVAL (operands[3])))
3969     FAIL;
3972 (define_insn "*extzv<mode>"
3973   [(set (match_operand:GPR 0 "register_operand" "=d")
3974         (zero_extract:GPR (match_operand:GPR 1 "register_operand" "d")
3975                           (match_operand 2 "const_int_operand" "")
3976                           (match_operand 3 "const_int_operand" "")))]
3977   "mips_use_ins_ext_p (operands[1], INTVAL (operands[2]),
3978                        INTVAL (operands[3]))"
3979   "<d>ext\t%0,%1,%3,%2"
3980   [(set_attr "type"     "arith")
3981    (set_attr "mode"     "<MODE>")])
3983 (define_insn "*extzv_truncsi_exts"
3984   [(set (match_operand:SI 0 "register_operand" "=d")
3985         (truncate:SI
3986          (zero_extract:DI (match_operand:DI 1 "register_operand" "d")
3987                           (match_operand 2 "const_int_operand" "")
3988                           (match_operand 3 "const_int_operand" ""))))]
3989   "ISA_HAS_EXTS && TARGET_64BIT && IN_RANGE (INTVAL (operands[2]), 32, 63)"
3990   "exts\t%0,%1,%3,31"
3991   [(set_attr "type"     "arith")
3992    (set_attr "mode"     "SI")])
3995 (define_expand "insvmisalign<mode>"
3996   [(set (zero_extract:GPR (match_operand:BLK 0 "memory_operand")
3997                           (match_operand 1 "const_int_operand")
3998                           (match_operand 2 "const_int_operand"))
3999         (match_operand:GPR 3 "reg_or_0_operand"))]
4000   "!TARGET_MIPS16"
4002   if (mips_expand_ins_as_unaligned_store (operands[0], operands[3],
4003                                           INTVAL (operands[1]),
4004                                           INTVAL (operands[2])))
4005     DONE;
4006   else
4007     FAIL;
4010 (define_expand "insv<mode>"
4011   [(set (zero_extract:GPR (match_operand:GPR 0 "register_operand")
4012                           (match_operand 1 "const_int_operand")
4013                           (match_operand 2 "const_int_operand"))
4014         (match_operand:GPR 3 "reg_or_0_operand"))]
4015   ""
4017   if (!mips_use_ins_ext_p (operands[0], INTVAL (operands[1]),
4018                            INTVAL (operands[2])))
4019     FAIL;
4022 (define_insn "*insv<mode>"
4023   [(set (zero_extract:GPR (match_operand:GPR 0 "register_operand" "+d")
4024                           (match_operand:SI 1 "const_int_operand" "")
4025                           (match_operand:SI 2 "const_int_operand" ""))
4026         (match_operand:GPR 3 "reg_or_0_operand" "dJ"))]
4027   "mips_use_ins_ext_p (operands[0], INTVAL (operands[1]),
4028                        INTVAL (operands[2]))"
4029   "<d>ins\t%0,%z3,%2,%1"
4030   [(set_attr "type"     "arith")
4031    (set_attr "mode"     "<MODE>")])
4033 ;; Combiner pattern for cins (clear and insert bit field).  We can
4034 ;; implement mask-and-shift-left operation with this.  Note that if
4035 ;; the upper bit of the mask is set in an SImode operation, the mask
4036 ;; itself will be sign-extended.  mask_low_and_shift_len will
4037 ;; therefore be greater than our threshold of 32.
4039 (define_insn "*cins<mode>"
4040   [(set (match_operand:GPR 0 "register_operand" "=d")
4041         (and:GPR
4042          (ashift:GPR (match_operand:GPR 1 "register_operand" "d")
4043                      (match_operand:GPR 2 "const_int_operand" ""))
4044          (match_operand:GPR 3 "const_int_operand" "")))]
4045   "ISA_HAS_CINS
4046    && mask_low_and_shift_p (<MODE>mode, operands[3], operands[2], 32)"
4048   operands[3] =
4049     GEN_INT (mask_low_and_shift_len (<MODE>mode, operands[3], operands[2]));
4050   return "cins\t%0,%1,%2,%m3";
4052   [(set_attr "type"     "shift")
4053    (set_attr "mode"     "<MODE>")])
4055 ;; Unaligned word moves generated by the bit field patterns.
4057 ;; As far as the rtl is concerned, both the left-part and right-part
4058 ;; instructions can access the whole field.  However, the real operand
4059 ;; refers to just the first or the last byte (depending on endianness).
4060 ;; We therefore use two memory operands to each instruction, one to
4061 ;; describe the rtl effect and one to use in the assembly output.
4063 ;; Operands 0 and 1 are the rtl-level target and source respectively.
4064 ;; This allows us to use the standard length calculations for the "load"
4065 ;; and "store" type attributes.
4067 (define_insn "mov_<load>l"
4068   [(set (match_operand:GPR 0 "register_operand" "=d")
4069         (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
4070                      (match_operand:QI 2 "memory_operand" "ZC")]
4071                     UNSPEC_LOAD_LEFT))]
4072   "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
4073   "<load>l\t%0,%2"
4074   [(set_attr "move_type" "load")
4075    (set_attr "mode" "<MODE>")])
4077 (define_insn "mov_<load>r"
4078   [(set (match_operand:GPR 0 "register_operand" "=d")
4079         (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
4080                      (match_operand:QI 2 "memory_operand" "ZC")
4081                      (match_operand:GPR 3 "register_operand" "0")]
4082                     UNSPEC_LOAD_RIGHT))]
4083   "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
4084   "<load>r\t%0,%2"
4085   [(set_attr "move_type" "load")
4086    (set_attr "mode" "<MODE>")])
4088 (define_insn "mov_<store>l"
4089   [(set (match_operand:BLK 0 "memory_operand" "=m")
4090         (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
4091                      (match_operand:QI 2 "memory_operand" "ZC")]
4092                     UNSPEC_STORE_LEFT))]
4093   "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
4094   "<store>l\t%z1,%2"
4095   [(set_attr "move_type" "store")
4096    (set_attr "mode" "<MODE>")])
4098 (define_insn "mov_<store>r"
4099   [(set (match_operand:BLK 0 "memory_operand" "+m")
4100         (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
4101                      (match_operand:QI 2 "memory_operand" "ZC")
4102                      (match_dup 0)]
4103                     UNSPEC_STORE_RIGHT))]
4104   "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
4105   "<store>r\t%z1,%2"
4106   [(set_attr "move_type" "store")
4107    (set_attr "mode" "<MODE>")])
4109 ;; An instruction to calculate the high part of a 64-bit SYMBOL_ABSOLUTE.
4110 ;; The required value is:
4112 ;;      (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
4114 ;; which translates to:
4116 ;;      lui     op0,%highest(op1)
4117 ;;      daddiu  op0,op0,%higher(op1)
4118 ;;      dsll    op0,op0,16
4119 ;;      daddiu  op0,op0,%hi(op1)
4120 ;;      dsll    op0,op0,16
4122 ;; The split is deferred until after flow2 to allow the peephole2 below
4123 ;; to take effect.
4124 (define_insn_and_split "*lea_high64"
4125   [(set (match_operand:DI 0 "register_operand" "=d")
4126         (high:DI (match_operand:DI 1 "absolute_symbolic_operand" "")))]
4127   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
4128   "#"
4129   "&& epilogue_completed"
4130   [(set (match_dup 0) (high:DI (match_dup 2)))
4131    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
4132    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
4133    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
4134    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
4136   operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
4137   operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
4139   [(set_attr "insn_count" "5")])
4141 ;; Use a scratch register to reduce the latency of the above pattern
4142 ;; on superscalar machines.  The optimized sequence is:
4144 ;;      lui     op1,%highest(op2)
4145 ;;      lui     op0,%hi(op2)
4146 ;;      daddiu  op1,op1,%higher(op2)
4147 ;;      dsll32  op1,op1,0
4148 ;;      daddu   op1,op1,op0
4149 (define_peephole2
4150   [(set (match_operand:DI 1 "d_operand")
4151         (high:DI (match_operand:DI 2 "absolute_symbolic_operand")))
4152    (match_scratch:DI 0 "d")]
4153   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
4154   [(set (match_dup 1) (high:DI (match_dup 3)))
4155    (set (match_dup 0) (high:DI (match_dup 4)))
4156    (set (match_dup 1) (lo_sum:DI (match_dup 1) (match_dup 3)))
4157    (set (match_dup 1) (ashift:DI (match_dup 1) (const_int 32)))
4158    (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 0)))]
4160   operands[3] = mips_unspec_address (operands[2], SYMBOL_64_HIGH);
4161   operands[4] = mips_unspec_address (operands[2], SYMBOL_64_LOW);
4164 ;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
4165 ;; SYMBOL_ABSOLUTE X will take 6 cycles.  This next pattern allows combine
4166 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
4167 ;; used once.  We can then use the sequence:
4169 ;;      lui     op0,%highest(op1)
4170 ;;      lui     op2,%hi(op1)
4171 ;;      daddiu  op0,op0,%higher(op1)
4172 ;;      daddiu  op2,op2,%lo(op1)
4173 ;;      dsll32  op0,op0,0
4174 ;;      daddu   op0,op0,op2
4176 ;; which takes 4 cycles on most superscalar targets.
4177 (define_insn_and_split "*lea64"
4178   [(set (match_operand:DI 0 "register_operand" "=d")
4179         (match_operand:DI 1 "absolute_symbolic_operand" ""))
4180    (clobber (match_scratch:DI 2 "=&d"))]
4181   "!TARGET_MIPS16
4182    && TARGET_EXPLICIT_RELOCS
4183    && ABI_HAS_64BIT_SYMBOLS
4184    && cse_not_expected"
4185   "#"
4186   "&& reload_completed"
4187   [(set (match_dup 0) (high:DI (match_dup 3)))
4188    (set (match_dup 2) (high:DI (match_dup 4)))
4189    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
4190    (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
4191    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
4192    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
4194   operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
4195   operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
4197   [(set_attr "insn_count" "6")])
4199 ;; Split HIGHs into:
4201 ;;      li op0,%hi(sym)
4202 ;;      sll op0,16
4204 ;; on MIPS16 targets.
4205 (define_split
4206   [(set (match_operand:P 0 "d_operand")
4207         (high:P (match_operand:P 1 "symbolic_operand_with_high")))]
4208   "TARGET_MIPS16 && reload_completed"
4209   [(set (match_dup 0) (unspec:P [(match_dup 1)] UNSPEC_UNSHIFTED_HIGH))
4210    (set (match_dup 0) (ashift:P (match_dup 0) (const_int 16)))])
4212 (define_insn "*unshifted_high"
4213   [(set (match_operand:P 0 "d_operand" "=d")
4214         (unspec:P [(match_operand:P 1 "symbolic_operand_with_high")]
4215                   UNSPEC_UNSHIFTED_HIGH))]
4216   ""
4217   "li\t%0,%h1"
4218   [(set_attr "extended_mips16" "yes")])
4220 ;; Insns to fetch a symbol from a big GOT.
4222 (define_insn_and_split "*xgot_hi<mode>"
4223   [(set (match_operand:P 0 "register_operand" "=d")
4224         (high:P (match_operand:P 1 "got_disp_operand" "")))]
4225   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
4226   "#"
4227   "&& reload_completed"
4228   [(set (match_dup 0) (high:P (match_dup 2)))
4229    (set (match_dup 0) (plus:P (match_dup 0) (match_dup 3)))]
4231   operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_DISP);
4232   operands[3] = pic_offset_table_rtx;
4234   [(set_attr "got" "xgot_high")
4235    (set_attr "mode" "<MODE>")])
4237 (define_insn_and_split "*xgot_lo<mode>"
4238   [(set (match_operand:P 0 "register_operand" "=d")
4239         (lo_sum:P (match_operand:P 1 "register_operand" "d")
4240                   (match_operand:P 2 "got_disp_operand" "")))]
4241   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
4242   "#"
4243   "&& reload_completed"
4244   [(set (match_dup 0)
4245         (unspec:P [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
4246   { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_DISP); }
4247   [(set_attr "got" "load")
4248    (set_attr "mode" "<MODE>")])
4250 ;; Insns to fetch a symbol from a normal GOT.
4252 (define_insn_and_split "*got_disp<mode>"
4253   [(set (match_operand:P 0 "register_operand" "=d")
4254         (match_operand:P 1 "got_disp_operand" ""))]
4255   "TARGET_EXPLICIT_RELOCS && !mips_split_p[SYMBOL_GOT_DISP]"
4256   "#"
4257   "&& reload_completed"
4258   [(set (match_dup 0) (match_dup 2))]
4259   { operands[2] = mips_got_load (NULL, operands[1], SYMBOL_GOTOFF_DISP); }
4260   [(set_attr "got" "load")
4261    (set_attr "mode" "<MODE>")])
4263 ;; Insns for loading the "page" part of a page/ofst address from the GOT.
4265 (define_insn_and_split "*got_page<mode>"
4266   [(set (match_operand:P 0 "register_operand" "=d")
4267         (high:P (match_operand:P 1 "got_page_ofst_operand" "")))]
4268   "TARGET_EXPLICIT_RELOCS && !mips_split_hi_p[SYMBOL_GOT_PAGE_OFST]"
4269   "#"
4270   "&& reload_completed"
4271   [(set (match_dup 0) (match_dup 2))]
4272   { operands[2] = mips_got_load (NULL, operands[1], SYMBOL_GOTOFF_PAGE); }
4273   [(set_attr "got" "load")
4274    (set_attr "mode" "<MODE>")])
4276 ;; Convenience expander that generates the rhs of a load_got<mode> insn.
4277 (define_expand "unspec_got_<mode>"
4278   [(unspec:P [(match_operand:P 0)
4279               (match_operand:P 1)] UNSPEC_LOAD_GOT)])
4281 ;; Lower-level instructions for loading an address from the GOT.
4282 ;; We could use MEMs, but an unspec gives more optimization
4283 ;; opportunities.
4285 (define_insn "load_got<mode>"
4286   [(set (match_operand:P 0 "register_operand" "=d")
4287         (unspec:P [(match_operand:P 1 "register_operand" "d")
4288                    (match_operand:P 2 "immediate_operand" "")]
4289                   UNSPEC_LOAD_GOT))]
4290   ""
4291   "<load>\t%0,%R2(%1)"
4292   [(set_attr "got" "load")
4293    (set_attr "mode" "<MODE>")])
4295 ;; Instructions for adding the low 16 bits of an address to a register.
4296 ;; Operand 2 is the address: mips_print_operand works out which relocation
4297 ;; should be applied.
4299 (define_insn "*low<mode>"
4300   [(set (match_operand:P 0 "register_operand" "=d")
4301         (lo_sum:P (match_operand:P 1 "register_operand" "d")
4302                   (match_operand:P 2 "immediate_operand" "")))]
4303   "!TARGET_MIPS16"
4304   "<d>addiu\t%0,%1,%R2"
4305   [(set_attr "alu_type" "add")
4306    (set_attr "mode" "<MODE>")])
4308 (define_insn "*low<mode>_mips16"
4309   [(set (match_operand:P 0 "register_operand" "=d")
4310         (lo_sum:P (match_operand:P 1 "register_operand" "0")
4311                   (match_operand:P 2 "immediate_operand" "")))]
4312   "TARGET_MIPS16"
4313   "<d>addiu\t%0,%R2"
4314   [(set_attr "alu_type" "add")
4315    (set_attr "mode" "<MODE>")
4316    (set_attr "extended_mips16" "yes")])
4318 ;; Expose MIPS16 uses of the global pointer after reload if the function
4319 ;; is responsible for setting up the register itself.
4320 (define_split
4321   [(set (match_operand:GPR 0 "d_operand")
4322         (const:GPR (unspec:GPR [(const_int 0)] UNSPEC_GP)))]
4323   "TARGET_MIPS16 && TARGET_USE_GOT && reload_completed"
4324   [(set (match_dup 0) (match_dup 1))]
4325   { operands[1] = pic_offset_table_rtx; })
4327 ;; Allow combine to split complex const_int load sequences, using operand 2
4328 ;; to store the intermediate results.  See move_operand for details.
4329 (define_split
4330   [(set (match_operand:GPR 0 "register_operand")
4331         (match_operand:GPR 1 "splittable_const_int_operand"))
4332    (clobber (match_operand:GPR 2 "register_operand"))]
4333   ""
4334   [(const_int 0)]
4336   mips_move_integer (operands[2], operands[0], INTVAL (operands[1]));
4337   DONE;
4340 ;; Likewise, for symbolic operands.
4341 (define_split
4342   [(set (match_operand:P 0 "register_operand")
4343         (match_operand:P 1))
4344    (clobber (match_operand:P 2 "register_operand"))]
4345   "mips_split_symbol (operands[2], operands[1], MAX_MACHINE_MODE, NULL)"
4346   [(set (match_dup 0) (match_dup 3))]
4348   mips_split_symbol (operands[2], operands[1],
4349                      MAX_MACHINE_MODE, &operands[3]);
4352 ;; 64-bit integer moves
4354 ;; Unlike most other insns, the move insns can't be split with
4355 ;; different predicates, because register spilling and other parts of
4356 ;; the compiler, have memoized the insn number already.
4358 (define_expand "movdi"
4359   [(set (match_operand:DI 0 "")
4360         (match_operand:DI 1 ""))]
4361   ""
4363   if (mips_legitimize_move (DImode, operands[0], operands[1]))
4364     DONE;
4367 ;; For mips16, we need a special case to handle storing $31 into
4368 ;; memory, since we don't have a constraint to match $31.  This
4369 ;; instruction can be generated by save_restore_insns.
4371 (define_insn "*mov<mode>_ra"
4372   [(set (match_operand:GPR 0 "stack_operand" "=m")
4373         (reg:GPR RETURN_ADDR_REGNUM))]
4374   "TARGET_MIPS16"
4375   "<store>\t$31,%0"
4376   [(set_attr "move_type" "store")
4377    (set_attr "mode" "<MODE>")])
4379 (define_insn "*movdi_32bit"
4380   [(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")
4381         (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"))]
4382   "!TARGET_64BIT && !TARGET_MIPS16
4383    && (register_operand (operands[0], DImode)
4384        || reg_or_0_operand (operands[1], DImode))"
4385   { return mips_output_move (operands[0], operands[1]); }
4386   [(set_attr "move_type" "move,const,load,store,imul,mtlo,mflo,mtc,fpload,mfc,fpstore,mtc,fpload,mfc,fpstore")
4387    (set (attr "mode")
4388         (if_then_else (eq_attr "move_type" "imul")
4389                       (const_string "SI")
4390                       (const_string "DI")))])
4392 (define_insn "*movdi_32bit_mips16"
4393   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4394         (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
4395   "!TARGET_64BIT && TARGET_MIPS16
4396    && (register_operand (operands[0], DImode)
4397        || register_operand (operands[1], DImode))"
4398   { return mips_output_move (operands[0], operands[1]); }
4399   [(set_attr "move_type" "move,move,move,const,constN,load,store,mflo")
4400    (set_attr "mode" "DI")])
4402 (define_insn "*movdi_64bit"
4403   [(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")
4404         (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"))]
4405   "TARGET_64BIT && !TARGET_MIPS16
4406    && (register_operand (operands[0], DImode)
4407        || reg_or_0_operand (operands[1], DImode))"
4408   { return mips_output_move (operands[0], operands[1]); }
4409   [(set_attr "move_type" "move,const,const,load,store,mtc,fpload,mfc,fpstore,mtlo,mflo,mtc,fpload,mfc,fpstore")
4410    (set_attr "mode" "DI")])
4412 (define_insn "*movdi_64bit_mips16"
4413   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,m,*d")
4414         (match_operand:DI 1 "move_operand" "d,d,y,K,N,Yd,kf,m,d,*a"))]
4415   "TARGET_64BIT && TARGET_MIPS16
4416    && (register_operand (operands[0], DImode)
4417        || register_operand (operands[1], DImode))"
4418   { return mips_output_move (operands[0], operands[1]); }
4419   [(set_attr "move_type" "move,move,move,const,constN,const,loadpool,load,store,mflo")
4420    (set_attr "mode" "DI")])
4422 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
4423 ;; when the original load is a 4 byte instruction but the add and the
4424 ;; load are 2 2 byte instructions.
4426 (define_split
4427   [(set (match_operand:DI 0 "d_operand")
4428         (mem:DI (plus:DI (match_dup 0)
4429                          (match_operand:DI 1 "const_int_operand"))))]
4430   "TARGET_64BIT && TARGET_MIPS16 && reload_completed
4431    && !TARGET_DEBUG_D_MODE
4432    && ((INTVAL (operands[1]) < 0
4433         && INTVAL (operands[1]) >= -0x10)
4434        || (INTVAL (operands[1]) >= 32 * 8
4435            && INTVAL (operands[1]) <= 31 * 8 + 0x8)
4436        || (INTVAL (operands[1]) >= 0
4437            && INTVAL (operands[1]) < 32 * 8
4438            && (INTVAL (operands[1]) & 7) != 0))"
4439   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
4440    (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
4442   HOST_WIDE_INT val = INTVAL (operands[1]);
4444   if (val < 0)
4445     operands[2] = const0_rtx;
4446   else if (val >= 32 * 8)
4447     {
4448       int off = val & 7;
4450       operands[1] = GEN_INT (0x8 + off);
4451       operands[2] = GEN_INT (val - off - 0x8);
4452     }
4453   else
4454     {
4455       int off = val & 7;
4457       operands[1] = GEN_INT (off);
4458       operands[2] = GEN_INT (val - off);
4459     }
4462 ;; 32-bit Integer moves
4464 ;; Unlike most other insns, the move insns can't be split with
4465 ;; different predicates, because register spilling and other parts of
4466 ;; the compiler, have memoized the insn number already.
4468 (define_expand "mov<mode>"
4469   [(set (match_operand:IMOVE32 0 "")
4470         (match_operand:IMOVE32 1 ""))]
4471   ""
4473   if (mips_legitimize_move (<MODE>mode, operands[0], operands[1]))
4474     DONE;
4477 ;; The difference between these two is whether or not ints are allowed
4478 ;; in FP registers (off by default, use -mdebugh to enable).
4480 (define_insn "*mov<mode>_internal"
4481   [(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")
4482         (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"))]
4483   "!TARGET_MIPS16
4484    && (register_operand (operands[0], <MODE>mode)
4485        || reg_or_0_operand (operands[1], <MODE>mode))"
4486   { return mips_output_move (operands[0], operands[1]); }
4487   [(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")
4488    (set_attr "compression" "all,micromips,micromips,*,*,micromips,micromips,*,micromips,micromips,*,*,*,*,*,*,*,*,*,*,*,*,*")
4489    (set_attr "mode" "SI")])
4491 (define_insn "*mov<mode>_mips16"
4492   [(set (match_operand:IMOVE32 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,m,*d")
4493         (match_operand:IMOVE32 1 "move_operand" "d,d,y,K,N,Yd,kf,m,d,*a"))]
4494   "TARGET_MIPS16
4495    && (register_operand (operands[0], <MODE>mode)
4496        || register_operand (operands[1], <MODE>mode))"
4497   { return mips_output_move (operands[0], operands[1]); }
4498   [(set_attr "move_type" "move,move,move,const,constN,const,loadpool,load,store,mflo")
4499    (set_attr "mode" "SI")])
4501 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
4502 ;; when the original load is a 4 byte instruction but the add and the
4503 ;; load are 2 2 byte instructions.
4505 (define_split
4506   [(set (match_operand:SI 0 "d_operand")
4507         (mem:SI (plus:SI (match_dup 0)
4508                          (match_operand:SI 1 "const_int_operand"))))]
4509   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4510    && ((INTVAL (operands[1]) < 0
4511         && INTVAL (operands[1]) >= -0x80)
4512        || (INTVAL (operands[1]) >= 32 * 4
4513            && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
4514        || (INTVAL (operands[1]) >= 0
4515            && INTVAL (operands[1]) < 32 * 4
4516            && (INTVAL (operands[1]) & 3) != 0))"
4517   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4518    (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
4520   HOST_WIDE_INT val = INTVAL (operands[1]);
4522   if (val < 0)
4523     operands[2] = const0_rtx;
4524   else if (val >= 32 * 4)
4525     {
4526       int off = val & 3;
4528       operands[1] = GEN_INT (0x7c + off);
4529       operands[2] = GEN_INT (val - off - 0x7c);
4530     }
4531   else
4532     {
4533       int off = val & 3;
4535       operands[1] = GEN_INT (off);
4536       operands[2] = GEN_INT (val - off);
4537     }
4540 ;; On the mips16, we can split a load of certain constants into a load
4541 ;; and an add.  This turns a 4 byte instruction into 2 2 byte
4542 ;; instructions.
4544 (define_split
4545   [(set (match_operand:SI 0 "d_operand")
4546         (match_operand:SI 1 "const_int_operand"))]
4547   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4548    && INTVAL (operands[1]) >= 0x100
4549    && INTVAL (operands[1]) <= 0xff + 0x7f"
4550   [(set (match_dup 0) (match_dup 1))
4551    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
4553   int val = INTVAL (operands[1]);
4555   operands[1] = GEN_INT (0xff);
4556   operands[2] = GEN_INT (val - 0xff);
4559 ;; MIPS4 supports loading and storing a floating point register from
4560 ;; the sum of two general registers.  We use two versions for each of
4561 ;; these four instructions: one where the two general registers are
4562 ;; SImode, and one where they are DImode.  This is because general
4563 ;; registers will be in SImode when they hold 32-bit values, but,
4564 ;; since the 32-bit values are always sign extended, the [ls][wd]xc1
4565 ;; instructions will still work correctly.
4567 ;; ??? Perhaps it would be better to support these instructions by
4568 ;; modifying TARGET_LEGITIMATE_ADDRESS_P and friends.  However, since
4569 ;; these instructions can only be used to load and store floating
4570 ;; point registers, that would probably cause trouble in reload.
4572 (define_insn "*<ANYF:loadx>_<P:mode>"
4573   [(set (match_operand:ANYF 0 "register_operand" "=f")
4574         (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d")
4575                           (match_operand:P 2 "register_operand" "d"))))]
4576   "ISA_HAS_LXC1_SXC1"
4577   "<ANYF:loadx>\t%0,%1(%2)"
4578   [(set_attr "type" "fpidxload")
4579    (set_attr "mode" "<ANYF:UNITMODE>")])
4581 (define_insn "*<ANYF:storex>_<P:mode>"
4582   [(set (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d")
4583                           (match_operand:P 2 "register_operand" "d")))
4584         (match_operand:ANYF 0 "register_operand" "f"))]
4585   "ISA_HAS_LXC1_SXC1"
4586   "<ANYF:storex>\t%0,%1(%2)"
4587   [(set_attr "type" "fpidxstore")
4588    (set_attr "mode" "<ANYF:UNITMODE>")])
4590 ;; Scaled indexed address load.
4591 ;; Per md.texi, we only need to look for a pattern with multiply in the
4592 ;; address expression, not shift.
4594 (define_insn "*lwxs"
4595   [(set (match_operand:IMOVE32 0 "register_operand" "=d")
4596         (mem:IMOVE32
4597           (plus:P (mult:P (match_operand:P 1 "register_operand" "d")
4598                           (const_int 4))
4599                   (match_operand:P 2 "register_operand" "d"))))]
4600   "ISA_HAS_LWXS"
4601   "lwxs\t%0,%1(%2)"
4602   [(set_attr "type"     "load")
4603    (set_attr "mode"     "SI")])
4605 ;; 16-bit Integer moves
4607 ;; Unlike most other insns, the move insns can't be split with
4608 ;; different predicates, because register spilling and other parts of
4609 ;; the compiler, have memoized the insn number already.
4610 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4612 (define_expand "movhi"
4613   [(set (match_operand:HI 0 "")
4614         (match_operand:HI 1 ""))]
4615   ""
4617   if (mips_legitimize_move (HImode, operands[0], operands[1]))
4618     DONE;
4621 (define_insn "*movhi_internal"
4622   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,!u,d,!u,d,ZU,m,*a,*d")
4623         (match_operand:HI 1 "move_operand"         "d,J,I,ZU,m,!kbJ,dJ,*d*J,*a"))]
4624   "!TARGET_MIPS16
4625    && (register_operand (operands[0], HImode)
4626        || reg_or_0_operand (operands[1], HImode))"
4627   { return mips_output_move (operands[0], operands[1]); }
4628   [(set_attr "move_type" "move,const,const,load,load,store,store,mtlo,mflo")
4629    (set_attr "compression" "all,micromips,*,micromips,*,micromips,*,*,*")
4630    (set_attr "mode" "HI")])
4632 (define_insn "*movhi_mips16"
4633   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4634         (match_operand:HI 1 "move_operand"         "d,d,y,K,N,m,d,*a"))]
4635   "TARGET_MIPS16
4636    && (register_operand (operands[0], HImode)
4637        || register_operand (operands[1], HImode))"
4638   { return mips_output_move (operands[0], operands[1]); }
4639   [(set_attr "move_type" "move,move,move,const,constN,load,store,mflo")
4640    (set_attr "mode" "HI")])
4642 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
4643 ;; when the original load is a 4 byte instruction but the add and the
4644 ;; load are 2 2 byte instructions.
4646 (define_split
4647   [(set (match_operand:HI 0 "d_operand")
4648         (mem:HI (plus:SI (match_dup 0)
4649                          (match_operand:SI 1 "const_int_operand"))))]
4650   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4651    && ((INTVAL (operands[1]) < 0
4652         && INTVAL (operands[1]) >= -0x80)
4653        || (INTVAL (operands[1]) >= 32 * 2
4654            && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
4655        || (INTVAL (operands[1]) >= 0
4656            && INTVAL (operands[1]) < 32 * 2
4657            && (INTVAL (operands[1]) & 1) != 0))"
4658   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4659    (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
4661   HOST_WIDE_INT val = INTVAL (operands[1]);
4663   if (val < 0)
4664     operands[2] = const0_rtx;
4665   else if (val >= 32 * 2)
4666     {
4667       int off = val & 1;
4669       operands[1] = GEN_INT (0x7e + off);
4670       operands[2] = GEN_INT (val - off - 0x7e);
4671     }
4672   else
4673     {
4674       int off = val & 1;
4676       operands[1] = GEN_INT (off);
4677       operands[2] = GEN_INT (val - off);
4678     }
4681 ;; 8-bit Integer moves
4683 ;; Unlike most other insns, the move insns can't be split with
4684 ;; different predicates, because register spilling and other parts of
4685 ;; the compiler, have memoized the insn number already.
4686 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4688 (define_expand "movqi"
4689   [(set (match_operand:QI 0 "")
4690         (match_operand:QI 1 ""))]
4691   ""
4693   if (mips_legitimize_move (QImode, operands[0], operands[1]))
4694     DONE;
4697 (define_insn "*movqi_internal"
4698   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,!u,d,!u,d,ZV,m,*a,*d")
4699         (match_operand:QI 1 "move_operand"         "d,J,I,ZW,m,!kbJ,dJ,*d*J,*a"))]
4700   "!TARGET_MIPS16
4701    && (register_operand (operands[0], QImode)
4702        || reg_or_0_operand (operands[1], QImode))"
4703   { return mips_output_move (operands[0], operands[1]); }
4704   [(set_attr "move_type" "move,const,const,load,load,store,store,mtlo,mflo")
4705    (set_attr "compression" "all,micromips,*,micromips,*,micromips,*,*,*")
4706    (set_attr "mode" "QI")])
4708 (define_insn "*movqi_mips16"
4709   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4710         (match_operand:QI 1 "move_operand"         "d,d,y,K,N,m,d,*a"))]
4711   "TARGET_MIPS16
4712    && (register_operand (operands[0], QImode)
4713        || register_operand (operands[1], QImode))"
4714   { return mips_output_move (operands[0], operands[1]); }
4715   [(set_attr "move_type" "move,move,move,const,constN,load,store,mflo")
4716    (set_attr "mode" "QI")])
4718 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
4719 ;; when the original load is a 4 byte instruction but the add and the
4720 ;; load are 2 2 byte instructions.
4722 (define_split
4723   [(set (match_operand:QI 0 "d_operand")
4724         (mem:QI (plus:SI (match_dup 0)
4725                          (match_operand:SI 1 "const_int_operand"))))]
4726   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4727    && ((INTVAL (operands[1]) < 0
4728         && INTVAL (operands[1]) >= -0x80)
4729        || (INTVAL (operands[1]) >= 32
4730            && INTVAL (operands[1]) <= 31 + 0x7f))"
4731   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4732    (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
4734   HOST_WIDE_INT val = INTVAL (operands[1]);
4736   if (val < 0)
4737     operands[2] = const0_rtx;
4738   else
4739     {
4740       operands[1] = GEN_INT (0x7f);
4741       operands[2] = GEN_INT (val - 0x7f);
4742     }
4745 ;; 32-bit floating point moves
4747 (define_expand "movsf"
4748   [(set (match_operand:SF 0 "")
4749         (match_operand:SF 1 ""))]
4750   ""
4752   if (mips_legitimize_move (SFmode, operands[0], operands[1]))
4753     DONE;
4756 (define_insn "*movsf_hardfloat"
4757   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
4758         (match_operand:SF 1 "move_operand" "f,G,m,f,G,*d,*f,*G*d,*m,*d"))]
4759   "TARGET_HARD_FLOAT
4760    && (register_operand (operands[0], SFmode)
4761        || reg_or_0_operand (operands[1], SFmode))"
4762   { return mips_output_move (operands[0], operands[1]); }
4763   [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
4764    (set_attr "mode" "SF")])
4766 (define_insn "*movsf_softfloat"
4767   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
4768         (match_operand:SF 1 "move_operand" "Gd,m,d"))]
4769   "TARGET_SOFT_FLOAT && !TARGET_MIPS16
4770    && (register_operand (operands[0], SFmode)
4771        || reg_or_0_operand (operands[1], SFmode))"
4772   { return mips_output_move (operands[0], operands[1]); }
4773   [(set_attr "move_type" "move,load,store")
4774    (set_attr "mode" "SF")])
4776 (define_insn "*movsf_mips16"
4777   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
4778         (match_operand:SF 1 "move_operand" "d,d,y,m,d"))]
4779   "TARGET_MIPS16
4780    && (register_operand (operands[0], SFmode)
4781        || register_operand (operands[1], SFmode))"
4782   { return mips_output_move (operands[0], operands[1]); }
4783   [(set_attr "move_type" "move,move,move,load,store")
4784    (set_attr "mode" "SF")])
4786 ;; 64-bit floating point moves
4788 (define_expand "movdf"
4789   [(set (match_operand:DF 0 "")
4790         (match_operand:DF 1 ""))]
4791   ""
4793   if (mips_legitimize_move (DFmode, operands[0], operands[1]))
4794     DONE;
4797 (define_insn "*movdf_hardfloat"
4798   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
4799         (match_operand:DF 1 "move_operand" "f,G,m,f,G,*d,*f,*d*G,*m,*d"))]
4800   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
4801    && (register_operand (operands[0], DFmode)
4802        || reg_or_0_operand (operands[1], DFmode))"
4803   { return mips_output_move (operands[0], operands[1]); }
4804   [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
4805    (set_attr "mode" "DF")])
4807 (define_insn "*movdf_softfloat"
4808   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m")
4809         (match_operand:DF 1 "move_operand" "dG,m,dG"))]
4810   "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
4811    && (register_operand (operands[0], DFmode)
4812        || reg_or_0_operand (operands[1], DFmode))"
4813   { return mips_output_move (operands[0], operands[1]); }
4814   [(set_attr "move_type" "move,load,store")
4815    (set_attr "mode" "DF")])
4817 (define_insn "*movdf_mips16"
4818   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
4819         (match_operand:DF 1 "move_operand" "d,d,y,m,d"))]
4820   "TARGET_MIPS16
4821    && (register_operand (operands[0], DFmode)
4822        || register_operand (operands[1], DFmode))"
4823   { return mips_output_move (operands[0], operands[1]); }
4824   [(set_attr "move_type" "move,move,move,load,store")
4825    (set_attr "mode" "DF")])
4827 ;; 128-bit integer moves
4829 (define_expand "movti"
4830   [(set (match_operand:TI 0)
4831         (match_operand:TI 1))]
4832   "TARGET_64BIT"
4834   if (mips_legitimize_move (TImode, operands[0], operands[1]))
4835     DONE;
4838 (define_insn "*movti"
4839   [(set (match_operand:TI 0 "nonimmediate_operand" "=d,d,d,m,*a,*a,*d")
4840         (match_operand:TI 1 "move_operand" "d,i,m,dJ,*J,*d,*a"))]
4841   "TARGET_64BIT
4842    && !TARGET_MIPS16
4843    && (register_operand (operands[0], TImode)
4844        || reg_or_0_operand (operands[1], TImode))"
4845   { return mips_output_move (operands[0], operands[1]); }
4846   [(set_attr "move_type" "move,const,load,store,imul,mtlo,mflo")
4847    (set (attr "mode")
4848         (if_then_else (eq_attr "move_type" "imul")
4849                       (const_string "SI")
4850                       (const_string "TI")))])
4852 (define_insn "*movti_mips16"
4853   [(set (match_operand:TI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4854         (match_operand:TI 1 "move_operand" "d,d,y,K,N,m,d,*a"))]
4855   "TARGET_64BIT
4856    && TARGET_MIPS16
4857    && (register_operand (operands[0], TImode)
4858        || register_operand (operands[1], TImode))"
4859   "#"
4860   [(set_attr "move_type" "move,move,move,const,constN,load,store,mflo")
4861    (set_attr "mode" "TI")])
4863 ;; 128-bit floating point moves
4865 (define_expand "movtf"
4866   [(set (match_operand:TF 0)
4867         (match_operand:TF 1))]
4868   "TARGET_64BIT"
4870   if (mips_legitimize_move (TFmode, operands[0], operands[1]))
4871     DONE;
4874 ;; This pattern handles both hard- and soft-float cases.
4875 (define_insn "*movtf"
4876   [(set (match_operand:TF 0 "nonimmediate_operand" "=d,d,m,f,d,f,m")
4877         (match_operand:TF 1 "move_operand" "dG,m,dG,dG,f,m,f"))]
4878   "TARGET_64BIT
4879    && !TARGET_MIPS16
4880    && (register_operand (operands[0], TFmode)
4881        || reg_or_0_operand (operands[1], TFmode))"
4882   "#"
4883   [(set_attr "move_type" "move,load,store,mtc,mfc,fpload,fpstore")
4884    (set_attr "mode" "TF")])
4886 (define_insn "*movtf_mips16"
4887   [(set (match_operand:TF 0 "nonimmediate_operand" "=d,y,d,d,m")
4888         (match_operand:TF 1 "move_operand" "d,d,y,m,d"))]
4889   "TARGET_64BIT
4890    && TARGET_MIPS16
4891    && (register_operand (operands[0], TFmode)
4892        || register_operand (operands[1], TFmode))"
4893   "#"
4894   [(set_attr "move_type" "move,move,move,load,store")
4895    (set_attr "mode" "TF")])
4897 (define_split
4898   [(set (match_operand:MOVE64 0 "nonimmediate_operand")
4899         (match_operand:MOVE64 1 "move_operand"))]
4900   "reload_completed && mips_split_move_insn_p (operands[0], operands[1], insn)"
4901   [(const_int 0)]
4903   mips_split_move_insn (operands[0], operands[1], curr_insn);
4904   DONE;
4907 (define_split
4908   [(set (match_operand:MOVE128 0 "nonimmediate_operand")
4909         (match_operand:MOVE128 1 "move_operand"))]
4910   "reload_completed && mips_split_move_insn_p (operands[0], operands[1], insn)"
4911   [(const_int 0)]
4913   mips_split_move_insn (operands[0], operands[1], curr_insn);
4914   DONE;
4917 ;; When generating mips16 code, split moves of negative constants into
4918 ;; a positive "li" followed by a negation.
4919 (define_split
4920   [(set (match_operand 0 "d_operand")
4921         (match_operand 1 "const_int_operand"))]
4922   "TARGET_MIPS16 && reload_completed && INTVAL (operands[1]) < 0"
4923   [(set (match_dup 2)
4924         (match_dup 3))
4925    (set (match_dup 2)
4926         (neg:SI (match_dup 2)))]
4928   operands[2] = gen_lowpart (SImode, operands[0]);
4929   operands[3] = GEN_INT (-INTVAL (operands[1]));
4932 ;; 64-bit paired-single floating point moves
4934 (define_expand "movv2sf"
4935   [(set (match_operand:V2SF 0)
4936         (match_operand:V2SF 1))]
4937   "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
4939   if (mips_legitimize_move (V2SFmode, operands[0], operands[1]))
4940     DONE;
4943 (define_insn "*movv2sf"
4944   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
4945         (match_operand:V2SF 1 "move_operand" "f,YG,m,f,YG,*d,*f,*d*YG,*m,*d"))]
4946   "TARGET_HARD_FLOAT
4947    && TARGET_PAIRED_SINGLE_FLOAT
4948    && (register_operand (operands[0], V2SFmode)
4949        || reg_or_0_operand (operands[1], V2SFmode))"
4950   { return mips_output_move (operands[0], operands[1]); }
4951   [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
4952    (set_attr "mode" "DF")])
4954 ;; Extract the high part of a HI/LO value.  See mips_hard_regno_mode_ok_p
4955 ;; for the reason why we can't just use (reg:GPR HI_REGNUM).
4957 ;; When generating VR4120 or VR4130 code, we use MACCHI and DMACCHI
4958 ;; instead of MFHI.  This avoids both the normal MIPS III hi/lo hazards
4959 ;; and the errata related to -mfix-vr4130.
4960 (define_insn "mfhi<GPR:mode>_<HILO:mode>"
4961   [(set (match_operand:GPR 0 "register_operand" "=d")
4962         (unspec:GPR [(match_operand:HILO 1 "hilo_operand" "x")]
4963                     UNSPEC_MFHI))]
4964   ""
4965   { return ISA_HAS_MACCHI ? "<GPR:d>macchi\t%0,%.,%." : "mfhi\t%0"; }
4966   [(set_attr "type" "mfhi")
4967    (set_attr "mode" "<GPR:MODE>")])
4969 ;; Set the high part of a HI/LO value, given that the low part has
4970 ;; already been set.  See mips_hard_regno_mode_ok_p for the reason
4971 ;; why we can't just use (reg:GPR HI_REGNUM).
4972 (define_insn "mthi<GPR:mode>_<HILO:mode>"
4973   [(set (match_operand:HILO 0 "register_operand" "=x")
4974         (unspec:HILO [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
4975                       (match_operand:GPR 2 "register_operand" "l")]
4976                      UNSPEC_MTHI))]
4977   ""
4978   "mthi\t%z1"
4979   [(set_attr "type" "mthi")
4980    (set_attr "mode" "SI")])
4982 ;; Emit a doubleword move in which exactly one of the operands is
4983 ;; a floating-point register.  We can't just emit two normal moves
4984 ;; because of the constraints imposed by the FPU register model;
4985 ;; see mips_cannot_change_mode_class for details.  Instead, we keep
4986 ;; the FPR whole and use special patterns to refer to each word of
4987 ;; the other operand.
4989 (define_expand "move_doubleword_fpr<mode>"
4990   [(set (match_operand:SPLITF 0)
4991         (match_operand:SPLITF 1))]
4992   ""
4994   if (FP_REG_RTX_P (operands[0]))
4995     {
4996       rtx low = mips_subword (operands[1], 0);
4997       rtx high = mips_subword (operands[1], 1);
4998       emit_insn (gen_load_low<mode> (operands[0], low));
4999       if (TARGET_FLOAT64 && !TARGET_64BIT)
5000         emit_insn (gen_mthc1<mode> (operands[0], high, operands[0]));
5001       else
5002         emit_insn (gen_load_high<mode> (operands[0], high, operands[0]));
5003     }
5004   else
5005     {
5006       rtx low = mips_subword (operands[0], 0);
5007       rtx high = mips_subword (operands[0], 1);
5008       emit_insn (gen_store_word<mode> (low, operands[1], const0_rtx));
5009       if (TARGET_FLOAT64 && !TARGET_64BIT)
5010         emit_insn (gen_mfhc1<mode> (high, operands[1]));
5011       else
5012         emit_insn (gen_store_word<mode> (high, operands[1], const1_rtx));
5013     }
5014   DONE;
5017 ;; Load the low word of operand 0 with operand 1.
5018 (define_insn "load_low<mode>"
5019   [(set (match_operand:SPLITF 0 "register_operand" "=f,f")
5020         (unspec:SPLITF [(match_operand:<HALFMODE> 1 "general_operand" "dJ,m")]
5021                        UNSPEC_LOAD_LOW))]
5022   "TARGET_HARD_FLOAT"
5024   operands[0] = mips_subword (operands[0], 0);
5025   return mips_output_move (operands[0], operands[1]);
5027   [(set_attr "move_type" "mtc,fpload")
5028    (set_attr "mode" "<HALFMODE>")])
5030 ;; Load the high word of operand 0 from operand 1, preserving the value
5031 ;; in the low word.
5032 (define_insn "load_high<mode>"
5033   [(set (match_operand:SPLITF 0 "register_operand" "=f,f")
5034         (unspec:SPLITF [(match_operand:<HALFMODE> 1 "general_operand" "dJ,m")
5035                         (match_operand:SPLITF 2 "register_operand" "0,0")]
5036                        UNSPEC_LOAD_HIGH))]
5037   "TARGET_HARD_FLOAT"
5039   operands[0] = mips_subword (operands[0], 1);
5040   return mips_output_move (operands[0], operands[1]);
5042   [(set_attr "move_type" "mtc,fpload")
5043    (set_attr "mode" "<HALFMODE>")])
5045 ;; Store one word of operand 1 in operand 0.  Operand 2 is 1 to store the
5046 ;; high word and 0 to store the low word.
5047 (define_insn "store_word<mode>"
5048   [(set (match_operand:<HALFMODE> 0 "nonimmediate_operand" "=d,m")
5049         (unspec:<HALFMODE> [(match_operand:SPLITF 1 "register_operand" "f,f")
5050                             (match_operand 2 "const_int_operand")]
5051                            UNSPEC_STORE_WORD))]
5052   "TARGET_HARD_FLOAT"
5054   operands[1] = mips_subword (operands[1], INTVAL (operands[2]));
5055   return mips_output_move (operands[0], operands[1]);
5057   [(set_attr "move_type" "mfc,fpstore")
5058    (set_attr "mode" "<HALFMODE>")])
5060 ;; Move operand 1 to the high word of operand 0 using mthc1, preserving the
5061 ;; value in the low word.
5062 (define_insn "mthc1<mode>"
5063   [(set (match_operand:SPLITF 0 "register_operand" "=f")
5064         (unspec:SPLITF [(match_operand:<HALFMODE> 1 "reg_or_0_operand" "dJ")
5065                         (match_operand:SPLITF 2 "register_operand" "0")]
5066                        UNSPEC_MTHC1))]
5067   "TARGET_HARD_FLOAT && ISA_HAS_MXHC1"
5068   "mthc1\t%z1,%0"
5069   [(set_attr "move_type" "mtc")
5070    (set_attr "mode" "<HALFMODE>")])
5072 ;; Move high word of operand 1 to operand 0 using mfhc1.
5073 (define_insn "mfhc1<mode>"
5074   [(set (match_operand:<HALFMODE> 0 "register_operand" "=d")
5075         (unspec:<HALFMODE> [(match_operand:SPLITF 1 "register_operand" "f")]
5076                             UNSPEC_MFHC1))]
5077   "TARGET_HARD_FLOAT && ISA_HAS_MXHC1"
5078   "mfhc1\t%0,%1"
5079   [(set_attr "move_type" "mfc")
5080    (set_attr "mode" "<HALFMODE>")])
5082 ;; Move a constant that satisfies CONST_GP_P into operand 0.
5083 (define_expand "load_const_gp_<mode>"
5084   [(set (match_operand:P 0 "register_operand" "=d")
5085         (const:P (unspec:P [(const_int 0)] UNSPEC_GP)))])
5087 ;; Insn to initialize $gp for n32/n64 abicalls.  Operand 0 is the offset
5088 ;; of _gp from the start of this function.  Operand 1 is the incoming
5089 ;; function address.
5090 (define_insn_and_split "loadgp_newabi_<mode>"
5091   [(set (match_operand:P 0 "register_operand" "=&d")
5092         (unspec:P [(match_operand:P 1)
5093                    (match_operand:P 2 "register_operand" "d")]
5094                   UNSPEC_LOADGP))]
5095   "mips_current_loadgp_style () == LOADGP_NEWABI"
5096   { return mips_must_initialize_gp_p () ? "#" : ""; }
5097   "&& mips_must_initialize_gp_p ()"
5098   [(set (match_dup 0) (match_dup 3))
5099    (set (match_dup 0) (match_dup 4))
5100    (set (match_dup 0) (match_dup 5))]
5102   operands[3] = gen_rtx_HIGH (Pmode, operands[1]);
5103   operands[4] = gen_rtx_PLUS (Pmode, operands[0], operands[2]);
5104   operands[5] = gen_rtx_LO_SUM (Pmode, operands[0], operands[1]);
5106   [(set_attr "type" "ghost")])
5108 ;; Likewise, for -mno-shared code.  Operand 0 is the __gnu_local_gp symbol.
5109 (define_insn_and_split "loadgp_absolute_<mode>"
5110   [(set (match_operand:P 0 "register_operand" "=d")
5111         (unspec:P [(match_operand:P 1)] UNSPEC_LOADGP))]
5112   "mips_current_loadgp_style () == LOADGP_ABSOLUTE"
5113   { return mips_must_initialize_gp_p () ? "#" : ""; }
5114   "&& mips_must_initialize_gp_p ()"
5115   [(const_int 0)]
5117   mips_emit_move (operands[0], operands[1]);
5118   DONE;
5120   [(set_attr "type" "ghost")])
5122 ;; This blockage instruction prevents the gp load from being
5123 ;; scheduled after an implicit use of gp.  It also prevents
5124 ;; the load from being deleted as dead.
5125 (define_insn "loadgp_blockage"
5126   [(unspec_volatile [(reg:SI 28)] UNSPEC_BLOCKAGE)]
5127   ""
5128   ""
5129   [(set_attr "type" "ghost")])
5131 ;; Initialize $gp for RTP PIC.  Operand 0 is the __GOTT_BASE__ symbol
5132 ;; and operand 1 is the __GOTT_INDEX__ symbol.
5133 (define_insn_and_split "loadgp_rtp_<mode>"
5134   [(set (match_operand:P 0 "register_operand" "=d")
5135         (unspec:P [(match_operand:P 1 "symbol_ref_operand")
5136                    (match_operand:P 2 "symbol_ref_operand")]
5137                   UNSPEC_LOADGP))]
5138   "mips_current_loadgp_style () == LOADGP_RTP"
5139   { return mips_must_initialize_gp_p () ? "#" : ""; }
5140   "&& mips_must_initialize_gp_p ()"
5141   [(set (match_dup 0) (high:P (match_dup 3)))
5142    (set (match_dup 0) (unspec:P [(match_dup 0)
5143                                  (match_dup 3)] UNSPEC_LOAD_GOT))
5144    (set (match_dup 0) (unspec:P [(match_dup 0)
5145                                  (match_dup 4)] UNSPEC_LOAD_GOT))]
5147   operands[3] = mips_unspec_address (operands[1], SYMBOL_ABSOLUTE);
5148   operands[4] = mips_unspec_address (operands[2], SYMBOL_HALF);
5150   [(set_attr "type" "ghost")])
5152 ;; Initialize the global pointer for MIPS16 code.  Operand 0 is the
5153 ;; global pointer and operand 1 is the MIPS16 register that holds
5154 ;; the required value.
5155 (define_insn_and_split "copygp_mips16_<mode>"
5156   [(set (match_operand:P 0 "register_operand" "=y")
5157         (unspec:P [(match_operand:P 1 "register_operand" "d")]
5158                   UNSPEC_COPYGP))]
5159   "TARGET_MIPS16"
5160   { return mips_must_initialize_gp_p () ? "#" : ""; }
5161   "&& mips_must_initialize_gp_p ()"
5162   [(set (match_dup 0) (match_dup 1))]
5163   ""
5164   [(set_attr "type" "ghost")])
5166 ;; A placeholder for where the cprestore instruction should go,
5167 ;; if we decide we need one.  Operand 0 and operand 1 are as for
5168 ;; "cprestore".  Operand 2 is a register that holds the gp value.
5170 ;; The "cprestore" pattern requires operand 2 to be pic_offset_table_rtx,
5171 ;; otherwise any register that holds the correct value will do.
5172 (define_insn_and_split "potential_cprestore_<mode>"
5173   [(set (match_operand:P 0 "cprestore_save_slot_operand" "=X,X")
5174         (unspec:P [(match_operand:P 1 "const_int_operand" "I,i")
5175                    (match_operand:P 2 "register_operand" "d,d")]
5176                   UNSPEC_POTENTIAL_CPRESTORE))
5177    (clobber (match_operand:P 3 "scratch_operand" "=X,&d"))]
5178   "!TARGET_CPRESTORE_DIRECTIVE || operands[2] == pic_offset_table_rtx"
5179   { return mips_must_initialize_gp_p () ? "#" : ""; }
5180   "mips_must_initialize_gp_p ()"
5181   [(const_int 0)]
5183   mips_save_gp_to_cprestore_slot (operands[0], operands[1],
5184                                   operands[2], operands[3]);
5185   DONE;
5187   [(set_attr "type" "ghost")])
5189 ;; Emit a .cprestore directive, which normally expands to a single store
5190 ;; instruction.  Operand 0 is a (possibly illegitimate) sp-based MEM
5191 ;; for the cprestore slot.  Operand 1 is the offset of the slot from
5192 ;; the stack pointer.  (This is redundant with operand 0, but it makes
5193 ;; things a little simpler.)
5194 (define_insn "cprestore_<mode>"
5195   [(set (match_operand:P 0 "cprestore_save_slot_operand" "=X,X")
5196         (unspec:P [(match_operand:P 1 "const_int_operand" "I,i")
5197                    (reg:P 28)]
5198                   UNSPEC_CPRESTORE))]
5199   "TARGET_CPRESTORE_DIRECTIVE"
5201   if (mips_nomacro.nesting_level > 0 && which_alternative == 1)
5202     return ".set\tmacro\;.cprestore\t%1\;.set\tnomacro";
5203   else
5204     return ".cprestore\t%1";
5206   [(set_attr "type" "store")
5207    (set_attr "insn_count" "1,3")])
5209 (define_insn "use_cprestore_<mode>"
5210   [(set (reg:P CPRESTORE_SLOT_REGNUM)
5211         (match_operand:P 0 "cprestore_load_slot_operand"))]
5212   ""
5213   ""
5214   [(set_attr "type" "ghost")])
5216 ;; Expand in-line code to clear the instruction cache between operand[0] and
5217 ;; operand[1].
5218 (define_expand "clear_cache"
5219   [(match_operand 0 "pmode_register_operand")
5220    (match_operand 1 "pmode_register_operand")]
5221   ""
5222   "
5224   if (TARGET_SYNCI)
5225     {
5226       mips_expand_synci_loop (operands[0], operands[1]);
5227       emit_insn (gen_sync ());
5228       emit_insn (PMODE_INSN (gen_clear_hazard, ()));
5229     }
5230   else if (mips_cache_flush_func && mips_cache_flush_func[0])
5231     {
5232       rtx len = gen_reg_rtx (Pmode);
5233       emit_insn (gen_sub3_insn (len, operands[1], operands[0]));
5234       MIPS_ICACHE_SYNC (operands[0], len);
5235     }
5236   DONE;
5239 (define_insn "sync"
5240   [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)]
5241   "GENERATE_SYNC"
5242   { return mips_output_sync (); })
5244 (define_insn "synci"
5245   [(unspec_volatile [(match_operand 0 "pmode_register_operand" "d")]
5246                     UNSPEC_SYNCI)]
5247   "TARGET_SYNCI"
5248   "synci\t0(%0)")
5250 (define_insn "rdhwr_synci_step_<mode>"
5251   [(set (match_operand:P 0 "register_operand" "=d")
5252         (unspec_volatile [(const_int 1)]
5253         UNSPEC_RDHWR))]
5254   "ISA_HAS_SYNCI"
5255   "rdhwr\t%0,$1")
5257 (define_insn "clear_hazard_<mode>"
5258   [(unspec_volatile [(const_int 0)] UNSPEC_CLEAR_HAZARD)
5259    (clobber (reg:P RETURN_ADDR_REGNUM))]
5260   "ISA_HAS_SYNCI"
5262   return "%(%<bal\t1f\n"
5263          "\tnop\n"
5264          "1:\t<d>addiu\t$31,$31,12\n"
5265          "\tjr.hb\t$31\n"
5266          "\tnop%>%)";
5268   [(set_attr "insn_count" "5")])
5270 ;; Cache operations for R4000-style caches.
5271 (define_insn "mips_cache"
5272   [(set (mem:BLK (scratch))
5273         (unspec:BLK [(match_operand:SI 0 "const_int_operand")
5274                      (match_operand:QI 1 "address_operand" "p")]
5275                     UNSPEC_MIPS_CACHE))]
5276   "ISA_HAS_CACHE"
5277   "cache\t%X0,%a1")
5279 ;; Similar, but with the operands hard-coded to an R10K cache barrier
5280 ;; operation.  We keep the pattern distinct so that we can identify
5281 ;; cache operations inserted by -mr10k-cache-barrier=, and so that
5282 ;; the operation is never inserted into a delay slot.
5283 (define_insn "r10k_cache_barrier"
5284   [(set (mem:BLK (scratch))
5285         (unspec:BLK [(const_int 0)] UNSPEC_R10K_CACHE_BARRIER))]
5286   "ISA_HAS_CACHE"
5287   "cache\t0x14,0(%$)"
5288   [(set_attr "can_delay" "no")])
5290 ;; Block moves, see mips.c for more details.
5291 ;; Argument 0 is the destination
5292 ;; Argument 1 is the source
5293 ;; Argument 2 is the length
5294 ;; Argument 3 is the alignment
5296 (define_expand "movmemsi"
5297   [(parallel [(set (match_operand:BLK 0 "general_operand")
5298                    (match_operand:BLK 1 "general_operand"))
5299               (use (match_operand:SI 2 ""))
5300               (use (match_operand:SI 3 "const_int_operand"))])]
5301   "!TARGET_MIPS16 && !TARGET_MEMCPY"
5303   if (mips_expand_block_move (operands[0], operands[1], operands[2]))
5304     DONE;
5305   else
5306     FAIL;
5310 ;;  ....................
5312 ;;      SHIFTS
5314 ;;  ....................
5316 (define_expand "<optab><mode>3"
5317   [(set (match_operand:GPR 0 "register_operand")
5318         (any_shift:GPR (match_operand:GPR 1 "register_operand")
5319                        (match_operand:SI 2 "arith_operand")))]
5320   ""
5322   /* On the mips16, a shift of more than 8 is a four byte instruction,
5323      so, for a shift between 8 and 16, it is just as fast to do two
5324      shifts of 8 or less.  If there is a lot of shifting going on, we
5325      may win in CSE.  Otherwise combine will put the shifts back
5326      together again.  This can be called by mips_function_arg, so we must
5327      be careful not to allocate a new register if we've reached the
5328      reload pass.  */
5329   if (TARGET_MIPS16
5330       && optimize
5331       && CONST_INT_P (operands[2])
5332       && INTVAL (operands[2]) > 8
5333       && INTVAL (operands[2]) <= 16
5334       && !reload_in_progress
5335       && !reload_completed)
5336     {
5337       rtx temp = gen_reg_rtx (<MODE>mode);
5339       emit_insn (gen_<optab><mode>3 (temp, operands[1], GEN_INT (8)));
5340       emit_insn (gen_<optab><mode>3 (operands[0], temp,
5341                                      GEN_INT (INTVAL (operands[2]) - 8)));
5342       DONE;
5343     }
5346 (define_insn "*<optab><mode>3"
5347   [(set (match_operand:GPR 0 "register_operand" "=!u,d")
5348         (any_shift:GPR (match_operand:GPR 1 "register_operand" "!u,d")
5349                        (match_operand:SI 2 "arith_operand" "Uib3,dI")))]
5350   "!TARGET_MIPS16"
5352   if (CONST_INT_P (operands[2]))
5353     operands[2] = GEN_INT (INTVAL (operands[2])
5354                            & (GET_MODE_BITSIZE (<MODE>mode) - 1));
5356   return "<d><insn>\t%0,%1,%2";
5358   [(set_attr "type" "shift")
5359    (set_attr "compression" "<shift_compression>,none")
5360    (set_attr "mode" "<MODE>")])
5362 (define_insn "*<optab>si3_extend"
5363   [(set (match_operand:DI 0 "register_operand" "=d")
5364         (sign_extend:DI
5365            (any_shift:SI (match_operand:SI 1 "register_operand" "d")
5366                          (match_operand:SI 2 "arith_operand" "dI"))))]
5367   "TARGET_64BIT && !TARGET_MIPS16"
5369   if (CONST_INT_P (operands[2]))
5370     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5372   return "<insn>\t%0,%1,%2";
5374   [(set_attr "type" "shift")
5375    (set_attr "mode" "SI")])
5377 (define_insn "*<optab>si3_mips16"
5378   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
5379         (any_shift:SI (match_operand:SI 1 "register_operand" "0,d,d")
5380                       (match_operand:SI 2 "arith_operand" "d,Uib3,I")))]
5381   "TARGET_MIPS16"
5383   if (which_alternative == 0)
5384     return "<insn>\t%0,%2";
5386   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5387   return "<insn>\t%0,%1,%2";
5389   [(set_attr "type" "shift")
5390    (set_attr "mode" "SI")
5391    (set_attr "extended_mips16" "no,no,yes")])
5393 ;; We need separate DImode MIPS16 patterns because of the irregularity
5394 ;; of right shifts.
5395 (define_insn "*ashldi3_mips16"
5396   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
5397         (ashift:DI (match_operand:DI 1 "register_operand" "0,d,d")
5398                    (match_operand:SI 2 "arith_operand" "d,Uib3,I")))]
5399   "TARGET_64BIT && TARGET_MIPS16"
5401   if (which_alternative == 0)
5402     return "dsll\t%0,%2";
5404   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5405   return "dsll\t%0,%1,%2";
5407   [(set_attr "type" "shift")
5408    (set_attr "mode" "DI")
5409    (set_attr "extended_mips16" "no,no,yes")])
5411 (define_insn "*ashrdi3_mips16"
5412   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
5413         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0,0")
5414                      (match_operand:SI 2 "arith_operand" "d,Uib3,I")))]
5415   "TARGET_64BIT && TARGET_MIPS16"
5417   if (CONST_INT_P (operands[2]))
5418     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5420   return "dsra\t%0,%2";
5422   [(set_attr "type" "shift")
5423    (set_attr "mode" "DI")
5424    (set_attr "extended_mips16" "no,no,yes")])
5426 (define_insn "*lshrdi3_mips16"
5427   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
5428         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0,0")
5429                      (match_operand:SI 2 "arith_operand" "d,Uib3,I")))]
5430   "TARGET_64BIT && TARGET_MIPS16"
5432   if (CONST_INT_P (operands[2]))
5433     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5435   return "dsrl\t%0,%2";
5437   [(set_attr "type" "shift")
5438    (set_attr "mode" "DI")
5439    (set_attr "extended_mips16" "no,no,yes")])
5441 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5443 (define_split
5444   [(set (match_operand:GPR 0 "d_operand")
5445         (any_shift:GPR (match_operand:GPR 1 "d_operand")
5446                        (match_operand:GPR 2 "const_int_operand")))]
5447   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5448    && INTVAL (operands[2]) > 8
5449    && INTVAL (operands[2]) <= 16"
5450   [(set (match_dup 0) (any_shift:GPR (match_dup 1) (const_int 8)))
5451    (set (match_dup 0) (any_shift:GPR (match_dup 0) (match_dup 2)))]
5452   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5454 ;; If we load a byte on the mips16 as a bitfield, the resulting
5455 ;; sequence of instructions is too complicated for combine, because it
5456 ;; involves four instructions: a load, a shift, a constant load into a
5457 ;; register, and an and (the key problem here is that the mips16 does
5458 ;; not have and immediate).  We recognize a shift of a load in order
5459 ;; to make it simple enough for combine to understand.
5461 ;; The instruction count here is the worst case.
5462 (define_insn_and_split ""
5463   [(set (match_operand:SI 0 "register_operand" "=d")
5464         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
5465                      (match_operand:SI 2 "immediate_operand" "I")))]
5466   "TARGET_MIPS16"
5467   "#"
5468   ""
5469   [(set (match_dup 0) (match_dup 1))
5470    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
5471   ""
5472   [(set_attr "type"     "load")
5473    (set_attr "mode"     "SI")
5474    (set (attr "insn_count")
5475         (symbol_ref "mips_load_store_insns (operands[1], insn) + 2"))])
5477 (define_insn "rotr<mode>3"
5478   [(set (match_operand:GPR 0 "register_operand" "=d")
5479         (rotatert:GPR (match_operand:GPR 1 "register_operand" "d")
5480                       (match_operand:SI 2 "arith_operand" "dI")))]
5481   "ISA_HAS_ROR"
5483   if (CONST_INT_P (operands[2]))
5484     gcc_assert (INTVAL (operands[2]) >= 0
5485                 && INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode));
5487   return "<d>ror\t%0,%1,%2";
5489   [(set_attr "type" "shift")
5490    (set_attr "mode" "<MODE>")])
5492 (define_insn "bswaphi2"
5493   [(set (match_operand:HI 0 "register_operand" "=d")
5494         (bswap:HI (match_operand:HI 1 "register_operand" "d")))]
5495   "ISA_HAS_WSBH"
5496   "wsbh\t%0,%1"
5497   [(set_attr "type" "shift")])
5499 (define_insn_and_split "bswapsi2"
5500   [(set (match_operand:SI 0 "register_operand" "=d")
5501         (bswap:SI (match_operand:SI 1 "register_operand" "d")))]
5502   "ISA_HAS_WSBH && ISA_HAS_ROR"
5503   "#"
5504   ""
5505   [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_WSBH))
5506    (set (match_dup 0) (rotatert:SI (match_dup 0) (const_int 16)))]
5507   ""
5508   [(set_attr "insn_count" "2")])
5510 (define_insn_and_split "bswapdi2"
5511   [(set (match_operand:DI 0 "register_operand" "=d")
5512         (bswap:DI (match_operand:DI 1 "register_operand" "d")))]
5513   "TARGET_64BIT && ISA_HAS_WSBH"
5514   "#"
5515   ""
5516   [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_DSBH))
5517    (set (match_dup 0) (unspec:DI [(match_dup 0)] UNSPEC_DSHD))]
5518   ""
5519   [(set_attr "insn_count" "2")])
5521 (define_insn "wsbh"
5522   [(set (match_operand:SI 0 "register_operand" "=d")
5523         (unspec:SI [(match_operand:SI 1 "register_operand" "d")] UNSPEC_WSBH))]
5524   "ISA_HAS_WSBH"
5525   "wsbh\t%0,%1"
5526   [(set_attr "type" "shift")])
5528 (define_insn "dsbh"
5529   [(set (match_operand:DI 0 "register_operand" "=d")
5530         (unspec:DI [(match_operand:DI 1 "register_operand" "d")] UNSPEC_DSBH))]
5531   "TARGET_64BIT && ISA_HAS_WSBH"
5532   "dsbh\t%0,%1"
5533   [(set_attr "type" "shift")])
5535 (define_insn "dshd"
5536   [(set (match_operand:DI 0 "register_operand" "=d")
5537         (unspec:DI [(match_operand:DI 1 "register_operand" "d")] UNSPEC_DSHD))]
5538   "TARGET_64BIT && ISA_HAS_WSBH"
5539   "dshd\t%0,%1"
5540   [(set_attr "type" "shift")])
5543 ;;  ....................
5545 ;;      CONDITIONAL BRANCHES
5547 ;;  ....................
5549 ;; Conditional branches on floating-point equality tests.
5551 (define_insn "*branch_fp"
5552   [(set (pc)
5553         (if_then_else
5554          (match_operator 1 "equality_operator"
5555                          [(match_operand:CC 2 "register_operand" "z")
5556                           (const_int 0)])
5557          (label_ref (match_operand 0 "" ""))
5558          (pc)))]
5559   "TARGET_HARD_FLOAT"
5561   return mips_output_conditional_branch (insn, operands,
5562                                          MIPS_BRANCH ("b%F1", "%Z2%0"),
5563                                          MIPS_BRANCH ("b%W1", "%Z2%0"));
5565   [(set_attr "type" "branch")])
5567 (define_insn "*branch_fp_inverted"
5568   [(set (pc)
5569         (if_then_else
5570          (match_operator 1 "equality_operator"
5571                          [(match_operand:CC 2 "register_operand" "z")
5572                           (const_int 0)])
5573          (pc)
5574          (label_ref (match_operand 0 "" ""))))]
5575   "TARGET_HARD_FLOAT"
5577   return mips_output_conditional_branch (insn, operands,
5578                                          MIPS_BRANCH ("b%W1", "%Z2%0"),
5579                                          MIPS_BRANCH ("b%F1", "%Z2%0"));
5581   [(set_attr "type" "branch")])
5583 ;; Conditional branches on ordered comparisons with zero.
5585 (define_insn "*branch_order<mode>"
5586   [(set (pc)
5587         (if_then_else
5588          (match_operator 1 "order_operator"
5589                          [(match_operand:GPR 2 "register_operand" "d")
5590                           (const_int 0)])
5591          (label_ref (match_operand 0 "" ""))
5592          (pc)))]
5593   "!TARGET_MIPS16"
5594   { return mips_output_order_conditional_branch (insn, operands, false); }
5595   [(set_attr "type" "branch")])
5597 (define_insn "*branch_order<mode>_inverted"
5598   [(set (pc)
5599         (if_then_else
5600          (match_operator 1 "order_operator"
5601                          [(match_operand:GPR 2 "register_operand" "d")
5602                           (const_int 0)])
5603          (pc)
5604          (label_ref (match_operand 0 "" ""))))]
5605   "!TARGET_MIPS16"
5606   { return mips_output_order_conditional_branch (insn, operands, true); }
5607   [(set_attr "type" "branch")])
5609 ;; Conditional branch on equality comparison.
5611 (define_insn "*branch_equality<mode>"
5612   [(set (pc)
5613         (if_then_else
5614          (match_operator 1 "equality_operator"
5615                          [(match_operand:GPR 2 "register_operand" "d")
5616                           (match_operand:GPR 3 "reg_or_0_operand" "dJ")])
5617          (label_ref (match_operand 0 "" ""))
5618          (pc)))]
5619   "!TARGET_MIPS16"
5621   /* For a simple BNEZ or BEQZ microMIPS branch.  */
5622   if (TARGET_MICROMIPS
5623       && operands[3] == const0_rtx
5624       && get_attr_length (insn) <= 8)
5625     return mips_output_conditional_branch (insn, operands,
5626                                            "%*b%C1z%:\t%2,%0",
5627                                            "%*b%N1z%:\t%2,%0");
5629   return mips_output_conditional_branch (insn, operands,
5630                                          MIPS_BRANCH ("b%C1", "%2,%z3,%0"),
5631                                          MIPS_BRANCH ("b%N1", "%2,%z3,%0"));
5633   [(set_attr "type" "branch")])
5635 (define_insn "*branch_equality<mode>_inverted"
5636   [(set (pc)
5637         (if_then_else
5638          (match_operator 1 "equality_operator"
5639                          [(match_operand:GPR 2 "register_operand" "d")
5640                           (match_operand:GPR 3 "reg_or_0_operand" "dJ")])
5641          (pc)
5642          (label_ref (match_operand 0 "" ""))))]
5643   "!TARGET_MIPS16"
5645   /* For a simple BNEZ or BEQZ microMIPS branch.  */
5646   if (TARGET_MICROMIPS
5647       && operands[3] == const0_rtx
5648       && get_attr_length (insn) <= 8)
5649     return mips_output_conditional_branch (insn, operands,
5650                                            "%*b%N0z%:\t%2,%1",
5651                                            "%*b%C0z%:\t%2,%1");
5653   return mips_output_conditional_branch (insn, operands,
5654                                          MIPS_BRANCH ("b%N1", "%2,%z3,%0"),
5655                                          MIPS_BRANCH ("b%C1", "%2,%z3,%0"));
5657   [(set_attr "type" "branch")])
5659 ;; MIPS16 branches
5661 (define_insn "*branch_equality<mode>_mips16"
5662   [(set (pc)
5663         (if_then_else
5664          (match_operator 1 "equality_operator"
5665                          [(match_operand:GPR 2 "register_operand" "d,t")
5666                           (const_int 0)])
5667          (label_ref (match_operand 0 "" ""))
5668          (pc)))]
5669   "TARGET_MIPS16"
5670   "@
5671    b%C1z\t%2,%0
5672    bt%C1z\t%0"
5673   [(set_attr "type" "branch")])
5675 (define_insn "*branch_equality<mode>_mips16_inverted"
5676   [(set (pc)
5677         (if_then_else
5678          (match_operator 1 "equality_operator"
5679                          [(match_operand:GPR 2 "register_operand" "d,t")
5680                           (const_int 0)])
5681          (pc)
5682          (label_ref (match_operand 0 "" ""))))]
5683   "TARGET_MIPS16"
5684   "@
5685    b%N1z\t%2,%0
5686    bt%N1z\t%0"
5687   [(set_attr "type" "branch")])
5689 (define_expand "cbranch<mode>4"
5690   [(set (pc)
5691         (if_then_else (match_operator 0 "comparison_operator"
5692                        [(match_operand:GPR 1 "register_operand")
5693                         (match_operand:GPR 2 "nonmemory_operand")])
5694                       (label_ref (match_operand 3 ""))
5695                       (pc)))]
5696   ""
5698   mips_expand_conditional_branch (operands);
5699   DONE;
5702 (define_expand "cbranch<mode>4"
5703   [(set (pc)
5704         (if_then_else (match_operator 0 "comparison_operator"
5705                        [(match_operand:SCALARF 1 "register_operand")
5706                         (match_operand:SCALARF 2 "register_operand")])
5707                       (label_ref (match_operand 3 ""))
5708                       (pc)))]
5709   ""
5711   mips_expand_conditional_branch (operands);
5712   DONE;
5715 ;; Used to implement built-in functions.
5716 (define_expand "condjump"
5717   [(set (pc)
5718         (if_then_else (match_operand 0)
5719                       (label_ref (match_operand 1))
5720                       (pc)))])
5722 ;; Branch if bit is set/clear.
5724 (define_insn "*branch_bit<bbv><mode>"
5725   [(set (pc)
5726         (if_then_else
5727          (equality_op (zero_extract:GPR
5728                        (match_operand:GPR 1 "register_operand" "d")
5729                        (const_int 1)
5730                        (match_operand 2 "const_int_operand" ""))
5731                       (const_int 0))
5732          (label_ref (match_operand 0 ""))
5733          (pc)))]
5734   "ISA_HAS_BBIT && UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
5736   return
5737     mips_output_conditional_branch (insn, operands,
5738                                     MIPS_BRANCH ("bbit<bbv>", "%1,%2,%0"),
5739                                     MIPS_BRANCH ("bbit<bbinv>", "%1,%2,%0"));
5741   [(set_attr "type"          "branch")
5742    (set_attr "branch_likely" "no")])
5744 (define_insn "*branch_bit<bbv><mode>_inverted"
5745   [(set (pc)
5746         (if_then_else
5747          (equality_op (zero_extract:GPR
5748                        (match_operand:GPR 1 "register_operand" "d")
5749                        (const_int 1)
5750                        (match_operand 2 "const_int_operand" ""))
5751                       (const_int 0))
5752          (pc)
5753          (label_ref (match_operand 0 ""))))]
5754   "ISA_HAS_BBIT && UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
5756   return
5757     mips_output_conditional_branch (insn, operands,
5758                                     MIPS_BRANCH ("bbit<bbinv>", "%1,%2,%0"),
5759                                     MIPS_BRANCH ("bbit<bbv>", "%1,%2,%0"));
5761   [(set_attr "type"          "branch")
5762    (set_attr "branch_likely" "no")])
5765 ;;  ....................
5767 ;;      SETTING A REGISTER FROM A COMPARISON
5769 ;;  ....................
5771 ;; Destination is always set in SI mode.
5773 (define_expand "cstore<mode>4"
5774   [(set (match_operand:SI 0 "register_operand")
5775         (match_operator:SI 1 "mips_cstore_operator"
5776          [(match_operand:GPR 2 "register_operand")
5777           (match_operand:GPR 3 "nonmemory_operand")]))]
5778   ""
5780   mips_expand_scc (operands);
5781   DONE;
5784 (define_insn "*seq_zero_<GPR:mode><GPR2:mode>"
5785   [(set (match_operand:GPR2 0 "register_operand" "=d")
5786         (eq:GPR2 (match_operand:GPR 1 "register_operand" "d")
5787                  (const_int 0)))]
5788   "!TARGET_MIPS16 && !ISA_HAS_SEQ_SNE"
5789   "sltu\t%0,%1,1"
5790   [(set_attr "type" "slt")
5791    (set_attr "mode" "<GPR:MODE>")])
5793 (define_insn "*seq_zero_<GPR:mode><GPR2:mode>_mips16"
5794   [(set (match_operand:GPR2 0 "register_operand" "=t")
5795         (eq:GPR2 (match_operand:GPR 1 "register_operand" "d")
5796                  (const_int 0)))]
5797   "TARGET_MIPS16 && !ISA_HAS_SEQ_SNE"
5798   "sltu\t%1,1"
5799   [(set_attr "type" "slt")
5800    (set_attr "mode" "<GPR:MODE>")])
5802 ;; Generate sltiu unless using seq results in better code.
5803 (define_insn "*seq_<GPR:mode><GPR2:mode>_seq"
5804   [(set (match_operand:GPR2 0 "register_operand" "=d,d,d")
5805         (eq:GPR2 (match_operand:GPR 1 "register_operand" "%d,d,d")
5806                  (match_operand:GPR 2 "reg_imm10_operand" "d,J,YB")))]
5807   "ISA_HAS_SEQ_SNE"
5808   "@
5809    seq\t%0,%1,%2
5810    sltiu\t%0,%1,1
5811    seqi\t%0,%1,%2"
5812   [(set_attr "type" "slt")
5813    (set_attr "mode" "<GPR:MODE>")])
5815 (define_insn "*sne_zero_<GPR:mode><GPR2:mode>"
5816   [(set (match_operand:GPR2 0 "register_operand" "=d")
5817         (ne:GPR2 (match_operand:GPR 1 "register_operand" "d")
5818                  (const_int 0)))]
5819   "!TARGET_MIPS16 && !ISA_HAS_SEQ_SNE"
5820   "sltu\t%0,%.,%1"
5821   [(set_attr "type" "slt")
5822    (set_attr "mode" "<GPR:MODE>")])
5824 ;; Generate sltu unless using sne results in better code.
5825 (define_insn "*sne_<GPR:mode><GPR2:mode>_sne"
5826   [(set (match_operand:GPR2 0 "register_operand" "=d,d,d")
5827         (ne:GPR2 (match_operand:GPR 1 "register_operand" "%d,d,d")
5828                  (match_operand:GPR 2 "reg_imm10_operand" "d,J,YB")))]
5829   "ISA_HAS_SEQ_SNE"
5830   "@
5831    sne\t%0,%1,%2
5832    sltu\t%0,%.,%1
5833    snei\t%0,%1,%2"
5834   [(set_attr "type" "slt")
5835    (set_attr "mode" "<GPR:MODE>")])
5837 (define_insn "*sgt<u>_<GPR:mode><GPR2:mode>"
5838   [(set (match_operand:GPR2 0 "register_operand" "=d")
5839         (any_gt:GPR2 (match_operand:GPR 1 "register_operand" "d")
5840                      (match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
5841   "!TARGET_MIPS16"
5842   "slt<u>\t%0,%z2,%1"
5843   [(set_attr "type" "slt")
5844    (set_attr "mode" "<GPR:MODE>")])
5846 (define_insn "*sgt<u>_<GPR:mode><GPR2:mode>_mips16"
5847   [(set (match_operand:GPR2 0 "register_operand" "=t")
5848         (any_gt:GPR2 (match_operand:GPR 1 "register_operand" "d")
5849                      (match_operand:GPR 2 "register_operand" "d")))]
5850   "TARGET_MIPS16"
5851   "slt<u>\t%2,%1"
5852   [(set_attr "type" "slt")
5853    (set_attr "mode" "<GPR:MODE>")])
5855 (define_insn "*sge<u>_<GPR:mode><GPR2:mode>"
5856   [(set (match_operand:GPR2 0 "register_operand" "=d")
5857         (any_ge:GPR2 (match_operand:GPR 1 "register_operand" "d")
5858                      (const_int 1)))]
5859   "!TARGET_MIPS16"
5860   "slt<u>\t%0,%.,%1"
5861   [(set_attr "type" "slt")
5862    (set_attr "mode" "<GPR:MODE>")])
5864 (define_insn "*slt<u>_<GPR:mode><GPR2:mode>"
5865   [(set (match_operand:GPR2 0 "register_operand" "=d")
5866         (any_lt:GPR2 (match_operand:GPR 1 "register_operand" "d")
5867                      (match_operand:GPR 2 "arith_operand" "dI")))]
5868   "!TARGET_MIPS16"
5869   "slt<u>\t%0,%1,%2"
5870   [(set_attr "type" "slt")
5871    (set_attr "mode" "<GPR:MODE>")])
5873 (define_insn "*slt<u>_<GPR:mode><GPR2:mode>_mips16"
5874   [(set (match_operand:GPR2 0 "register_operand" "=t,t,t")
5875         (any_lt:GPR2 (match_operand:GPR 1 "register_operand" "d,d,d")
5876                      (match_operand:GPR 2 "arith_operand" "d,Uub8,I")))]
5877   "TARGET_MIPS16"
5878   "slt<u>\t%1,%2"
5879   [(set_attr "type" "slt")
5880    (set_attr "mode" "<GPR:MODE>")
5881    (set_attr "extended_mips16" "no,no,yes")])
5883 (define_insn "*sle<u>_<GPR:mode><GPR2:mode>"
5884   [(set (match_operand:GPR2 0 "register_operand" "=d")
5885         (any_le:GPR2 (match_operand:GPR 1 "register_operand" "d")
5886                      (match_operand:GPR 2 "sle_operand" "")))]
5887   "!TARGET_MIPS16"
5889   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5890   return "slt<u>\t%0,%1,%2";
5892   [(set_attr "type" "slt")
5893    (set_attr "mode" "<GPR:MODE>")])
5895 (define_insn "*sle<u>_<GPR:mode><GPR2:mode>_mips16"
5896   [(set (match_operand:GPR2 0 "register_operand" "=t,t")
5897         (any_le:GPR2 (match_operand:GPR 1 "register_operand" "d,d")
5898                      (match_operand:GPR 2 "sle_operand" "Udb8,i")))]
5899   "TARGET_MIPS16"
5901   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5902   return "slt<u>\t%1,%2";
5904   [(set_attr "type" "slt")
5905    (set_attr "mode" "<GPR:MODE>")
5906    (set_attr "extended_mips16" "no,yes")])
5909 ;;  ....................
5911 ;;      FLOATING POINT COMPARISONS
5913 ;;  ....................
5915 (define_insn "s<code>_<mode>"
5916   [(set (match_operand:CC 0 "register_operand" "=z")
5917         (fcond:CC (match_operand:SCALARF 1 "register_operand" "f")
5918                   (match_operand:SCALARF 2 "register_operand" "f")))]
5919   ""
5920   "c.<fcond>.<fmt>\t%Z0%1,%2"
5921   [(set_attr "type" "fcmp")
5922    (set_attr "mode" "FPSW")])
5924 (define_insn "s<code>_<mode>"
5925   [(set (match_operand:CC 0 "register_operand" "=z")
5926         (swapped_fcond:CC (match_operand:SCALARF 1 "register_operand" "f")
5927                           (match_operand:SCALARF 2 "register_operand" "f")))]
5928   ""
5929   "c.<swapped_fcond>.<fmt>\t%Z0%2,%1"
5930   [(set_attr "type" "fcmp")
5931    (set_attr "mode" "FPSW")])
5934 ;;  ....................
5936 ;;      UNCONDITIONAL BRANCHES
5938 ;;  ....................
5940 ;; Unconditional branches.
5942 (define_expand "jump"
5943   [(set (pc)
5944         (label_ref (match_operand 0)))])
5946 (define_insn "*jump_absolute"
5947   [(set (pc)
5948         (label_ref (match_operand 0)))]
5949   "!TARGET_MIPS16 && TARGET_ABSOLUTE_JUMPS"
5951   /* Use a branch for microMIPS.  The assembler will choose
5952      a 16-bit branch, a 32-bit branch, or a 32-bit jump.  */
5953   if (TARGET_MICROMIPS && !TARGET_ABICALLS_PIC2)
5954     return "%*b\t%l0%/";
5955   else
5956     return MIPS_ABSOLUTE_JUMP ("%*j\t%l0%/");
5958   [(set_attr "type" "jump")])
5960 (define_insn "*jump_pic"
5961   [(set (pc)
5962         (label_ref (match_operand 0)))]
5963   "!TARGET_MIPS16 && !TARGET_ABSOLUTE_JUMPS"
5965   if (get_attr_length (insn) <= 8)
5966     return "%*b\t%l0%/";
5967   else
5968     {
5969       mips_output_load_label (operands[0]);
5970       return "%*jr\t%@%/%]";
5971     }
5973   [(set_attr "type" "branch")])
5975 ;; We need a different insn for the mips16, because a mips16 branch
5976 ;; does not have a delay slot.
5978 (define_insn "*jump_mips16"
5979   [(set (pc)
5980         (label_ref (match_operand 0 "" "")))]
5981   "TARGET_MIPS16"
5982   "b\t%l0"
5983   [(set_attr "type" "branch")
5984    (set (attr "length")
5985         ;; This calculation is like the normal branch one, but the
5986         ;; range of the unextended instruction is [-0x800, 0x7fe] rather
5987         ;; than [-0x100, 0xfe].  This translates to a range of:
5988         ;;
5989         ;;    [-(0x800 - sizeof (branch)), 0x7fe]
5990         ;; == [-0x7fe, 0x7fe]
5991         ;;
5992         ;; from the shorten_branches reference address.  Long-branch
5993         ;; sequences will replace this one, so the minimum length
5994         ;; is one instruction shorter than for conditional branches.
5995         (cond [(and (le (minus (match_dup 0) (pc)) (const_int 2046))
5996                     (le (minus (pc) (match_dup 0)) (const_int 2046)))
5997                (const_int 2)
5998                (and (le (minus (match_dup 0) (pc)) (const_int 65534))
5999                     (le (minus (pc) (match_dup 0)) (const_int 65532)))
6000                (const_int 4)
6001                (and (match_test "TARGET_ABICALLS")
6002                     (not (match_test "TARGET_ABSOLUTE_ABICALLS")))
6003                (const_int 18)
6004                (match_test "Pmode == SImode")
6005                (const_int 14)
6006                ] (const_int 22)))])
6008 (define_expand "indirect_jump"
6009   [(set (pc) (match_operand 0 "register_operand"))]
6010   ""
6012   operands[0] = force_reg (Pmode, operands[0]);
6013   emit_jump_insn (PMODE_INSN (gen_indirect_jump, (operands[0])));
6014   DONE;
6017 (define_insn "indirect_jump_<mode>"
6018   [(set (pc) (match_operand:P 0 "register_operand" "d"))]
6019   ""
6021   if (TARGET_MICROMIPS)
6022     return "%*jr%:\t%0";
6023   else
6024     return "%*j\t%0%/";
6026   [(set_attr "type" "jump")
6027    (set_attr "mode" "none")])
6029 ;; A combined jump-and-move instruction, used for MIPS16 long-branch
6030 ;; sequences.  Having a dedicated pattern is more convenient than
6031 ;; creating a SEQUENCE for this special case.
6032 (define_insn "indirect_jump_and_restore_<mode>"
6033   [(set (pc) (match_operand:P 1 "register_operand" "d"))
6034    (set (match_operand:P 0 "register_operand" "=d")
6035         (match_operand:P 2 "register_operand" "y"))]
6036   ""
6037   "%(%<jr\t%1\;move\t%0,%2%>%)"
6038   [(set_attr "type" "multi")
6039    (set_attr "extended_mips16" "yes")])
6041 (define_expand "tablejump"
6042   [(set (pc)
6043         (match_operand 0 "register_operand"))
6044    (use (label_ref (match_operand 1 "")))]
6045   "!TARGET_MIPS16_SHORT_JUMP_TABLES"
6047   if (TARGET_GPWORD)
6048     operands[0] = expand_binop (Pmode, add_optab, operands[0],
6049                                 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
6050   else if (TARGET_RTP_PIC)
6051     {
6052       /* When generating RTP PIC, we use case table entries that are relative
6053          to the start of the function.  Add the function's address to the
6054          value we loaded.  */
6055       rtx start = get_hard_reg_initial_val (Pmode, PIC_FUNCTION_ADDR_REGNUM);
6056       operands[0] = expand_binop (ptr_mode, add_optab, operands[0],
6057                                   start, 0, 0, OPTAB_WIDEN);
6058     }
6060   emit_jump_insn (PMODE_INSN (gen_tablejump, (operands[0], operands[1])));
6061   DONE;
6064 (define_insn "tablejump_<mode>"
6065   [(set (pc)
6066         (match_operand:P 0 "register_operand" "d"))
6067    (use (label_ref (match_operand 1 "" "")))]
6068   ""
6070   if (TARGET_MICROMIPS)
6071     return "%*jr%:\t%0";
6072   else
6073     return "%*j\t%0%/";
6075   [(set_attr "type" "jump")
6076    (set_attr "mode" "none")])
6078 ;; For MIPS16, we don't know whether a given jump table will use short or
6079 ;; word-sized offsets until late in compilation, when we are able to determine
6080 ;; the sizes of the insns which comprise the containing function.  This
6081 ;; necessitates the use of the casesi rather than the tablejump pattern, since
6082 ;; the latter tries to calculate the index of the offset to jump through early
6083 ;; in compilation, i.e. at expand time, when nothing is known about the
6084 ;; eventual function layout.
6086 (define_expand "casesi"
6087   [(match_operand:SI 0 "register_operand" "")   ; index to jump on
6088    (match_operand:SI 1 "const_int_operand" "")  ; lower bound
6089    (match_operand:SI 2 "const_int_operand" "")  ; total range
6090    (match_operand 3 "" "")                      ; table label
6091    (match_operand 4 "" "")]                     ; out of range label
6092   "TARGET_MIPS16_SHORT_JUMP_TABLES"
6094   if (operands[1] != const0_rtx)
6095     {
6096       rtx reg = gen_reg_rtx (SImode);
6097       rtx offset = gen_int_mode (-INTVAL (operands[1]), SImode);
6098       
6099       if (!arith_operand (offset, SImode))
6100         offset = force_reg (SImode, offset);
6101       
6102       emit_insn (gen_addsi3 (reg, operands[0], offset));
6103       operands[0] = reg;
6104     }
6106   if (!arith_operand (operands[0], SImode))
6107     operands[0] = force_reg (SImode, operands[0]);
6109   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6111   emit_jump_insn (PMODE_INSN (gen_casesi_internal_mips16,
6112                               (operands[0], operands[2],
6113                                operands[3], operands[4])));
6115   DONE;
6118 (define_insn "casesi_internal_mips16_<mode>"
6119   [(set (pc)
6120      (if_then_else
6121        (leu (match_operand:SI 0 "register_operand" "d")
6122             (match_operand:SI 1 "arith_operand" "dI"))
6123        (unspec:P
6124         [(match_dup 0)
6125          (label_ref (match_operand 2 "" ""))]
6126         UNSPEC_CASESI_DISPATCH)
6127        (label_ref (match_operand 3 "" ""))))
6128    (clobber (match_scratch:P 4 "=d"))
6129    (clobber (match_scratch:P 5 "=d"))
6130    (clobber (reg:SI MIPS16_T_REGNUM))]
6131   "TARGET_MIPS16_SHORT_JUMP_TABLES"
6133   rtx diff_vec = PATTERN (NEXT_INSN (operands[2]));
6135   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
6136   
6137   output_asm_insn ("sltu\t%0, %1", operands);
6138   output_asm_insn ("bteqz\t%3", operands);
6139   
6140   switch (GET_MODE (diff_vec))
6141     {
6142     case HImode:
6143       output_asm_insn ("sll\t%5, %0, 1", operands);
6144       output_asm_insn ("la\t%4, %2", operands);
6145       output_asm_insn ("<d>addu\t%5, %4, %5", operands);
6146       output_asm_insn ("lh\t%5, 0(%5)", operands);
6147       break;
6148     
6149     case SImode:
6150       output_asm_insn ("sll\t%5, %0, 2", operands);
6151       output_asm_insn ("la\t%4, %2", operands);
6152       output_asm_insn ("<d>addu\t%5, %4, %5", operands);
6153       output_asm_insn ("lw\t%5, 0(%5)", operands);
6154       break;
6156     default:
6157       gcc_unreachable ();
6158     }
6159   
6160   output_asm_insn ("addu\t%4, %4, %5", operands);
6161   
6162   return "j\t%4";
6164   [(set_attr "insn_count" "16")])
6166 ;; For TARGET_USE_GOT, we save the gp in the jmp_buf as well.
6167 ;; While it is possible to either pull it off the stack (in the
6168 ;; o32 case) or recalculate it given t9 and our target label,
6169 ;; it takes 3 or 4 insns to do so.
6171 (define_expand "builtin_setjmp_setup"
6172   [(use (match_operand 0 "register_operand"))]
6173   "TARGET_USE_GOT"
6175   rtx addr;
6177   addr = plus_constant (Pmode, operands[0], GET_MODE_SIZE (Pmode) * 3);
6178   mips_emit_move (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
6179   DONE;
6182 ;; Restore the gp that we saved above.  Despite the earlier comment, it seems
6183 ;; that older code did recalculate the gp from $25.  Continue to jump through
6184 ;; $25 for compatibility (we lose nothing by doing so).
6186 (define_expand "builtin_longjmp"
6187   [(use (match_operand 0 "register_operand"))]
6188   "TARGET_USE_GOT"
6190   /* The elements of the buffer are, in order:  */
6191   int W = GET_MODE_SIZE (Pmode);
6192   rtx fp = gen_rtx_MEM (Pmode, operands[0]);
6193   rtx lab = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], 1*W));
6194   rtx stack = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], 2*W));
6195   rtx gpv = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], 3*W));
6196   rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
6197   /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
6198      The target is bound to be using $28 as the global pointer
6199      but the current function might not be.  */
6200   rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
6202   /* This bit is similar to expand_builtin_longjmp except that it
6203      restores $gp as well.  */
6204   mips_emit_move (hard_frame_pointer_rtx, fp);
6205   mips_emit_move (pv, lab);
6206   emit_stack_restore (SAVE_NONLOCAL, stack);
6207   mips_emit_move (gp, gpv);
6208   emit_use (hard_frame_pointer_rtx);
6209   emit_use (stack_pointer_rtx);
6210   emit_use (gp);
6211   emit_indirect_jump (pv);
6212   DONE;
6216 ;;  ....................
6218 ;;      Function prologue/epilogue
6220 ;;  ....................
6223 (define_expand "prologue"
6224   [(const_int 1)]
6225   ""
6227   mips_expand_prologue ();
6228   DONE;
6231 ;; Block any insns from being moved before this point, since the
6232 ;; profiling call to mcount can use various registers that aren't
6233 ;; saved or used to pass arguments.
6235 (define_insn "blockage"
6236   [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
6237   ""
6238   ""
6239   [(set_attr "type" "ghost")
6240    (set_attr "mode" "none")])
6242 (define_insn "probe_stack_range_<P:mode>"
6243   [(set (match_operand:P 0 "register_operand" "=d")
6244         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6245                             (match_operand:P 2 "register_operand" "d")]
6246                             UNSPEC_PROBE_STACK_RANGE))]
6247   ""
6248  { return mips_output_probe_stack_range (operands[0], operands[2]); }
6249   [(set_attr "type" "unknown")
6250    (set_attr "can_delay" "no")
6251    (set_attr "mode" "<MODE>")])
6253 (define_expand "epilogue"
6254   [(const_int 2)]
6255   ""
6257   mips_expand_epilogue (false);
6258   DONE;
6261 (define_expand "sibcall_epilogue"
6262   [(const_int 2)]
6263   ""
6265   mips_expand_epilogue (true);
6266   DONE;
6269 ;; Trivial return.  Make it look like a normal return insn as that
6270 ;; allows jump optimizations to work better.
6272 (define_expand "return"
6273   [(simple_return)]
6274   "mips_can_use_return_insn ()"
6275   { mips_expand_before_return (); })
6277 (define_expand "simple_return"
6278   [(simple_return)]
6279   ""
6280   { mips_expand_before_return (); })
6282 (define_insn "*<optab>"
6283   [(any_return)]
6284   ""
6285   {
6286     if (TARGET_MICROMIPS)
6287       return "%*jr%:\t$31";
6288     else
6289       return "%*j\t$31%/";
6290   }
6291   [(set_attr "type"     "jump")
6292    (set_attr "mode"     "none")])
6294 ;; Normal return.
6296 (define_insn "<optab>_internal"
6297   [(any_return)
6298    (use (match_operand 0 "pmode_register_operand" ""))]
6299   ""
6301   if (TARGET_MICROMIPS)
6302     return "%*jr%:\t%0";
6303   else
6304     return "%*j\t%0%/";
6306   [(set_attr "type"     "jump")
6307    (set_attr "mode"     "none")])
6309 ;; Exception return.
6310 (define_insn "mips_eret"
6311   [(return)
6312    (unspec_volatile [(const_int 0)] UNSPEC_ERET)]
6313   ""
6314   "eret"
6315   [(set_attr "type"     "trap")
6316    (set_attr "mode"     "none")])
6318 ;; Debug exception return.
6319 (define_insn "mips_deret"
6320   [(return)
6321    (unspec_volatile [(const_int 0)] UNSPEC_DERET)]
6322   ""
6323   "deret"
6324   [(set_attr "type"     "trap")
6325    (set_attr "mode"     "none")])
6327 ;; Disable interrupts.
6328 (define_insn "mips_di"
6329   [(unspec_volatile [(const_int 0)] UNSPEC_DI)]
6330   ""
6331   "di"
6332   [(set_attr "type"     "trap")
6333    (set_attr "mode"     "none")])
6335 ;; Execution hazard barrier.
6336 (define_insn "mips_ehb"
6337   [(unspec_volatile [(const_int 0)] UNSPEC_EHB)]
6338   ""
6339   "ehb"
6340   [(set_attr "type"     "trap")
6341    (set_attr "mode"     "none")])
6343 ;; Read GPR from previous shadow register set.
6344 (define_insn "mips_rdpgpr"
6345   [(set (match_operand:SI 0 "register_operand" "=d")
6346         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "d")]
6347                             UNSPEC_RDPGPR))]
6348   ""
6349   "rdpgpr\t%0,%1"
6350   [(set_attr "type"     "move")
6351    (set_attr "mode"     "SI")])
6353 ;; Move involving COP0 registers.
6354 (define_insn "cop0_move"
6355   [(set (match_operand:SI 0 "register_operand" "=B,d")
6356         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "d,B")]
6357                             UNSPEC_COP0))]
6358   ""
6359 { return mips_output_move (operands[0], operands[1]); }
6360   [(set_attr "type"     "mtc,mfc")
6361    (set_attr "mode"     "SI")])
6363 ;; This is used in compiling the unwind routines.
6364 (define_expand "eh_return"
6365   [(use (match_operand 0 "general_operand"))]
6366   ""
6368   if (GET_MODE (operands[0]) != word_mode)
6369     operands[0] = convert_to_mode (word_mode, operands[0], 0);
6370   if (TARGET_64BIT)
6371     emit_insn (gen_eh_set_lr_di (operands[0]));
6372   else
6373     emit_insn (gen_eh_set_lr_si (operands[0]));
6374   DONE;
6377 ;; Clobber the return address on the stack.  We can't expand this
6378 ;; until we know where it will be put in the stack frame.
6380 (define_insn "eh_set_lr_si"
6381   [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
6382    (clobber (match_scratch:SI 1 "=&d"))]
6383   "! TARGET_64BIT"
6384   "#")
6386 (define_insn "eh_set_lr_di"
6387   [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
6388    (clobber (match_scratch:DI 1 "=&d"))]
6389   "TARGET_64BIT"
6390   "#")
6392 (define_split
6393   [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
6394    (clobber (match_scratch 1))]
6395   "reload_completed"
6396   [(const_int 0)]
6398   mips_set_return_address (operands[0], operands[1]);
6399   DONE;
6402 (define_expand "exception_receiver"
6403   [(const_int 0)]
6404   "TARGET_USE_GOT"
6406   /* See the comment above load_call<mode> for details.  */
6407   emit_insn (gen_set_got_version ());
6409   /* If we have a call-clobbered $gp, restore it from its save slot.  */
6410   if (HAVE_restore_gp_si)
6411     emit_insn (gen_restore_gp_si ());
6412   else if (HAVE_restore_gp_di)
6413     emit_insn (gen_restore_gp_di ());
6414   DONE;
6417 (define_expand "nonlocal_goto_receiver"
6418   [(const_int 0)]
6419   "TARGET_USE_GOT"
6421   /* See the comment above load_call<mode> for details.  */
6422   emit_insn (gen_set_got_version ());
6423   DONE;
6426 ;; Restore $gp from its .cprestore stack slot.  The instruction remains
6427 ;; volatile until all uses of $28 are exposed.
6428 (define_insn_and_split "restore_gp_<mode>"
6429   [(set (reg:P 28)
6430         (unspec_volatile:P [(const_int 0)] UNSPEC_RESTORE_GP))
6431    (clobber (match_scratch:P 0 "=&d"))]
6432   "TARGET_CALL_CLOBBERED_GP"
6433   "#"
6434   "&& epilogue_completed"
6435   [(const_int 0)]
6437   mips_restore_gp_from_cprestore_slot (operands[0]);
6438   DONE;
6440   [(set_attr "type" "ghost")])
6442 ;; Move between $gp and its register save slot.
6443 (define_insn_and_split "move_gp<mode>"
6444   [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,m")
6445         (unspec:GPR [(match_operand:GPR 1 "move_operand" "m,d")]
6446                     UNSPEC_MOVE_GP))]
6447   ""
6448   { return mips_must_initialize_gp_p () ? "#" : ""; }
6449   "mips_must_initialize_gp_p ()"
6450   [(const_int 0)]
6452   mips_emit_move (operands[0], operands[1]);
6453   DONE;
6455   [(set_attr "type" "ghost")])
6458 ;;  ....................
6460 ;;      FUNCTION CALLS
6462 ;;  ....................
6464 ;; Instructions to load a call address from the GOT.  The address might
6465 ;; point to a function or to a lazy binding stub.  In the latter case,
6466 ;; the stub will use the dynamic linker to resolve the function, which
6467 ;; in turn will change the GOT entry to point to the function's real
6468 ;; address.
6470 ;; This means that every call, even pure and constant ones, can
6471 ;; potentially modify the GOT entry.  And once a stub has been called,
6472 ;; we must not call it again.
6474 ;; We represent this restriction using an imaginary, fixed, call-saved
6475 ;; register called GOT_VERSION_REGNUM.  The idea is to make the register
6476 ;; live throughout the function and to change its value after every
6477 ;; potential call site.  This stops any rtx value that uses the register
6478 ;; from being computed before an earlier call.  To do this, we:
6480 ;;    - Ensure that the register is live on entry to the function,
6481 ;;      so that it is never thought to be used uninitalized.
6483 ;;    - Ensure that the register is live on exit from the function,
6484 ;;      so that it is live throughout.
6486 ;;    - Make each call (lazily-bound or not) use the current value
6487 ;;      of GOT_VERSION_REGNUM, so that updates of the register are
6488 ;;      not moved across call boundaries.
6490 ;;    - Add "ghost" definitions of the register to the beginning of
6491 ;;      blocks reached by EH and ABNORMAL_CALL edges, because those
6492 ;;      edges may involve calls that normal paths don't.  (E.g. the
6493 ;;      unwinding code that handles a non-call exception may change
6494 ;;      lazily-bound GOT entries.)  We do this by making the
6495 ;;      exception_receiver and nonlocal_goto_receiver expanders emit
6496 ;;      a set_got_version instruction.
6498 ;;    - After each call (lazily-bound or not), use a "ghost"
6499 ;;      update_got_version instruction to change the register's value.
6500 ;;      This instruction mimics the _possible_ effect of the dynamic
6501 ;;      resolver during the call and it remains live even if the call
6502 ;;      itself becomes dead.
6504 ;;    - Leave GOT_VERSION_REGNUM out of all register classes.
6505 ;;      The register is therefore not a valid register_operand
6506 ;;      and cannot be moved to or from other registers.
6508 (define_insn "load_call<mode>"
6509   [(set (match_operand:P 0 "register_operand" "=d")
6510         (unspec:P [(match_operand:P 1 "register_operand" "d")
6511                    (match_operand:P 2 "immediate_operand" "")
6512                    (reg:SI GOT_VERSION_REGNUM)] UNSPEC_LOAD_CALL))]
6513   "TARGET_USE_GOT"
6514   "<load>\t%0,%R2(%1)"
6515   [(set_attr "got" "load")
6516    (set_attr "mode" "<MODE>")])
6518 (define_insn "set_got_version"
6519   [(set (reg:SI GOT_VERSION_REGNUM)
6520         (unspec_volatile:SI [(const_int 0)] UNSPEC_SET_GOT_VERSION))]
6521   "TARGET_USE_GOT"
6522   ""
6523   [(set_attr "type" "ghost")])
6525 (define_insn "update_got_version"
6526   [(set (reg:SI GOT_VERSION_REGNUM)
6527         (unspec:SI [(reg:SI GOT_VERSION_REGNUM)] UNSPEC_UPDATE_GOT_VERSION))]
6528   "TARGET_USE_GOT"
6529   ""
6530   [(set_attr "type" "ghost")])
6532 ;; Sibling calls.  All these patterns use jump instructions.
6534 ;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
6535 ;; addresses if a direct jump is acceptable.  Since the 'S' constraint
6536 ;; is defined in terms of call_insn_operand, the same is true of the
6537 ;; constraints.
6539 ;; When we use an indirect jump, we need a register that will be
6540 ;; preserved by the epilogue.  Since TARGET_USE_PIC_FN_ADDR_REG forces
6541 ;; us to use $25 for this purpose -- and $25 is never clobbered by the
6542 ;; epilogue -- we might as well use it for !TARGET_USE_PIC_FN_ADDR_REG
6543 ;; as well.
6545 (define_expand "sibcall"
6546   [(parallel [(call (match_operand 0 "")
6547                     (match_operand 1 ""))
6548               (use (match_operand 2 ""))        ;; next_arg_reg
6549               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
6550   "TARGET_SIBCALLS"
6552   mips_expand_call (MIPS_CALL_SIBCALL, NULL_RTX, XEXP (operands[0], 0),
6553                     operands[1], operands[2], false);
6554   DONE;
6557 (define_insn "sibcall_internal"
6558   [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
6559          (match_operand 1 "" ""))]
6560   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6562   if (TARGET_MICROMIPS)
6563     return MICROMIPS_J ("j", operands, 0);
6564   else
6565     return MIPS_CALL ("j", operands, 0, 1);
6567   [(set_attr "jal" "indirect,direct")
6568    (set_attr "jal_macro" "no")])
6570 (define_expand "sibcall_value"
6571   [(parallel [(set (match_operand 0 "")
6572                    (call (match_operand 1 "")
6573                          (match_operand 2 "")))
6574               (use (match_operand 3 ""))])]             ;; next_arg_reg
6575   "TARGET_SIBCALLS"
6577   mips_expand_call (MIPS_CALL_SIBCALL, operands[0], XEXP (operands[1], 0),
6578                     operands[2], operands[3], false);
6579   DONE;
6582 (define_insn "sibcall_value_internal"
6583   [(set (match_operand 0 "register_operand" "")
6584         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
6585               (match_operand 2 "" "")))]
6586   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6588   if (TARGET_MICROMIPS)
6589     return MICROMIPS_J ("j", operands, 1);
6590   else
6591     return MIPS_CALL ("j", operands, 1, 2);
6593   [(set_attr "jal" "indirect,direct")
6594    (set_attr "jal_macro" "no")])
6596 (define_insn "sibcall_value_multiple_internal"
6597   [(set (match_operand 0 "register_operand" "")
6598         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
6599               (match_operand 2 "" "")))
6600    (set (match_operand 3 "register_operand" "")
6601         (call (mem:SI (match_dup 1))
6602               (match_dup 2)))]
6603   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6605   if (TARGET_MICROMIPS)
6606     return MICROMIPS_J ("j", operands, 1);
6607   else
6608     return MIPS_CALL ("j", operands, 1, 2);
6610   [(set_attr "jal" "indirect,direct")
6611    (set_attr "jal_macro" "no")])
6613 (define_expand "call"
6614   [(parallel [(call (match_operand 0 "")
6615                     (match_operand 1 ""))
6616               (use (match_operand 2 ""))        ;; next_arg_reg
6617               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
6618   ""
6620   mips_expand_call (MIPS_CALL_NORMAL, NULL_RTX, XEXP (operands[0], 0),
6621                     operands[1], operands[2], false);
6622   DONE;
6625 ;; This instruction directly corresponds to an assembly-language "jal".
6626 ;; There are four cases:
6628 ;;    - -mno-abicalls:
6629 ;;        Both symbolic and register destinations are OK.  The pattern
6630 ;;        always expands to a single mips instruction.
6632 ;;    - -mabicalls/-mno-explicit-relocs:
6633 ;;        Again, both symbolic and register destinations are OK.
6634 ;;        The call is treated as a multi-instruction black box.
6636 ;;    - -mabicalls/-mexplicit-relocs with n32 or n64:
6637 ;;        Only "jal $25" is allowed.  This expands to a single "jalr $25"
6638 ;;        instruction.
6640 ;;    - -mabicalls/-mexplicit-relocs with o32 or o64:
6641 ;;        Only "jal $25" is allowed.  The call is actually two instructions:
6642 ;;        "jalr $25" followed by an insn to reload $gp.
6644 ;; In the last case, we can generate the individual instructions with
6645 ;; a define_split.  There are several things to be wary of:
6647 ;;   - We can't expose the load of $gp before reload.  If we did,
6648 ;;     it might get removed as dead, but reload can introduce new
6649 ;;     uses of $gp by rematerializing constants.
6651 ;;   - We shouldn't restore $gp after calls that never return.
6652 ;;     It isn't valid to insert instructions between a noreturn
6653 ;;     call and the following barrier.
6655 ;;   - The splitter deliberately changes the liveness of $gp.  The unsplit
6656 ;;     instruction preserves $gp and so have no effect on its liveness.
6657 ;;     But once we generate the separate insns, it becomes obvious that
6658 ;;     $gp is not live on entry to the call.
6660 (define_insn_and_split "call_internal"
6661   [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
6662          (match_operand 1 "" ""))
6663    (clobber (reg:SI RETURN_ADDR_REGNUM))]
6664   ""
6665   { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 0, 1); }
6666   "reload_completed && TARGET_SPLIT_CALLS"
6667   [(const_int 0)]
6669   mips_split_call (curr_insn, gen_call_split (operands[0], operands[1]));
6670   DONE;
6672   [(set_attr "jal" "indirect,direct")])
6674 (define_insn "call_split"
6675   [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
6676          (match_operand 1 "" ""))
6677    (clobber (reg:SI RETURN_ADDR_REGNUM))
6678    (clobber (reg:SI 28))]
6679   "TARGET_SPLIT_CALLS"
6680   { return MIPS_CALL ("jal", operands, 0, 1); }
6681   [(set_attr "jal" "indirect,direct")
6682    (set_attr "jal_macro" "no")])
6684 ;; A pattern for calls that must be made directly.  It is used for
6685 ;; MIPS16 calls that the linker may need to redirect to a hard-float
6686 ;; stub; the linker relies on the call relocation type to detect when
6687 ;; such redirection is needed.
6688 (define_insn_and_split "call_internal_direct"
6689   [(call (mem:SI (match_operand 0 "const_call_insn_operand"))
6690          (match_operand 1))
6691    (const_int 1)
6692    (clobber (reg:SI RETURN_ADDR_REGNUM))]
6693   ""
6694   { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 0, -1); }
6695   "reload_completed && TARGET_SPLIT_CALLS"
6696   [(const_int 0)]
6698   mips_split_call (curr_insn,
6699                    gen_call_direct_split (operands[0], operands[1]));
6700   DONE;
6702   [(set_attr "jal" "direct")])
6704 (define_insn "call_direct_split"
6705   [(call (mem:SI (match_operand 0 "const_call_insn_operand"))
6706          (match_operand 1))
6707    (const_int 1)
6708    (clobber (reg:SI RETURN_ADDR_REGNUM))
6709    (clobber (reg:SI 28))]
6710   "TARGET_SPLIT_CALLS"
6711   { return MIPS_CALL ("jal", operands, 0, -1); }
6712   [(set_attr "jal" "direct")
6713    (set_attr "jal_macro" "no")])
6715 (define_expand "call_value"
6716   [(parallel [(set (match_operand 0 "")
6717                    (call (match_operand 1 "")
6718                          (match_operand 2 "")))
6719               (use (match_operand 3 ""))])]             ;; next_arg_reg
6720   ""
6722   mips_expand_call (MIPS_CALL_NORMAL, operands[0], XEXP (operands[1], 0),
6723                     operands[2], operands[3], false);
6724   DONE;
6727 ;; See comment for call_internal.
6728 (define_insn_and_split "call_value_internal"
6729   [(set (match_operand 0 "register_operand" "")
6730         (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
6731               (match_operand 2 "" "")))
6732    (clobber (reg:SI RETURN_ADDR_REGNUM))]
6733   ""
6734   { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1, 2); }
6735   "reload_completed && TARGET_SPLIT_CALLS"
6736   [(const_int 0)]
6738   mips_split_call (curr_insn,
6739                    gen_call_value_split (operands[0], operands[1],
6740                                          operands[2]));
6741   DONE;
6743   [(set_attr "jal" "indirect,direct")])
6745 (define_insn "call_value_split"
6746   [(set (match_operand 0 "register_operand" "")
6747         (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
6748               (match_operand 2 "" "")))
6749    (clobber (reg:SI RETURN_ADDR_REGNUM))
6750    (clobber (reg:SI 28))]
6751   "TARGET_SPLIT_CALLS"
6752   { return MIPS_CALL ("jal", operands, 1, 2); }
6753   [(set_attr "jal" "indirect,direct")
6754    (set_attr "jal_macro" "no")])
6756 ;; See call_internal_direct.
6757 (define_insn_and_split "call_value_internal_direct"
6758   [(set (match_operand 0 "register_operand")
6759         (call (mem:SI (match_operand 1 "const_call_insn_operand"))
6760               (match_operand 2)))
6761    (const_int 1)
6762    (clobber (reg:SI RETURN_ADDR_REGNUM))]
6763   ""
6764   { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1, -1); }
6765   "reload_completed && TARGET_SPLIT_CALLS"
6766   [(const_int 0)]
6768   mips_split_call (curr_insn,
6769                    gen_call_value_direct_split (operands[0], operands[1],
6770                                                 operands[2]));
6771   DONE;
6773   [(set_attr "jal" "direct")])
6775 (define_insn "call_value_direct_split"
6776   [(set (match_operand 0 "register_operand")
6777         (call (mem:SI (match_operand 1 "const_call_insn_operand"))
6778               (match_operand 2)))
6779    (const_int 1)
6780    (clobber (reg:SI RETURN_ADDR_REGNUM))
6781    (clobber (reg:SI 28))]
6782   "TARGET_SPLIT_CALLS"
6783   { return MIPS_CALL ("jal", operands, 1, -1); }
6784   [(set_attr "jal" "direct")
6785    (set_attr "jal_macro" "no")])
6787 ;; See comment for call_internal.
6788 (define_insn_and_split "call_value_multiple_internal"
6789   [(set (match_operand 0 "register_operand" "")
6790         (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
6791               (match_operand 2 "" "")))
6792    (set (match_operand 3 "register_operand" "")
6793         (call (mem:SI (match_dup 1))
6794               (match_dup 2)))
6795    (clobber (reg:SI RETURN_ADDR_REGNUM))]
6796   ""
6797   { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1, 2); }
6798   "reload_completed && TARGET_SPLIT_CALLS"
6799   [(const_int 0)]
6801   mips_split_call (curr_insn,
6802                    gen_call_value_multiple_split (operands[0], operands[1],
6803                                                   operands[2], operands[3]));
6804   DONE;
6806   [(set_attr "jal" "indirect,direct")])
6808 (define_insn "call_value_multiple_split"
6809   [(set (match_operand 0 "register_operand" "")
6810         (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
6811               (match_operand 2 "" "")))
6812    (set (match_operand 3 "register_operand" "")
6813         (call (mem:SI (match_dup 1))
6814               (match_dup 2)))
6815    (clobber (reg:SI RETURN_ADDR_REGNUM))
6816    (clobber (reg:SI 28))]
6817   "TARGET_SPLIT_CALLS"
6818   { return MIPS_CALL ("jal", operands, 1, 2); }
6819   [(set_attr "jal" "indirect,direct")
6820    (set_attr "jal_macro" "no")])
6822 ;; Call subroutine returning any type.
6824 (define_expand "untyped_call"
6825   [(parallel [(call (match_operand 0 "")
6826                     (const_int 0))
6827               (match_operand 1 "")
6828               (match_operand 2 "")])]
6829   ""
6831   int i;
6833   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
6835   for (i = 0; i < XVECLEN (operands[2], 0); i++)
6836     {
6837       rtx set = XVECEXP (operands[2], 0, i);
6838       mips_emit_move (SET_DEST (set), SET_SRC (set));
6839     }
6841   emit_insn (gen_blockage ());
6842   DONE;
6846 ;;  ....................
6848 ;;      MISC.
6850 ;;  ....................
6854 (define_insn "prefetch"
6855   [(prefetch (match_operand:QI 0 "address_operand" "ZD")
6856              (match_operand 1 "const_int_operand" "n")
6857              (match_operand 2 "const_int_operand" "n"))]
6858   "ISA_HAS_PREFETCH && TARGET_EXPLICIT_RELOCS"
6860   if (TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A)
6861     {
6862       /* Loongson 2[ef] and Loongson 3a use load to $0 for prefetching.  */
6863       if (TARGET_64BIT)
6864         return "ld\t$0,%a0";
6865       else
6866         return "lw\t$0,%a0";
6867     }
6868   operands[1] = mips_prefetch_cookie (operands[1], operands[2]);
6869   return "pref\t%1,%a0";
6871   [(set_attr "type" "prefetch")])
6873 (define_insn "*prefetch_indexed_<mode>"
6874   [(prefetch (plus:P (match_operand:P 0 "register_operand" "d")
6875                      (match_operand:P 1 "register_operand" "d"))
6876              (match_operand 2 "const_int_operand" "n")
6877              (match_operand 3 "const_int_operand" "n"))]
6878   "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6880   operands[2] = mips_prefetch_cookie (operands[2], operands[3]);
6881   return "prefx\t%2,%1(%0)";
6883   [(set_attr "type" "prefetchx")])
6885 (define_insn "nop"
6886   [(const_int 0)]
6887   ""
6888   "%(nop%)"
6889   [(set_attr "type"     "nop")
6890    (set_attr "mode"     "none")])
6892 ;; Like nop, but commented out when outside a .set noreorder block.
6893 (define_insn "hazard_nop"
6894   [(const_int 1)]
6895   ""
6896   {
6897     if (mips_noreorder.nesting_level > 0)
6898       return "nop";
6899     else
6900       return "#nop";
6901   }
6902   [(set_attr "type"     "nop")])
6904 ;; MIPS4 Conditional move instructions.
6906 (define_insn "*mov<GPR:mode>_on_<MOVECC:mode>"
6907   [(set (match_operand:GPR 0 "register_operand" "=d,d")
6908         (if_then_else:GPR
6909          (match_operator 4 "equality_operator"
6910                 [(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>")
6911                  (const_int 0)])
6912          (match_operand:GPR 2 "reg_or_0_operand" "dJ,0")
6913          (match_operand:GPR 3 "reg_or_0_operand" "0,dJ")))]
6914   "ISA_HAS_CONDMOVE"
6915   "@
6916     mov%T4\t%0,%z2,%1
6917     mov%t4\t%0,%z3,%1"
6918   [(set_attr "type" "condmove")
6919    (set_attr "mode" "<GPR:MODE>")])
6921 (define_insn "*mov<GPR:mode>_on_<GPR2:mode>_ne"
6922   [(set (match_operand:GPR 0 "register_operand" "=d,d")
6923        (if_then_else:GPR
6924         (match_operand:GPR2 1 "register_operand" "<GPR2:reg>,<GPR2:reg>")
6925         (match_operand:GPR 2 "reg_or_0_operand" "dJ,0")
6926         (match_operand:GPR 3 "reg_or_0_operand" "0,dJ")))]
6927   "ISA_HAS_CONDMOVE"
6928   "@
6929     movn\t%0,%z2,%1
6930     movz\t%0,%z3,%1"
6931   [(set_attr "type" "condmove")
6932    (set_attr "mode" "<GPR:MODE>")])
6934 (define_insn "*mov<SCALARF:mode>_on_<MOVECC:mode>"
6935   [(set (match_operand:SCALARF 0 "register_operand" "=f,f")
6936         (if_then_else:SCALARF
6937          (match_operator 4 "equality_operator"
6938                 [(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>")
6939                  (const_int 0)])
6940          (match_operand:SCALARF 2 "register_operand" "f,0")
6941          (match_operand:SCALARF 3 "register_operand" "0,f")))]
6942   "ISA_HAS_FP_CONDMOVE"
6943   "@
6944     mov%T4.<fmt>\t%0,%2,%1
6945     mov%t4.<fmt>\t%0,%3,%1"
6946   [(set_attr "type" "condmove")
6947    (set_attr "mode" "<SCALARF:MODE>")])
6949 ;; These are the main define_expand's used to make conditional moves.
6951 (define_expand "mov<mode>cc"
6952   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
6953    (set (match_operand:GPR 0 "register_operand")
6954         (if_then_else:GPR (match_dup 5)
6955                           (match_operand:GPR 2 "reg_or_0_operand")
6956                           (match_operand:GPR 3 "reg_or_0_operand")))]
6957   "ISA_HAS_CONDMOVE"
6959   mips_expand_conditional_move (operands);
6960   DONE;
6963 (define_expand "mov<mode>cc"
6964   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
6965    (set (match_operand:SCALARF 0 "register_operand")
6966         (if_then_else:SCALARF (match_dup 5)
6967                               (match_operand:SCALARF 2 "register_operand")
6968                               (match_operand:SCALARF 3 "register_operand")))]
6969   "ISA_HAS_FP_CONDMOVE"
6971   mips_expand_conditional_move (operands);
6972   DONE;
6976 ;;  ....................
6978 ;;      mips16 inline constant tables
6980 ;;  ....................
6983 (define_insn "consttable_tls_reloc"
6984   [(unspec_volatile [(match_operand 0 "tls_reloc_operand" "")
6985                      (match_operand 1 "const_int_operand" "")]
6986                     UNSPEC_CONSTTABLE_INT)]
6987   "TARGET_MIPS16_PCREL_LOADS"
6988   { return mips_output_tls_reloc_directive (&operands[0]); }
6989   [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
6991 (define_insn "consttable_int"
6992   [(unspec_volatile [(match_operand 0 "consttable_operand" "")
6993                      (match_operand 1 "const_int_operand" "")]
6994                     UNSPEC_CONSTTABLE_INT)]
6995   "TARGET_MIPS16"
6997   assemble_integer (mips_strip_unspec_address (operands[0]),
6998                     INTVAL (operands[1]),
6999                     BITS_PER_UNIT * INTVAL (operands[1]), 1);
7000   return "";
7002   [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
7004 (define_insn "consttable_float"
7005   [(unspec_volatile [(match_operand 0 "consttable_operand" "")]
7006                     UNSPEC_CONSTTABLE_FLOAT)]
7007   "TARGET_MIPS16"
7009   REAL_VALUE_TYPE d;
7011   gcc_assert (GET_CODE (operands[0]) == CONST_DOUBLE);
7012   REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7013   assemble_real (d, GET_MODE (operands[0]),
7014                  GET_MODE_BITSIZE (GET_MODE (operands[0])));
7015   return "";
7017   [(set (attr "length")
7018         (symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))])
7020 (define_insn "align"
7021   [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)]
7022   ""
7023   ".align\t%0"
7024   [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))])
7026 (define_split
7027   [(match_operand 0 "small_data_pattern")]
7028   "reload_completed"
7029   [(match_dup 0)]
7030   { operands[0] = mips_rewrite_small_data (operands[0]); })
7033 ;;  ....................
7035 ;;      MIPS16e Save/Restore
7037 ;;  ....................
7040 (define_insn "*mips16e_save_restore"
7041   [(match_parallel 0 ""
7042        [(set (match_operand:SI 1 "register_operand")
7043              (plus:SI (match_dup 1)
7044                       (match_operand:SI 2 "const_int_operand")))])]
7045   "operands[1] == stack_pointer_rtx
7046    && mips16e_save_restore_pattern_p (operands[0], INTVAL (operands[2]), NULL)"
7047   { return mips16e_output_save_restore (operands[0], INTVAL (operands[2])); }
7048   [(set_attr "type" "arith")
7049    (set_attr "extended_mips16" "yes")])
7051 ;; Thread-Local Storage
7053 ;; The TLS base pointer is accessed via "rdhwr $3, $29".  No current
7054 ;; MIPS architecture defines this register, and no current
7055 ;; implementation provides it; instead, any OS which supports TLS is
7056 ;; expected to trap and emulate this instruction.  rdhwr is part of the
7057 ;; MIPS 32r2 specification, but we use it on any architecture because
7058 ;; we expect it to be emulated.  Use .set to force the assembler to
7059 ;; accept it.
7061 ;; We do not use a constraint to force the destination to be $3
7062 ;; because $3 can appear explicitly as a function return value.
7063 ;; If we leave the use of $3 implicit in the constraints until
7064 ;; reload, we may end up making a $3 return value live across
7065 ;; the instruction, leading to a spill failure when reloading it.
7066 (define_insn_and_split "tls_get_tp_<mode>"
7067   [(set (match_operand:P 0 "register_operand" "=d")
7068         (unspec:P [(const_int 0)] UNSPEC_TLS_GET_TP))
7069    (clobber (reg:P TLS_GET_TP_REGNUM))]
7070   "HAVE_AS_TLS && !TARGET_MIPS16"
7071   "#"
7072   "&& reload_completed"
7073   [(set (reg:P TLS_GET_TP_REGNUM)
7074         (unspec:P [(const_int 0)] UNSPEC_TLS_GET_TP))
7075    (set (match_dup 0) (reg:P TLS_GET_TP_REGNUM))]
7076   ""
7077   [(set_attr "type" "unknown")
7078    (set_attr "mode" "<MODE>")
7079    (set_attr "insn_count" "2")])
7081 (define_insn "*tls_get_tp_<mode>_split"
7082   [(set (reg:P TLS_GET_TP_REGNUM)
7083         (unspec:P [(const_int 0)] UNSPEC_TLS_GET_TP))]
7084   "HAVE_AS_TLS && !TARGET_MIPS16"
7085   ".set\tpush\;.set\tmips32r2\t\;rdhwr\t$3,$29\;.set\tpop"
7086   [(set_attr "type" "unknown")
7087    ; Since rdhwr always generates a trap for now, putting it in a delay
7088    ; slot would make the kernel's emulation of it much slower.
7089    (set_attr "can_delay" "no")
7090    (set_attr "mode" "<MODE>")])
7092 ;; In MIPS16 mode, the TLS base pointer is accessed by a
7093 ;; libgcc helper function __mips16_rdhwr(), as 'rdhwr' is not
7094 ;; accessible in MIPS16.
7096 ;; This is not represented as a call insn, to avoid the
7097 ;; unnecesarry clobbering of caller-save registers by a
7098 ;; function consisting only of: "rdhwr $3,$29; j $31; nop;"
7100 ;; A $25 clobber is added to cater for a $25 load stub added by the
7101 ;; linker to __mips16_rdhwr when the call is made from non-PIC code.
7103 (define_insn_and_split "tls_get_tp_mips16_<mode>"
7104   [(set (match_operand:P 0 "register_operand" "=d")
7105         (unspec:P [(match_operand:P 1 "call_insn_operand" "dS")]
7106                   UNSPEC_TLS_GET_TP))
7107    (clobber (reg:P TLS_GET_TP_REGNUM))
7108    (clobber (reg:P PIC_FUNCTION_ADDR_REGNUM))
7109    (clobber (reg:P RETURN_ADDR_REGNUM))]
7110   "HAVE_AS_TLS && TARGET_MIPS16"
7111   "#"
7112   "&& reload_completed"
7113   [(parallel [(set (reg:P TLS_GET_TP_REGNUM)
7114                    (unspec:P [(match_dup 1)] UNSPEC_TLS_GET_TP))
7115               (clobber (reg:P PIC_FUNCTION_ADDR_REGNUM))
7116               (clobber (reg:P RETURN_ADDR_REGNUM))])
7117    (set (match_dup 0) (reg:P TLS_GET_TP_REGNUM))]
7118   ""
7119   [(set_attr "type" "multi")
7120    (set_attr "insn_count" "4")
7121    (set_attr "mode" "<MODE>")])
7123 (define_insn "*tls_get_tp_mips16_call_<mode>"
7124   [(set (reg:P TLS_GET_TP_REGNUM)
7125         (unspec:P [(match_operand:P 0 "call_insn_operand" "dS")]
7126                   UNSPEC_TLS_GET_TP))
7127    (clobber (reg:P PIC_FUNCTION_ADDR_REGNUM))
7128    (clobber (reg:P RETURN_ADDR_REGNUM))]
7129   "HAVE_AS_TLS && TARGET_MIPS16"
7130   { return MIPS_CALL ("jal", operands, 0, -1); }
7131   [(set_attr "type" "call")
7132    (set_attr "insn_count" "3")
7133    (set_attr "mode" "<MODE>")])
7135 ;; Named pattern for expanding thread pointer reference.
7136 (define_expand "get_thread_pointer<mode>"
7137   [(match_operand:P 0 "register_operand" "=d")]
7138   "HAVE_AS_TLS"
7140   mips_expand_thread_pointer (operands[0]);
7141   DONE;
7144 ;; __builtin_mips_get_fcsr: move the FCSR into operand 0.
7145 (define_expand "mips_get_fcsr"
7146   [(set (match_operand:SI 0 "register_operand")
7147         (unspec_volatile [(const_int 0)] UNSPEC_GET_FCSR))]
7148   "TARGET_HARD_FLOAT_ABI"
7150   if (TARGET_MIPS16)
7151     {
7152       mips16_expand_get_fcsr (operands[0]);
7153       DONE;
7154     }
7157 (define_insn "*mips_get_fcsr"
7158   [(set (match_operand:SI 0 "register_operand" "=d")
7159         (unspec_volatile [(const_int 0)] UNSPEC_GET_FCSR))]
7160   "TARGET_HARD_FLOAT"
7161   "cfc1\t%0,$31")
7163 ;; See tls_get_tp_mips16_<mode> for why this form is used.
7164 (define_insn "mips_get_fcsr_mips16_<mode>"
7165   [(set (reg:SI GET_FCSR_REGNUM)
7166         (unspec:SI [(match_operand:P 0 "call_insn_operand" "dS")]
7167                    UNSPEC_GET_FCSR))
7168    (clobber (reg:P PIC_FUNCTION_ADDR_REGNUM))
7169    (clobber (reg:P RETURN_ADDR_REGNUM))]
7170   "TARGET_HARD_FLOAT_ABI && TARGET_MIPS16"
7171   { return MIPS_CALL ("jal", operands, 0, -1); }
7172   [(set_attr "type" "call")
7173    (set_attr "insn_count" "3")])
7175 ;; __builtin_mips_set_fcsr: move operand 0 into the FCSR.
7176 (define_expand "mips_set_fcsr"
7177   [(unspec_volatile [(match_operand:SI 0 "register_operand")]
7178                     UNSPEC_SET_FCSR)]
7179   "TARGET_HARD_FLOAT_ABI"
7181   if (TARGET_MIPS16)
7182     {
7183       mips16_expand_set_fcsr (operands[0]);
7184       DONE;
7185     }
7188 (define_insn "*mips_set_fcsr"
7189   [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")]
7190                     UNSPEC_SET_FCSR)]
7191   "TARGET_HARD_FLOAT"
7192   "ctc1\t%0,$31")
7194 ;; See tls_get_tp_mips16_<mode> for why this form is used.
7195 (define_insn "mips_set_fcsr_mips16_<mode>"
7196   [(unspec_volatile:SI [(match_operand:P 0 "call_insn_operand" "dS")
7197                         (reg:SI SET_FCSR_REGNUM)] UNSPEC_SET_FCSR)
7198    (clobber (reg:P PIC_FUNCTION_ADDR_REGNUM))
7199    (clobber (reg:P RETURN_ADDR_REGNUM))]
7200   "TARGET_HARD_FLOAT_ABI && TARGET_MIPS16"
7201   { return MIPS_CALL ("jal", operands, 0, -1); }
7202   [(set_attr "type" "call")
7203    (set_attr "insn_count" "3")])
7205 ;; Synchronization instructions.
7207 (include "sync.md")
7209 ; The MIPS Paired-Single Floating Point and MIPS-3D Instructions.
7211 (include "mips-ps-3d.md")
7213 ; The MIPS DSP Instructions.
7215 (include "mips-dsp.md")
7217 ; The MIPS DSP REV 2 Instructions.
7219 (include "mips-dspr2.md")
7221 ; MIPS fixed-point instructions.
7222 (include "mips-fixed.md")
7224 ; microMIPS patterns.
7225 (include "micromips.md")
7227 ; ST-Microelectronics Loongson-2E/2F-specific patterns.
7228 (include "loongson.md")
7230 (define_c_enum "unspec" [
7231   UNSPEC_ADDRESS_FIRST