2008-05-30 Vladimir Makarov <vmakarov@redhat.com>
[official-gcc.git] / gcc / config / mips / mips.md
blob592ad528042fd2556d6f4ba3d610501f2e98247d
1 ;;  Mips.md          Machine Description for MIPS based processors
2 ;;  Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;;  1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
4 ;;  Free Software Foundation, Inc.
5 ;;  Contributed by   A. Lichnewsky, lich@inria.inria.fr
6 ;;  Changes by       Michael Meissner, meissner@osf.org
7 ;;  64-bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
8 ;;  Brendan Eich, brendan@microunity.com.
10 ;; This file is part of GCC.
12 ;; GCC is free software; you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; any later version.
17 ;; GCC is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 ;; GNU General Public License for more details.
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GCC; see the file COPYING3.  If not see
24 ;; <http://www.gnu.org/licenses/>.
26 (define_constants
27   [(UNSPEC_LOAD_LOW              0)
28    (UNSPEC_LOAD_HIGH             1)
29    (UNSPEC_STORE_WORD            2)
30    (UNSPEC_GET_FNADDR            3)
31    (UNSPEC_BLOCKAGE              4)
32    (UNSPEC_CPRESTORE             5)
33    (UNSPEC_RESTORE_GP            6)
34    (UNSPEC_EH_RETURN             7)
35    (UNSPEC_CONSTTABLE_INT        8)
36    (UNSPEC_CONSTTABLE_FLOAT      9)
37    (UNSPEC_ALIGN                14)
38    (UNSPEC_HIGH                 17)
39    (UNSPEC_LOAD_LEFT            18)
40    (UNSPEC_LOAD_RIGHT           19)
41    (UNSPEC_STORE_LEFT           20)
42    (UNSPEC_STORE_RIGHT          21)
43    (UNSPEC_LOADGP               22)
44    (UNSPEC_LOAD_CALL            23)
45    (UNSPEC_LOAD_GOT             24)
46    (UNSPEC_GP                   25)
47    (UNSPEC_MFHILO               26)
48    (UNSPEC_TLS_LDM              27)
49    (UNSPEC_TLS_GET_TP           28)
50    (UNSPEC_MFHC1                31)
51    (UNSPEC_MTHC1                32)
52    (UNSPEC_CLEAR_HAZARD         33)
53    (UNSPEC_RDHWR                34)
54    (UNSPEC_SYNCI                35)
55    (UNSPEC_SYNC                 36)
56    (UNSPEC_COMPARE_AND_SWAP     37)
57    (UNSPEC_COMPARE_AND_SWAP_12  38)
58    (UNSPEC_SYNC_OLD_OP          39)
59    (UNSPEC_SYNC_NEW_OP          40)
60    (UNSPEC_SYNC_NEW_OP_12       41)
61    (UNSPEC_SYNC_OLD_OP_12       42)
62    (UNSPEC_SYNC_EXCHANGE        43)
63    (UNSPEC_SYNC_EXCHANGE_12     44)
64    (UNSPEC_MEMORY_BARRIER       45)
65    (UNSPEC_SET_GOT_VERSION      46)
66    (UNSPEC_UPDATE_GOT_VERSION   47)
67    
68    (UNSPEC_ADDRESS_FIRST        100)
70    (GOT_VERSION_REGNUM          79)
72    ;; For MIPS Paired-Singled Floating Point Instructions.
74    (UNSPEC_MOVE_TF_PS           200)
75    (UNSPEC_C                    201)
77    ;; MIPS64/MIPS32R2 alnv.ps
78    (UNSPEC_ALNV_PS              202)
80    ;; MIPS-3D instructions
81    (UNSPEC_CABS                 203)
83    (UNSPEC_ADDR_PS              204)
84    (UNSPEC_CVT_PW_PS            205)
85    (UNSPEC_CVT_PS_PW            206)
86    (UNSPEC_MULR_PS              207)
87    (UNSPEC_ABS_PS               208)
89    (UNSPEC_RSQRT1               209)
90    (UNSPEC_RSQRT2               210)
91    (UNSPEC_RECIP1               211)
92    (UNSPEC_RECIP2               212)
93    (UNSPEC_SINGLE_CC            213)
94    (UNSPEC_SCC                  214)
96    ;; MIPS DSP ASE Revision 0.98 3/24/2005
97    (UNSPEC_ADDQ                 300)
98    (UNSPEC_ADDQ_S               301)
99    (UNSPEC_SUBQ                 302)
100    (UNSPEC_SUBQ_S               303)
101    (UNSPEC_ADDSC                304)
102    (UNSPEC_ADDWC                305)
103    (UNSPEC_MODSUB               306)
104    (UNSPEC_RADDU_W_QB           307)
105    (UNSPEC_ABSQ_S               308)
106    (UNSPEC_PRECRQ_QB_PH         309)
107    (UNSPEC_PRECRQ_PH_W          310)
108    (UNSPEC_PRECRQ_RS_PH_W       311)
109    (UNSPEC_PRECRQU_S_QB_PH      312)
110    (UNSPEC_PRECEQ_W_PHL         313)
111    (UNSPEC_PRECEQ_W_PHR         314)
112    (UNSPEC_PRECEQU_PH_QBL       315)
113    (UNSPEC_PRECEQU_PH_QBR       316)
114    (UNSPEC_PRECEQU_PH_QBLA      317)
115    (UNSPEC_PRECEQU_PH_QBRA      318)
116    (UNSPEC_PRECEU_PH_QBL        319)
117    (UNSPEC_PRECEU_PH_QBR        320)
118    (UNSPEC_PRECEU_PH_QBLA       321)
119    (UNSPEC_PRECEU_PH_QBRA       322)
120    (UNSPEC_SHLL                 323)
121    (UNSPEC_SHLL_S               324)
122    (UNSPEC_SHRL_QB              325)
123    (UNSPEC_SHRA_PH              326)
124    (UNSPEC_SHRA_R               327)
125    (UNSPEC_MULEU_S_PH_QBL       328)
126    (UNSPEC_MULEU_S_PH_QBR       329)
127    (UNSPEC_MULQ_RS_PH           330)
128    (UNSPEC_MULEQ_S_W_PHL        331)
129    (UNSPEC_MULEQ_S_W_PHR        332)
130    (UNSPEC_DPAU_H_QBL           333)
131    (UNSPEC_DPAU_H_QBR           334)
132    (UNSPEC_DPSU_H_QBL           335)
133    (UNSPEC_DPSU_H_QBR           336)
134    (UNSPEC_DPAQ_S_W_PH          337)
135    (UNSPEC_DPSQ_S_W_PH          338)
136    (UNSPEC_MULSAQ_S_W_PH        339)
137    (UNSPEC_DPAQ_SA_L_W          340)
138    (UNSPEC_DPSQ_SA_L_W          341)
139    (UNSPEC_MAQ_S_W_PHL          342)
140    (UNSPEC_MAQ_S_W_PHR          343)
141    (UNSPEC_MAQ_SA_W_PHL         344)
142    (UNSPEC_MAQ_SA_W_PHR         345)
143    (UNSPEC_BITREV               346)
144    (UNSPEC_INSV                 347)
145    (UNSPEC_REPL_QB              348)
146    (UNSPEC_REPL_PH              349)
147    (UNSPEC_CMP_EQ               350)
148    (UNSPEC_CMP_LT               351)
149    (UNSPEC_CMP_LE               352)
150    (UNSPEC_CMPGU_EQ_QB          353)
151    (UNSPEC_CMPGU_LT_QB          354)
152    (UNSPEC_CMPGU_LE_QB          355)
153    (UNSPEC_PICK                 356)
154    (UNSPEC_PACKRL_PH            357)
155    (UNSPEC_EXTR_W               358)
156    (UNSPEC_EXTR_R_W             359)
157    (UNSPEC_EXTR_RS_W            360)
158    (UNSPEC_EXTR_S_H             361)
159    (UNSPEC_EXTP                 362)
160    (UNSPEC_EXTPDP               363)
161    (UNSPEC_SHILO                364)
162    (UNSPEC_MTHLIP               365)
163    (UNSPEC_WRDSP                366)
164    (UNSPEC_RDDSP                367)
166    ;; MIPS DSP ASE REV 2 Revision 0.02 11/24/2006
167    (UNSPEC_ABSQ_S_QB            400)
168    (UNSPEC_ADDU_PH              401)
169    (UNSPEC_ADDU_S_PH            402)
170    (UNSPEC_ADDUH_QB             403)
171    (UNSPEC_ADDUH_R_QB           404)
172    (UNSPEC_APPEND               405)
173    (UNSPEC_BALIGN               406)
174    (UNSPEC_CMPGDU_EQ_QB         407)
175    (UNSPEC_CMPGDU_LT_QB         408)
176    (UNSPEC_CMPGDU_LE_QB         409)
177    (UNSPEC_DPA_W_PH             410)
178    (UNSPEC_DPS_W_PH             411)
179    (UNSPEC_MADD                 412)
180    (UNSPEC_MADDU                413)
181    (UNSPEC_MSUB                 414)
182    (UNSPEC_MSUBU                415)
183    (UNSPEC_MUL_PH               416)
184    (UNSPEC_MUL_S_PH             417)
185    (UNSPEC_MULQ_RS_W            418)
186    (UNSPEC_MULQ_S_PH            419)
187    (UNSPEC_MULQ_S_W             420)
188    (UNSPEC_MULSA_W_PH           421)
189    (UNSPEC_MULT                 422)
190    (UNSPEC_MULTU                423)
191    (UNSPEC_PRECR_QB_PH          424)
192    (UNSPEC_PRECR_SRA_PH_W       425)
193    (UNSPEC_PRECR_SRA_R_PH_W     426)
194    (UNSPEC_PREPEND              427)
195    (UNSPEC_SHRA_QB              428)
196    (UNSPEC_SHRA_R_QB            429)
197    (UNSPEC_SHRL_PH              430)
198    (UNSPEC_SUBU_PH              431)
199    (UNSPEC_SUBU_S_PH            432)
200    (UNSPEC_SUBUH_QB             433)
201    (UNSPEC_SUBUH_R_QB           434)
202    (UNSPEC_ADDQH_PH             435)
203    (UNSPEC_ADDQH_R_PH           436)
204    (UNSPEC_ADDQH_W              437)
205    (UNSPEC_ADDQH_R_W            438)
206    (UNSPEC_SUBQH_PH             439)
207    (UNSPEC_SUBQH_R_PH           440)
208    (UNSPEC_SUBQH_W              441)
209    (UNSPEC_SUBQH_R_W            442)
210    (UNSPEC_DPAX_W_PH            443)
211    (UNSPEC_DPSX_W_PH            444)
212    (UNSPEC_DPAQX_S_W_PH         445)
213    (UNSPEC_DPAQX_SA_W_PH        446)
214    (UNSPEC_DPSQX_S_W_PH         447)
215    (UNSPEC_DPSQX_SA_W_PH        448)
216   ]
219 (include "predicates.md")
220 (include "constraints.md")
222 ;; ....................
224 ;;      Attributes
226 ;; ....................
228 (define_attr "got" "unset,xgot_high,load"
229   (const_string "unset"))
231 ;; For jal instructions, this attribute is DIRECT when the target address
232 ;; is symbolic and INDIRECT when it is a register.
233 (define_attr "jal" "unset,direct,indirect"
234   (const_string "unset"))
236 ;; This attribute is YES if the instruction is a jal macro (not a
237 ;; real jal instruction).
239 ;; jal is always a macro for TARGET_CALL_CLOBBERED_GP because it includes
240 ;; an instruction to restore $gp.  Direct jals are also macros for
241 ;; flag_pic && !TARGET_ABSOLUTE_ABICALLS because they first load
242 ;; the target address into a register.
243 (define_attr "jal_macro" "no,yes"
244   (cond [(eq_attr "jal" "direct")
245          (symbol_ref "TARGET_CALL_CLOBBERED_GP
246                       || (flag_pic && !TARGET_ABSOLUTE_ABICALLS)")
247          (eq_attr "jal" "indirect")
248          (symbol_ref "TARGET_CALL_CLOBBERED_GP")]
249         (const_string "no")))
251 ;; Classification of each insn.
252 ;; branch       conditional branch
253 ;; jump         unconditional jump
254 ;; call         unconditional call
255 ;; load         load instruction(s)
256 ;; fpload       floating point load
257 ;; fpidxload    floating point indexed load
258 ;; store        store instruction(s)
259 ;; fpstore      floating point store
260 ;; fpidxstore   floating point indexed store
261 ;; prefetch     memory prefetch (register + offset)
262 ;; prefetchx    memory indexed prefetch (register + register)
263 ;; condmove     conditional moves
264 ;; mfc          transfer from coprocessor
265 ;; mtc          transfer to coprocessor
266 ;; mthilo       transfer to hi/lo registers
267 ;; mfhilo       transfer from hi/lo registers
268 ;; const        load constant
269 ;; arith        integer arithmetic instructions
270 ;; logical      integer logical instructions
271 ;; shift        integer shift instructions
272 ;; slt          set less than instructions
273 ;; signext      sign extend instructions
274 ;; clz          the clz and clo instructions
275 ;; trap         trap if instructions
276 ;; imul         integer multiply 2 operands
277 ;; imul3        integer multiply 3 operands
278 ;; imadd        integer multiply-add
279 ;; idiv         integer divide
280 ;; move         integer register move ({,D}ADD{,U} with rt = 0)
281 ;; fmove        floating point register move
282 ;; fadd         floating point add/subtract
283 ;; fmul         floating point multiply
284 ;; fmadd        floating point multiply-add
285 ;; fdiv         floating point divide
286 ;; frdiv        floating point reciprocal divide
287 ;; frdiv1       floating point reciprocal divide step 1
288 ;; frdiv2       floating point reciprocal divide step 2
289 ;; fabs         floating point absolute value
290 ;; fneg         floating point negation
291 ;; fcmp         floating point compare
292 ;; fcvt         floating point convert
293 ;; fsqrt        floating point square root
294 ;; frsqrt       floating point reciprocal square root
295 ;; frsqrt1      floating point reciprocal square root step1
296 ;; frsqrt2      floating point reciprocal square root step2
297 ;; multi        multiword sequence (or user asm statements)
298 ;; nop          no operation
299 ;; ghost        an instruction that produces no real code
300 (define_attr "type"
301   "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,prefetch,prefetchx,condmove,mfc,mtc,mthilo,mfhilo,const,arith,logical,shift,slt,signext,clz,trap,imul,imul3,imadd,idiv,move,fmove,fadd,fmul,fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,frsqrt1,frsqrt2,multi,nop,ghost"
302   (cond [(eq_attr "jal" "!unset") (const_string "call")
303          (eq_attr "got" "load") (const_string "load")]
304         (const_string "unknown")))
306 ;; Main data type used by the insn
307 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW"
308   (const_string "unknown"))
310 ;; Mode for conversion types (fcvt)
311 ;; I2S          integer to float single (SI/DI to SF)
312 ;; I2D          integer to float double (SI/DI to DF)
313 ;; S2I          float to integer (SF to SI/DI)
314 ;; D2I          float to integer (DF to SI/DI)
315 ;; D2S          double to float single
316 ;; S2D          float single to double
318 (define_attr "cnv_mode" "unknown,I2S,I2D,S2I,D2I,D2S,S2D" 
319   (const_string "unknown"))
321 ;; Is this an extended instruction in mips16 mode?
322 (define_attr "extended_mips16" "no,yes"
323   (const_string "no"))
325 ;; Length of instruction in bytes.
326 (define_attr "length" ""
327    (cond [;; Direct branch instructions have a range of [-0x40000,0x3fffc].
328           ;; If a branch is outside this range, we have a choice of two
329           ;; sequences.  For PIC, an out-of-range branch like:
330           ;;
331           ;;    bne     r1,r2,target
332           ;;    dslot
333           ;;
334           ;; becomes the equivalent of:
335           ;;
336           ;;    beq     r1,r2,1f
337           ;;    dslot
338           ;;    la      $at,target
339           ;;    jr      $at
340           ;;    nop
341           ;; 1:
342           ;;
343           ;; where the load address can be up to three instructions long
344           ;; (lw, nop, addiu).
345           ;;
346           ;; The non-PIC case is similar except that we use a direct
347           ;; jump instead of an la/jr pair.  Since the target of this
348           ;; jump is an absolute 28-bit bit address (the other bits
349           ;; coming from the address of the delay slot) this form cannot
350           ;; cross a 256MB boundary.  We could provide the option of
351           ;; using la/jr in this case too, but we do not do so at
352           ;; present.
353           ;;
354           ;; Note that this value does not account for the delay slot
355           ;; instruction, whose length is added separately.  If the RTL
356           ;; pattern has no explicit delay slot, mips_adjust_insn_length
357           ;; will add the length of the implicit nop.  The values for
358           ;; forward and backward branches will be different as well.
359           (eq_attr "type" "branch")
360           (cond [(and (le (minus (match_dup 1) (pc)) (const_int 131064))
361                       (le (minus (pc) (match_dup 1)) (const_int 131068)))
362                   (const_int 4)
363                  (ne (symbol_ref "flag_pic") (const_int 0))
364                  (const_int 24)
365                  ] (const_int 12))
367           (eq_attr "got" "load")
368           (const_int 4)
369           (eq_attr "got" "xgot_high")
370           (const_int 8)
372           (eq_attr "type" "const")
373           (symbol_ref "mips_const_insns (operands[1]) * 4")
374           (eq_attr "type" "load,fpload")
375           (symbol_ref "mips_load_store_insns (operands[1], insn) * 4")
376           (eq_attr "type" "store,fpstore")
377           (symbol_ref "mips_load_store_insns (operands[0], insn) * 4")
379           ;; In the worst case, a call macro will take 8 instructions:
380           ;;
381           ;;     lui $25,%call_hi(FOO)
382           ;;     addu $25,$25,$28
383           ;;     lw $25,%call_lo(FOO)($25)
384           ;;     nop
385           ;;     jalr $25
386           ;;     nop
387           ;;     lw $gp,X($sp)
388           ;;     nop
389           (eq_attr "jal_macro" "yes")
390           (const_int 32)
392           (and (eq_attr "extended_mips16" "yes")
393                (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
394           (const_int 8)
396           ;; Various VR4120 errata require a nop to be inserted after a macc
397           ;; instruction.  The assembler does this for us, so account for
398           ;; the worst-case length here.
399           (and (eq_attr "type" "imadd")
400                (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0)))
401           (const_int 8)
403           ;; VR4120 errata MD(4): if there are consecutive dmult instructions,
404           ;; the result of the second one is missed.  The assembler should work
405           ;; around this by inserting a nop after the first dmult.
406           (and (eq_attr "type" "imul,imul3")
407                (and (eq_attr "mode" "DI")
408                     (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0))))
409           (const_int 8)
411           (eq_attr "type" "idiv")
412           (symbol_ref "mips_idiv_insns () * 4")
413           ] (const_int 4)))
415 ;; Attribute describing the processor.  This attribute must match exactly
416 ;; with the processor_type enumeration in mips.h.
417 (define_attr "cpu"
418   "r3000,4kc,4kp,5kc,5kf,20kc,24kc,24kf2_1,24kf1_1,74kc,74kf2_1,74kf1_1,74kf3_2,loongson2e,loongson2f,m4k,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sb1a,sr71000"
419   (const (symbol_ref "mips_tune")))
421 ;; The type of hardware hazard associated with this instruction.
422 ;; DELAY means that the next instruction cannot read the result
423 ;; of this one.  HILO means that the next two instructions cannot
424 ;; write to HI or LO.
425 (define_attr "hazard" "none,delay,hilo"
426   (cond [(and (eq_attr "type" "load,fpload,fpidxload")
427               (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int 0)))
428          (const_string "delay")
430          (and (eq_attr "type" "mfc,mtc")
431               (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0)))
432          (const_string "delay")
434          (and (eq_attr "type" "fcmp")
435               (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0)))
436          (const_string "delay")
438          ;; The r4000 multiplication patterns include an mflo instruction.
439          (and (eq_attr "type" "imul")
440               (ne (symbol_ref "TARGET_FIX_R4000") (const_int 0)))
441          (const_string "hilo")
443          (and (eq_attr "type" "mfhilo")
444               (eq (symbol_ref "ISA_HAS_HILO_INTERLOCKS") (const_int 0)))
445          (const_string "hilo")]
446         (const_string "none")))
448 ;; Is it a single instruction?
449 (define_attr "single_insn" "no,yes"
450   (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)"))
452 ;; Can the instruction be put into a delay slot?
453 (define_attr "can_delay" "no,yes"
454   (if_then_else (and (eq_attr "type" "!branch,call,jump")
455                      (and (eq_attr "hazard" "none")
456                           (eq_attr "single_insn" "yes")))
457                 (const_string "yes")
458                 (const_string "no")))
460 ;; Attribute defining whether or not we can use the branch-likely instructions
461 (define_attr "branch_likely" "no,yes"
462   (const
463    (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
464                  (const_string "yes")
465                  (const_string "no"))))
467 ;; True if an instruction might assign to hi or lo when reloaded.
468 ;; This is used by the TUNE_MACC_CHAINS code.
469 (define_attr "may_clobber_hilo" "no,yes"
470   (if_then_else (eq_attr "type" "imul,imul3,imadd,idiv,mthilo")
471                 (const_string "yes")
472                 (const_string "no")))
474 ;; Describe a user's asm statement.
475 (define_asm_attributes
476   [(set_attr "type" "multi")
477    (set_attr "can_delay" "no")])
479 ;; This mode iterator allows 32-bit and 64-bit GPR patterns to be generated
480 ;; from the same template.
481 (define_mode_iterator GPR [SI (DI "TARGET_64BIT")])
483 ;; A copy of GPR that can be used when a pattern has two independent
484 ;; modes.
485 (define_mode_iterator GPR2 [SI (DI "TARGET_64BIT")])
487 ;; This mode iterator allows :P to be used for patterns that operate on
488 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
489 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
491 ;; This mode iterator allows :MOVECC to be used anywhere that a
492 ;; conditional-move-type condition is needed.
493 (define_mode_iterator MOVECC [SI (DI "TARGET_64BIT") (CC "TARGET_HARD_FLOAT")])
495 ;; 64-bit modes for which we provide move patterns.
496 (define_mode_iterator MOVE64
497   [DI DF (V2SF "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT")])
499 ;; This mode iterator allows the QI and HI extension patterns to be
500 ;; defined from the same template.
501 (define_mode_iterator SHORT [QI HI])
503 ;; Likewise the 64-bit truncate-and-shift patterns.
504 (define_mode_iterator SUBDI [QI HI SI])
506 ;; This mode iterator allows :ANYF to be used wherever a scalar or vector
507 ;; floating-point mode is allowed.
508 (define_mode_iterator ANYF [(SF "TARGET_HARD_FLOAT")
509                             (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
510                             (V2SF "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT")])
512 ;; Like ANYF, but only applies to scalar modes.
513 (define_mode_iterator SCALARF [(SF "TARGET_HARD_FLOAT")
514                                (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")])
516 ;; A floating-point mode for which moves involving FPRs may need to be split.
517 (define_mode_iterator SPLITF
518   [(DF "!TARGET_64BIT && TARGET_DOUBLE_FLOAT")
519    (DI "!TARGET_64BIT && TARGET_DOUBLE_FLOAT")
520    (V2SF "!TARGET_64BIT && TARGET_PAIRED_SINGLE_FLOAT")
521    (TF "TARGET_64BIT && TARGET_FLOAT64")])
523 ;; In GPR templates, a string like "<d>subu" will expand to "subu" in the
524 ;; 32-bit version and "dsubu" in the 64-bit version.
525 (define_mode_attr d [(SI "") (DI "d")
526                      (QQ "") (HQ "") (SQ "") (DQ "d")
527                      (UQQ "") (UHQ "") (USQ "") (UDQ "d")
528                      (HA "") (SA "") (DA "d")
529                      (UHA "") (USA "") (UDA "d")])
531 ;; This attribute gives the length suffix for a sign- or zero-extension
532 ;; instruction.
533 (define_mode_attr size [(QI "b") (HI "h")])
535 ;; This attributes gives the mode mask of a SHORT.
536 (define_mode_attr mask [(QI "0x00ff") (HI "0xffff")])
538 ;; Mode attributes for GPR loads and stores.
539 (define_mode_attr load [(SI "lw") (DI "ld")])
540 (define_mode_attr store [(SI "sw") (DI "sd")])
542 ;; Similarly for MIPS IV indexed FPR loads and stores.
543 (define_mode_attr loadx [(SF "lwxc1") (DF "ldxc1") (V2SF "ldxc1")])
544 (define_mode_attr storex [(SF "swxc1") (DF "sdxc1") (V2SF "sdxc1")])
546 ;; The unextended ranges of the MIPS16 addiu and daddiu instructions
547 ;; are different.  Some forms of unextended addiu have an 8-bit immediate
548 ;; field but the equivalent daddiu has only a 5-bit field.
549 (define_mode_attr si8_di5 [(SI "8") (DI "5")])
551 ;; This attribute gives the best constraint to use for registers of
552 ;; a given mode.
553 (define_mode_attr reg [(SI "d") (DI "d") (CC "z")])
555 ;; This attribute gives the format suffix for floating-point operations.
556 (define_mode_attr fmt [(SF "s") (DF "d") (V2SF "ps")])
558 ;; This attribute gives the upper-case mode name for one unit of a
559 ;; floating-point mode.
560 (define_mode_attr UNITMODE [(SF "SF") (DF "DF") (V2SF "SF")])
562 ;; This attribute gives the integer mode that has the same size as a
563 ;; fixed-point mode.
564 (define_mode_attr IMODE [(QQ "QI") (HQ "HI") (SQ "SI") (DQ "DI")
565                          (UQQ "QI") (UHQ "HI") (USQ "SI") (UDQ "DI")
566                          (HA "HI") (SA "SI") (DA "DI")
567                          (UHA "HI") (USA "SI") (UDA "DI")
568                          (V4UQQ "SI") (V2UHQ "SI") (V2UHA "SI")
569                          (V2HQ "SI") (V2HA "SI")])
571 ;; This attribute gives the integer mode that has half the size of
572 ;; the controlling mode.
573 (define_mode_attr HALFMODE [(DF "SI") (DI "SI") (V2SF "SI") (TF "DI")])
575 ;; This attribute works around the early SB-1 rev2 core "F2" erratum:
577 ;; In certain cases, div.s and div.ps may have a rounding error
578 ;; and/or wrong inexact flag.
580 ;; Therefore, we only allow div.s if not working around SB-1 rev2
581 ;; errata or if a slight loss of precision is OK.
582 (define_mode_attr divide_condition
583   [DF (SF "!TARGET_FIX_SB1 || flag_unsafe_math_optimizations")
584    (V2SF "TARGET_SB1 && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)")])
586 ;; This attribute gives the conditions under which SQRT.fmt instructions
587 ;; can be used.
588 (define_mode_attr sqrt_condition
589   [(SF "!ISA_MIPS1") (DF "!ISA_MIPS1") (V2SF "TARGET_SB1")])
591 ;; This attribute gives the conditions under which RECIP.fmt and RSQRT.fmt
592 ;; instructions can be used.  The MIPS32 and MIPS64 ISAs say that RECIP.D
593 ;; and RSQRT.D are unpredictable when doubles are stored in pairs of FPRs,
594 ;; so for safety's sake, we apply this restriction to all targets.
595 (define_mode_attr recip_condition
596   [(SF "ISA_HAS_FP4")
597    (DF "ISA_HAS_FP4 && TARGET_FLOAT64")
598    (V2SF "TARGET_SB1")])
600 ;; This code iterator allows all branch instructions to be generated from
601 ;; a single define_expand template.
602 (define_code_iterator any_cond [unordered ordered unlt unge uneq ltgt unle ungt
603                                 eq ne gt ge lt le gtu geu ltu leu])
605 ;; This code iterator allows signed and unsigned widening multiplications
606 ;; to use the same template.
607 (define_code_iterator any_extend [sign_extend zero_extend])
609 ;; This code iterator allows the three shift instructions to be generated
610 ;; from the same template.
611 (define_code_iterator any_shift [ashift ashiftrt lshiftrt])
613 ;; This code iterator allows all native floating-point comparisons to be
614 ;; generated from the same template.
615 (define_code_iterator fcond [unordered uneq unlt unle eq lt le])
617 ;; This code iterator is used for comparisons that can be implemented
618 ;; by swapping the operands.
619 (define_code_iterator swapped_fcond [ge gt unge ungt])
621 ;; These code iterators allow the signed and unsigned scc operations to use
622 ;; the same template.
623 (define_code_iterator any_gt [gt gtu])
624 (define_code_iterator any_ge [ge geu])
625 (define_code_iterator any_lt [lt ltu])
626 (define_code_iterator any_le [le leu])
628 ;; <u> expands to an empty string when doing a signed operation and
629 ;; "u" when doing an unsigned operation.
630 (define_code_attr u [(sign_extend "") (zero_extend "u")
631                      (gt "") (gtu "u")
632                      (ge "") (geu "u")
633                      (lt "") (ltu "u")
634                      (le "") (leu "u")])
636 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
637 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
639 ;; <optab> expands to the name of the optab for a particular code.
640 (define_code_attr optab [(ashift "ashl")
641                          (ashiftrt "ashr")
642                          (lshiftrt "lshr")
643                          (ior "ior")
644                          (xor "xor")
645                          (and "and")
646                          (plus "add")
647                          (minus "sub")])
649 ;; <insn> expands to the name of the insn that implements a particular code.
650 (define_code_attr insn [(ashift "sll")
651                         (ashiftrt "sra")
652                         (lshiftrt "srl")
653                         (ior "or")
654                         (xor "xor")
655                         (and "and")
656                         (plus "addu")
657                         (minus "subu")])
659 ;; <fcond> is the c.cond.fmt condition associated with a particular code.
660 (define_code_attr fcond [(unordered "un")
661                          (uneq "ueq")
662                          (unlt "ult")
663                          (unle "ule")
664                          (eq "eq")
665                          (lt "lt")
666                          (le "le")])
668 ;; Similar, but for swapped conditions.
669 (define_code_attr swapped_fcond [(ge "le")
670                                  (gt "lt")
671                                  (unge "ule")
672                                  (ungt "ult")])
674 ;; Atomic fetch bitwise operations.
675 (define_code_iterator fetchop_bit [ior xor and])
677 ;; <immediate_insn> expands to the name of the insn that implements
678 ;; a particular code to operate in immediate values.
679 (define_code_attr immediate_insn [(ior "ori") (xor "xori") (and "andi")])
681 ;; Atomic HI and QI operations
682 (define_code_iterator atomic_hiqi_op [plus minus ior xor and])
684 ;; .........................
686 ;;      Branch, call and jump delay slots
688 ;; .........................
690 (define_delay (and (eq_attr "type" "branch")
691                    (eq (symbol_ref "TARGET_MIPS16") (const_int 0)))
692   [(eq_attr "can_delay" "yes")
693    (nil)
694    (and (eq_attr "branch_likely" "yes")
695         (eq_attr "can_delay" "yes"))])
697 (define_delay (eq_attr "type" "jump")
698   [(eq_attr "can_delay" "yes")
699    (nil)
700    (nil)])
702 (define_delay (and (eq_attr "type" "call")
703                    (eq_attr "jal_macro" "no"))
704   [(eq_attr "can_delay" "yes")
705    (nil)
706    (nil)])
708 ;; Pipeline descriptions.
710 ;; generic.md provides a fallback for processors without a specific
711 ;; pipeline description.  It is derived from the old define_function_unit
712 ;; version and uses the "alu" and "imuldiv" units declared below.
714 ;; Some of the processor-specific files are also derived from old
715 ;; define_function_unit descriptions and simply override the parts of
716 ;; generic.md that don't apply.  The other processor-specific files
717 ;; are self-contained.
718 (define_automaton "alu,imuldiv")
720 (define_cpu_unit "alu" "alu")
721 (define_cpu_unit "imuldiv" "imuldiv")
723 ;; Ghost instructions produce no real code and introduce no hazards.
724 ;; They exist purely to express an effect on dataflow.
725 (define_insn_reservation "ghost" 0
726   (eq_attr "type" "ghost")
727   "nothing")
729 (include "4k.md")
730 (include "5k.md")
731 (include "20kc.md")
732 (include "24k.md")
733 (include "74k.md")
734 (include "3000.md")
735 (include "4000.md")
736 (include "4100.md")
737 (include "4130.md")
738 (include "4300.md")
739 (include "4600.md")
740 (include "5000.md")
741 (include "5400.md")
742 (include "5500.md")
743 (include "6000.md")
744 (include "7000.md")
745 (include "9000.md")
746 (include "sb1.md")
747 (include "sr71k.md")
748 (include "generic.md")
751 ;;  ....................
753 ;;      CONDITIONAL TRAPS
755 ;;  ....................
758 (define_insn "trap"
759   [(trap_if (const_int 1) (const_int 0))]
760   ""
762   if (ISA_HAS_COND_TRAP)
763     return "teq\t$0,$0";
764   else if (TARGET_MIPS16)
765     return "break 0";
766   else
767     return "break";
769   [(set_attr "type" "trap")])
771 (define_expand "conditional_trap"
772   [(trap_if (match_operator 0 "comparison_operator"
773                             [(match_dup 2) (match_dup 3)])
774             (match_operand 1 "const_int_operand"))]
775   "ISA_HAS_COND_TRAP"
777   if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) == MODE_INT
778       && operands[1] == const0_rtx)
779     {
780       mips_expand_conditional_trap (GET_CODE (operands[0]));
781       DONE;
782     }
783   FAIL;
786 (define_insn "*conditional_trap<mode>"
787   [(trap_if (match_operator:GPR 0 "trap_comparison_operator"
788                                 [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
789                                  (match_operand:GPR 2 "arith_operand" "dI")])
790             (const_int 0))]
791   "ISA_HAS_COND_TRAP"
792   "t%C0\t%z1,%2"
793   [(set_attr "type" "trap")])
796 ;;  ....................
798 ;;      ADDITION
800 ;;  ....................
803 (define_insn "add<mode>3"
804   [(set (match_operand:ANYF 0 "register_operand" "=f")
805         (plus:ANYF (match_operand:ANYF 1 "register_operand" "f")
806                    (match_operand:ANYF 2 "register_operand" "f")))]
807   ""
808   "add.<fmt>\t%0,%1,%2"
809   [(set_attr "type" "fadd")
810    (set_attr "mode" "<UNITMODE>")])
812 (define_expand "add<mode>3"
813   [(set (match_operand:GPR 0 "register_operand")
814         (plus:GPR (match_operand:GPR 1 "register_operand")
815                   (match_operand:GPR 2 "arith_operand")))]
816   "")
818 (define_insn "*add<mode>3"
819   [(set (match_operand:GPR 0 "register_operand" "=d,d")
820         (plus:GPR (match_operand:GPR 1 "register_operand" "d,d")
821                   (match_operand:GPR 2 "arith_operand" "d,Q")))]
822   "!TARGET_MIPS16"
823   "@
824     <d>addu\t%0,%1,%2
825     <d>addiu\t%0,%1,%2"
826   [(set_attr "type" "arith")
827    (set_attr "mode" "<MODE>")])
829 (define_insn "*add<mode>3_mips16"
830   [(set (match_operand:GPR 0 "register_operand" "=ks,d,d,d,d")
831         (plus:GPR (match_operand:GPR 1 "register_operand" "ks,ks,0,d,d")
832                   (match_operand:GPR 2 "arith_operand" "Q,Q,Q,O,d")))]
833   "TARGET_MIPS16"
834   "@
835     <d>addiu\t%0,%2
836     <d>addiu\t%0,%1,%2
837     <d>addiu\t%0,%2
838     <d>addiu\t%0,%1,%2
839     <d>addu\t%0,%1,%2"
840   [(set_attr "type" "arith")
841    (set_attr "mode" "<MODE>")
842    (set_attr_alternative "length"
843                 [(if_then_else (match_operand 2 "m16_simm8_8")
844                                (const_int 4)
845                                (const_int 8))
846                  (if_then_else (match_operand 2 "m16_uimm<si8_di5>_4")
847                                (const_int 4)
848                                (const_int 8))
849                  (if_then_else (match_operand 2 "m16_simm<si8_di5>_1")
850                                (const_int 4)
851                                (const_int 8))
852                  (if_then_else (match_operand 2 "m16_simm4_1")
853                                (const_int 4)
854                                (const_int 8))
855                  (const_int 4)])])
857 ;; On the mips16, we can sometimes split an add of a constant which is
858 ;; a 4 byte instruction into two adds which are both 2 byte
859 ;; instructions.  There are two cases: one where we are adding a
860 ;; constant plus a register to another register, and one where we are
861 ;; simply adding a constant to a register.
863 (define_split
864   [(set (match_operand:SI 0 "register_operand")
865         (plus:SI (match_dup 0)
866                  (match_operand:SI 1 "const_int_operand")))]
867   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
868    && REG_P (operands[0])
869    && M16_REG_P (REGNO (operands[0]))
870    && GET_CODE (operands[1]) == CONST_INT
871    && ((INTVAL (operands[1]) > 0x7f
872         && INTVAL (operands[1]) <= 0x7f + 0x7f)
873        || (INTVAL (operands[1]) < - 0x80
874            && INTVAL (operands[1]) >= - 0x80 - 0x80))"
875   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
876    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
878   HOST_WIDE_INT val = INTVAL (operands[1]);
880   if (val >= 0)
881     {
882       operands[1] = GEN_INT (0x7f);
883       operands[2] = GEN_INT (val - 0x7f);
884     }
885   else
886     {
887       operands[1] = GEN_INT (- 0x80);
888       operands[2] = GEN_INT (val + 0x80);
889     }
892 (define_split
893   [(set (match_operand:SI 0 "register_operand")
894         (plus:SI (match_operand:SI 1 "register_operand")
895                  (match_operand:SI 2 "const_int_operand")))]
896   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
897    && REG_P (operands[0])
898    && M16_REG_P (REGNO (operands[0]))
899    && REG_P (operands[1])
900    && M16_REG_P (REGNO (operands[1]))
901    && REGNO (operands[0]) != REGNO (operands[1])
902    && GET_CODE (operands[2]) == CONST_INT
903    && ((INTVAL (operands[2]) > 0x7
904         && INTVAL (operands[2]) <= 0x7 + 0x7f)
905        || (INTVAL (operands[2]) < - 0x8
906            && INTVAL (operands[2]) >= - 0x8 - 0x80))"
907   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
908    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
910   HOST_WIDE_INT val = INTVAL (operands[2]);
912   if (val >= 0)
913     {
914       operands[2] = GEN_INT (0x7);
915       operands[3] = GEN_INT (val - 0x7);
916     }
917   else
918     {
919       operands[2] = GEN_INT (- 0x8);
920       operands[3] = GEN_INT (val + 0x8);
921     }
924 (define_split
925   [(set (match_operand:DI 0 "register_operand")
926         (plus:DI (match_dup 0)
927                  (match_operand:DI 1 "const_int_operand")))]
928   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
929    && REG_P (operands[0])
930    && M16_REG_P (REGNO (operands[0]))
931    && GET_CODE (operands[1]) == CONST_INT
932    && ((INTVAL (operands[1]) > 0xf
933         && INTVAL (operands[1]) <= 0xf + 0xf)
934        || (INTVAL (operands[1]) < - 0x10
935            && INTVAL (operands[1]) >= - 0x10 - 0x10))"
936   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
937    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
939   HOST_WIDE_INT val = INTVAL (operands[1]);
941   if (val >= 0)
942     {
943       operands[1] = GEN_INT (0xf);
944       operands[2] = GEN_INT (val - 0xf);
945     }
946   else
947     {
948       operands[1] = GEN_INT (- 0x10);
949       operands[2] = GEN_INT (val + 0x10);
950     }
953 (define_split
954   [(set (match_operand:DI 0 "register_operand")
955         (plus:DI (match_operand:DI 1 "register_operand")
956                  (match_operand:DI 2 "const_int_operand")))]
957   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
958    && REG_P (operands[0])
959    && M16_REG_P (REGNO (operands[0]))
960    && REG_P (operands[1])
961    && M16_REG_P (REGNO (operands[1]))
962    && REGNO (operands[0]) != REGNO (operands[1])
963    && GET_CODE (operands[2]) == CONST_INT
964    && ((INTVAL (operands[2]) > 0x7
965         && INTVAL (operands[2]) <= 0x7 + 0xf)
966        || (INTVAL (operands[2]) < - 0x8
967            && INTVAL (operands[2]) >= - 0x8 - 0x10))"
968   [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
969    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
971   HOST_WIDE_INT val = INTVAL (operands[2]);
973   if (val >= 0)
974     {
975       operands[2] = GEN_INT (0x7);
976       operands[3] = GEN_INT (val - 0x7);
977     }
978   else
979     {
980       operands[2] = GEN_INT (- 0x8);
981       operands[3] = GEN_INT (val + 0x8);
982     }
985 (define_insn "*addsi3_extended"
986   [(set (match_operand:DI 0 "register_operand" "=d,d")
987         (sign_extend:DI
988              (plus:SI (match_operand:SI 1 "register_operand" "d,d")
989                       (match_operand:SI 2 "arith_operand" "d,Q"))))]
990   "TARGET_64BIT && !TARGET_MIPS16"
991   "@
992     addu\t%0,%1,%2
993     addiu\t%0,%1,%2"
994   [(set_attr "type" "arith")
995    (set_attr "mode" "SI")])
997 ;; Split this insn so that the addiu splitters can have a crack at it.
998 ;; Use a conservative length estimate until the split.
999 (define_insn_and_split "*addsi3_extended_mips16"
1000   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1001         (sign_extend:DI
1002              (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1003                       (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
1004   "TARGET_64BIT && TARGET_MIPS16"
1005   "#"
1006   "&& reload_completed"
1007   [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))]
1008   { operands[3] = gen_lowpart (SImode, operands[0]); }
1009   [(set_attr "type" "arith")
1010    (set_attr "mode" "SI")
1011    (set_attr "extended_mips16" "yes")])
1014 ;;  ....................
1016 ;;      SUBTRACTION
1018 ;;  ....................
1021 (define_insn "sub<mode>3"
1022   [(set (match_operand:ANYF 0 "register_operand" "=f")
1023         (minus:ANYF (match_operand:ANYF 1 "register_operand" "f")
1024                     (match_operand:ANYF 2 "register_operand" "f")))]
1025   ""
1026   "sub.<fmt>\t%0,%1,%2"
1027   [(set_attr "type" "fadd")
1028    (set_attr "mode" "<UNITMODE>")])
1030 (define_insn "sub<mode>3"
1031   [(set (match_operand:GPR 0 "register_operand" "=d")
1032         (minus:GPR (match_operand:GPR 1 "register_operand" "d")
1033                    (match_operand:GPR 2 "register_operand" "d")))]
1034   ""
1035   "<d>subu\t%0,%1,%2"
1036   [(set_attr "type" "arith")
1037    (set_attr "mode" "<MODE>")])
1039 (define_insn "*subsi3_extended"
1040   [(set (match_operand:DI 0 "register_operand" "=d")
1041         (sign_extend:DI
1042             (minus:SI (match_operand:SI 1 "register_operand" "d")
1043                       (match_operand:SI 2 "register_operand" "d"))))]
1044   "TARGET_64BIT"
1045   "subu\t%0,%1,%2"
1046   [(set_attr "type" "arith")
1047    (set_attr "mode" "DI")])
1050 ;;  ....................
1052 ;;      MULTIPLICATION
1054 ;;  ....................
1057 (define_expand "mul<mode>3"
1058   [(set (match_operand:SCALARF 0 "register_operand")
1059         (mult:SCALARF (match_operand:SCALARF 1 "register_operand")
1060                       (match_operand:SCALARF 2 "register_operand")))]
1061   ""
1062   "")
1064 (define_insn "*mul<mode>3"
1065   [(set (match_operand:SCALARF 0 "register_operand" "=f")
1066         (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
1067                       (match_operand:SCALARF 2 "register_operand" "f")))]
1068   "!TARGET_4300_MUL_FIX"
1069   "mul.<fmt>\t%0,%1,%2"
1070   [(set_attr "type" "fmul")
1071    (set_attr "mode" "<MODE>")])
1073 ;; Early VR4300 silicon has a CPU bug where multiplies with certain
1074 ;; operands may corrupt immediately following multiplies. This is a
1075 ;; simple fix to insert NOPs.
1077 (define_insn "*mul<mode>3_r4300"
1078   [(set (match_operand:SCALARF 0 "register_operand" "=f")
1079         (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
1080                       (match_operand:SCALARF 2 "register_operand" "f")))]
1081   "TARGET_4300_MUL_FIX"
1082   "mul.<fmt>\t%0,%1,%2\;nop"
1083   [(set_attr "type" "fmul")
1084    (set_attr "mode" "<MODE>")
1085    (set_attr "length" "8")])
1087 (define_insn "mulv2sf3"
1088   [(set (match_operand:V2SF 0 "register_operand" "=f")
1089         (mult:V2SF (match_operand:V2SF 1 "register_operand" "f")
1090                    (match_operand:V2SF 2 "register_operand" "f")))]
1091   "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
1092   "mul.ps\t%0,%1,%2"
1093   [(set_attr "type" "fmul")
1094    (set_attr "mode" "SF")])
1096 ;; The original R4000 has a cpu bug.  If a double-word or a variable
1097 ;; shift executes while an integer multiplication is in progress, the
1098 ;; shift may give an incorrect result.  Avoid this by keeping the mflo
1099 ;; with the mult on the R4000.
1101 ;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
1102 ;; (also valid for MIPS R4000MC processors):
1104 ;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
1105 ;;      this errata description.
1106 ;;      The following code sequence causes the R4000 to incorrectly
1107 ;;      execute the Double Shift Right Arithmetic 32 (dsra32)
1108 ;;      instruction.  If the dsra32 instruction is executed during an
1109 ;;      integer multiply, the dsra32 will only shift by the amount in
1110 ;;      specified in the instruction rather than the amount plus 32
1111 ;;      bits.
1112 ;;      instruction 1:          mult    rs,rt           integer multiply
1113 ;;      instruction 2-12:       dsra32  rd,rt,rs        doubleword shift
1114 ;;                                                      right arithmetic + 32
1115 ;;      Workaround: A dsra32 instruction placed after an integer
1116 ;;      multiply should not be one of the 11 instructions after the
1117 ;;      multiply instruction."
1119 ;; and:
1121 ;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
1122 ;;      the following description.
1123 ;;      All extended shifts (shift by n+32) and variable shifts (32 and
1124 ;;      64-bit versions) may produce incorrect results under the
1125 ;;      following conditions:
1126 ;;      1) An integer multiply is currently executing
1127 ;;      2) These types of shift instructions are executed immediately
1128 ;;         following an integer divide instruction.
1129 ;;      Workaround:
1130 ;;      1) Make sure no integer multiply is running wihen these
1131 ;;         instruction are executed.  If this cannot be predicted at
1132 ;;         compile time, then insert a "mfhi" to R0 instruction
1133 ;;         immediately after the integer multiply instruction.  This
1134 ;;         will cause the integer multiply to complete before the shift
1135 ;;         is executed.
1136 ;;      2) Separate integer divide and these two classes of shift
1137 ;;         instructions by another instruction or a noop."
1139 ;; These processors have PRId values of 0x00004220 and 0x00004300,
1140 ;; respectively.
1142 (define_expand "mulsi3"
1143   [(set (match_operand:SI 0 "register_operand")
1144         (mult:SI (match_operand:SI 1 "register_operand")
1145                  (match_operand:SI 2 "register_operand")))]
1146   ""
1148   if (ISA_HAS_MUL3)
1149     emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
1150   else if (TARGET_FIX_R4000)
1151     emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
1152   else
1153     emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
1154   DONE;
1157 (define_expand "muldi3"
1158   [(set (match_operand:DI 0 "register_operand")
1159         (mult:DI (match_operand:DI 1 "register_operand")
1160                  (match_operand:DI 2 "register_operand")))]
1161   "TARGET_64BIT"
1163   if (TARGET_FIX_R4000)
1164     emit_insn (gen_muldi3_r4000 (operands[0], operands[1], operands[2]));
1165   else
1166     emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
1167   DONE;
1170 (define_insn "mulsi3_mult3"
1171   [(set (match_operand:SI 0 "register_operand" "=d,l")
1172         (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1173                  (match_operand:SI 2 "register_operand" "d,d")))
1174    (clobber (match_scratch:SI 3 "=h,h"))
1175    (clobber (match_scratch:SI 4 "=l,X"))]
1176   "ISA_HAS_MUL3"
1178   if (which_alternative == 1)
1179     return "mult\t%1,%2";
1180   if (TARGET_MIPS3900)
1181     return "mult\t%0,%1,%2";
1182   return "mul\t%0,%1,%2";
1184   [(set_attr "type" "imul3,imul")
1185    (set_attr "mode" "SI")])
1187 ;; If a register gets allocated to LO, and we spill to memory, the reload
1188 ;; will include a move from LO to a GPR.  Merge it into the multiplication
1189 ;; if it can set the GPR directly.
1191 ;; Operand 0: LO
1192 ;; Operand 1: GPR (1st multiplication operand)
1193 ;; Operand 2: GPR (2nd multiplication operand)
1194 ;; Operand 3: HI
1195 ;; Operand 4: GPR (destination)
1196 (define_peephole2
1197   [(parallel
1198        [(set (match_operand:SI 0 "register_operand")
1199              (mult:SI (match_operand:SI 1 "register_operand")
1200                       (match_operand:SI 2 "register_operand")))
1201         (clobber (match_operand:SI 3 "register_operand"))
1202         (clobber (scratch:SI))])
1203    (set (match_operand:SI 4 "register_operand")
1204         (unspec [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
1205   "ISA_HAS_MUL3 && peep2_reg_dead_p (2, operands[0])"
1206   [(parallel
1207        [(set (match_dup 4)
1208              (mult:SI (match_dup 1)
1209                       (match_dup 2)))
1210         (clobber (match_dup 3))
1211         (clobber (match_dup 0))])])
1213 (define_insn "mul<mode>3_internal"
1214   [(set (match_operand:GPR 0 "register_operand" "=l")
1215         (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1216                   (match_operand:GPR 2 "register_operand" "d")))
1217    (clobber (match_scratch:GPR 3 "=h"))]
1218   "!TARGET_FIX_R4000"
1219   "<d>mult\t%1,%2"
1220   [(set_attr "type" "imul")
1221    (set_attr "mode" "<MODE>")])
1223 (define_insn "mul<mode>3_r4000"
1224   [(set (match_operand:GPR 0 "register_operand" "=d")
1225         (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1226                   (match_operand:GPR 2 "register_operand" "d")))
1227    (clobber (match_scratch:GPR 3 "=h"))
1228    (clobber (match_scratch:GPR 4 "=l"))]
1229   "TARGET_FIX_R4000"
1230   "<d>mult\t%1,%2\;mflo\t%0"
1231   [(set_attr "type" "imul")
1232    (set_attr "mode" "<MODE>")
1233    (set_attr "length" "8")])
1235 ;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
1236 ;; of "mult; mflo".  They have the same latency, but the first form gives
1237 ;; us an extra cycle to compute the operands.
1239 ;; Operand 0: LO
1240 ;; Operand 1: GPR (1st multiplication operand)
1241 ;; Operand 2: GPR (2nd multiplication operand)
1242 ;; Operand 3: HI
1243 ;; Operand 4: GPR (destination)
1244 (define_peephole2
1245   [(parallel
1246        [(set (match_operand:SI 0 "register_operand")
1247              (mult:SI (match_operand:SI 1 "register_operand")
1248                       (match_operand:SI 2 "register_operand")))
1249         (clobber (match_operand:SI 3 "register_operand"))])
1250    (set (match_operand:SI 4 "register_operand")
1251         (unspec:SI [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
1252   "ISA_HAS_MACC && !ISA_HAS_MUL3"
1253   [(set (match_dup 0)
1254         (const_int 0))
1255    (parallel
1256        [(set (match_dup 0)
1257              (plus:SI (mult:SI (match_dup 1)
1258                                (match_dup 2))
1259                       (match_dup 0)))
1260         (set (match_dup 4)
1261              (plus:SI (mult:SI (match_dup 1)
1262                                (match_dup 2))
1263                       (match_dup 0)))
1264         (clobber (match_dup 3))])])
1266 ;; Multiply-accumulate patterns
1268 ;; For processors that can copy the output to a general register:
1270 ;; The all-d alternative is needed because the combiner will find this
1271 ;; pattern and then register alloc/reload will move registers around to
1272 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
1274 ;; The last alternative should be made slightly less desirable, but adding
1275 ;; "?" to the constraint is too strong, and causes values to be loaded into
1276 ;; LO even when that's more costly.  For now, using "*d" mostly does the
1277 ;; trick.
1278 (define_insn "*mul_acc_si"
1279   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1280         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1281                           (match_operand:SI 2 "register_operand" "d,d,d"))
1282                  (match_operand:SI 3 "register_operand" "0,l,*d")))
1283    (clobber (match_scratch:SI 4 "=h,h,h"))
1284    (clobber (match_scratch:SI 5 "=X,3,l"))
1285    (clobber (match_scratch:SI 6 "=X,X,&d"))]
1286   "(TARGET_MIPS3900
1287    || GENERATE_MADD_MSUB)
1288    && !TARGET_MIPS16"
1290   static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" };
1291   if (which_alternative == 2)
1292     return "#";
1293   if (GENERATE_MADD_MSUB && which_alternative != 0)
1294     return "#";
1295   return madd[which_alternative];
1297   [(set_attr "type"     "imadd")
1298    (set_attr "mode"     "SI")
1299    (set_attr "length"   "4,4,8")])
1301 ;; Split the above insn if we failed to get LO allocated.
1302 (define_split
1303   [(set (match_operand:SI 0 "register_operand")
1304         (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1305                           (match_operand:SI 2 "register_operand"))
1306                  (match_operand:SI 3 "register_operand")))
1307    (clobber (match_scratch:SI 4))
1308    (clobber (match_scratch:SI 5))
1309    (clobber (match_scratch:SI 6))]
1310   "reload_completed && !TARGET_DEBUG_D_MODE
1311    && GP_REG_P (true_regnum (operands[0]))
1312    && GP_REG_P (true_regnum (operands[3]))"
1313   [(parallel [(set (match_dup 6)
1314                    (mult:SI (match_dup 1) (match_dup 2)))
1315               (clobber (match_dup 4))
1316               (clobber (match_dup 5))])
1317    (set (match_dup 0) (plus:SI (match_dup 6) (match_dup 3)))]
1318   "")
1320 ;; Splitter to copy result of MADD to a general register
1321 (define_split
1322   [(set (match_operand:SI                   0 "register_operand")
1323         (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1324                           (match_operand:SI 2 "register_operand"))
1325                  (match_operand:SI          3 "register_operand")))
1326    (clobber (match_scratch:SI               4))
1327    (clobber (match_scratch:SI               5))
1328    (clobber (match_scratch:SI               6))]
1329   "reload_completed && !TARGET_DEBUG_D_MODE
1330    && GP_REG_P (true_regnum (operands[0]))
1331    && true_regnum (operands[3]) == LO_REGNUM"
1332   [(parallel [(set (match_dup 3)
1333                    (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1334                             (match_dup 3)))
1335               (clobber (match_dup 4))
1336               (clobber (match_dup 5))
1337               (clobber (match_dup 6))])
1338    (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1339   "")
1341 (define_insn "*macc"
1342   [(set (match_operand:SI 0 "register_operand" "=l,d")
1343         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1344                           (match_operand:SI 2 "register_operand" "d,d"))
1345                  (match_operand:SI 3 "register_operand" "0,l")))
1346    (clobber (match_scratch:SI 4 "=h,h"))
1347    (clobber (match_scratch:SI 5 "=X,3"))]
1348   "ISA_HAS_MACC"
1350   if (which_alternative == 1)
1351     return "macc\t%0,%1,%2";
1352   else if (TARGET_MIPS5500)
1353     return "madd\t%1,%2";
1354   else
1355     /* The VR4130 assumes that there is a two-cycle latency between a macc
1356        that "writes" to $0 and an instruction that reads from it.  We avoid
1357        this by assigning to $1 instead.  */
1358     return "%[macc\t%@,%1,%2%]";
1360   [(set_attr "type" "imadd")
1361    (set_attr "mode" "SI")])
1363 (define_insn "*msac"
1364   [(set (match_operand:SI 0 "register_operand" "=l,d")
1365         (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1366                   (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1367                            (match_operand:SI 3 "register_operand" "d,d"))))
1368    (clobber (match_scratch:SI 4 "=h,h"))
1369    (clobber (match_scratch:SI 5 "=X,1"))]
1370   "ISA_HAS_MSAC"
1372   if (which_alternative == 1)
1373     return "msac\t%0,%2,%3";
1374   else if (TARGET_MIPS5500)
1375     return "msub\t%2,%3";
1376   else
1377     return "msac\t$0,%2,%3";
1379   [(set_attr "type"     "imadd")
1380    (set_attr "mode"     "SI")])
1382 ;; An msac-like instruction implemented using negation and a macc.
1383 (define_insn_and_split "*msac_using_macc"
1384   [(set (match_operand:SI 0 "register_operand" "=l,d")
1385         (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1386                   (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1387                            (match_operand:SI 3 "register_operand" "d,d"))))
1388    (clobber (match_scratch:SI 4 "=h,h"))
1389    (clobber (match_scratch:SI 5 "=X,1"))
1390    (clobber (match_scratch:SI 6 "=d,d"))]
1391   "ISA_HAS_MACC && !ISA_HAS_MSAC"
1392   "#"
1393   "&& reload_completed"
1394   [(set (match_dup 6)
1395         (neg:SI (match_dup 3)))
1396    (parallel
1397        [(set (match_dup 0)
1398              (plus:SI (mult:SI (match_dup 2)
1399                                (match_dup 6))
1400                       (match_dup 1)))
1401         (clobber (match_dup 4))
1402         (clobber (match_dup 5))])]
1403   ""
1404   [(set_attr "type"     "imadd")
1405    (set_attr "length"   "8")])
1407 ;; Patterns generated by the define_peephole2 below.
1409 (define_insn "*macc2"
1410   [(set (match_operand:SI 0 "register_operand" "=l")
1411         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1412                           (match_operand:SI 2 "register_operand" "d"))
1413                  (match_dup 0)))
1414    (set (match_operand:SI 3 "register_operand" "=d")
1415         (plus:SI (mult:SI (match_dup 1)
1416                           (match_dup 2))
1417                  (match_dup 0)))
1418    (clobber (match_scratch:SI 4 "=h"))]
1419   "ISA_HAS_MACC && reload_completed"
1420   "macc\t%3,%1,%2"
1421   [(set_attr "type"     "imadd")
1422    (set_attr "mode"     "SI")])
1424 (define_insn "*msac2"
1425   [(set (match_operand:SI 0 "register_operand" "=l")
1426         (minus:SI (match_dup 0)
1427                   (mult:SI (match_operand:SI 1 "register_operand" "d")
1428                            (match_operand:SI 2 "register_operand" "d"))))
1429    (set (match_operand:SI 3 "register_operand" "=d")
1430         (minus:SI (match_dup 0)
1431                   (mult:SI (match_dup 1)
1432                            (match_dup 2))))
1433    (clobber (match_scratch:SI 4 "=h"))]
1434   "ISA_HAS_MSAC && reload_completed"
1435   "msac\t%3,%1,%2"
1436   [(set_attr "type"     "imadd")
1437    (set_attr "mode"     "SI")])
1439 ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1440 ;; Similarly msac.
1442 ;; Operand 0: LO
1443 ;; Operand 1: macc/msac
1444 ;; Operand 2: HI
1445 ;; Operand 3: GPR (destination)
1446 (define_peephole2
1447   [(parallel
1448        [(set (match_operand:SI 0 "register_operand")
1449              (match_operand:SI 1 "macc_msac_operand"))
1450         (clobber (match_operand:SI 2 "register_operand"))
1451         (clobber (scratch:SI))])
1452    (set (match_operand:SI 3 "register_operand")
1453         (unspec:SI [(match_dup 0) (match_dup 2)] UNSPEC_MFHILO))]
1454   ""
1455   [(parallel [(set (match_dup 0)
1456                    (match_dup 1))
1457               (set (match_dup 3)
1458                    (match_dup 1))
1459               (clobber (match_dup 2))])]
1460   "")
1462 ;; When we have a three-address multiplication instruction, it should
1463 ;; be faster to do a separate multiply and add, rather than moving
1464 ;; something into LO in order to use a macc instruction.
1466 ;; This peephole needs a scratch register to cater for the case when one
1467 ;; of the multiplication operands is the same as the destination.
1469 ;; Operand 0: GPR (scratch)
1470 ;; Operand 1: LO
1471 ;; Operand 2: GPR (addend)
1472 ;; Operand 3: GPR (destination)
1473 ;; Operand 4: macc/msac
1474 ;; Operand 5: HI
1475 ;; Operand 6: new multiplication
1476 ;; Operand 7: new addition/subtraction
1477 (define_peephole2
1478   [(match_scratch:SI 0 "d")
1479    (set (match_operand:SI 1 "register_operand")
1480         (match_operand:SI 2 "register_operand"))
1481    (match_dup 0)
1482    (parallel
1483        [(set (match_operand:SI 3 "register_operand")
1484              (match_operand:SI 4 "macc_msac_operand"))
1485         (clobber (match_operand:SI 5 "register_operand"))
1486         (clobber (match_dup 1))])]
1487   "ISA_HAS_MUL3
1488    && true_regnum (operands[1]) == LO_REGNUM
1489    && peep2_reg_dead_p (2, operands[1])
1490    && GP_REG_P (true_regnum (operands[3]))"
1491   [(parallel [(set (match_dup 0)
1492                    (match_dup 6))
1493               (clobber (match_dup 5))
1494               (clobber (match_dup 1))])
1495    (set (match_dup 3)
1496         (match_dup 7))]
1498   operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1499   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1500                                 operands[2], operands[0]);
1503 ;; Same as above, except LO is the initial target of the macc.
1505 ;; Operand 0: GPR (scratch)
1506 ;; Operand 1: LO
1507 ;; Operand 2: GPR (addend)
1508 ;; Operand 3: macc/msac
1509 ;; Operand 4: HI
1510 ;; Operand 5: GPR (destination)
1511 ;; Operand 6: new multiplication
1512 ;; Operand 7: new addition/subtraction
1513 (define_peephole2
1514   [(match_scratch:SI 0 "d")
1515    (set (match_operand:SI 1 "register_operand")
1516         (match_operand:SI 2 "register_operand"))
1517    (match_dup 0)
1518    (parallel
1519        [(set (match_dup 1)
1520              (match_operand:SI 3 "macc_msac_operand"))
1521         (clobber (match_operand:SI 4 "register_operand"))
1522         (clobber (scratch:SI))])
1523    (match_dup 0)
1524    (set (match_operand:SI 5 "register_operand")
1525         (unspec:SI [(match_dup 1) (match_dup 4)] UNSPEC_MFHILO))]
1526   "ISA_HAS_MUL3 && peep2_reg_dead_p (3, operands[1])"
1527   [(parallel [(set (match_dup 0)
1528                    (match_dup 6))
1529               (clobber (match_dup 4))
1530               (clobber (match_dup 1))])
1531    (set (match_dup 5)
1532         (match_dup 7))]
1534   operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1535   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1536                                 operands[2], operands[0]);
1539 (define_insn "*mul_sub_si"
1540   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1541         (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1542                   (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1543                            (match_operand:SI 3 "register_operand" "d,d,d"))))
1544    (clobber (match_scratch:SI 4 "=h,h,h"))
1545    (clobber (match_scratch:SI 5 "=X,1,l"))
1546    (clobber (match_scratch:SI 6 "=X,X,&d"))]
1547   "GENERATE_MADD_MSUB"
1548   "@
1549    msub\t%2,%3
1550    #
1551    #"
1552   [(set_attr "type"     "imadd")
1553    (set_attr "mode"     "SI")
1554    (set_attr "length"   "4,8,8")])
1556 ;; Split the above insn if we failed to get LO allocated.
1557 (define_split
1558   [(set (match_operand:SI 0 "register_operand")
1559         (minus:SI (match_operand:SI 1 "register_operand")
1560                   (mult:SI (match_operand:SI 2 "register_operand")
1561                            (match_operand:SI 3 "register_operand"))))
1562    (clobber (match_scratch:SI 4))
1563    (clobber (match_scratch:SI 5))
1564    (clobber (match_scratch:SI 6))]
1565   "reload_completed && !TARGET_DEBUG_D_MODE
1566    && GP_REG_P (true_regnum (operands[0]))
1567    && GP_REG_P (true_regnum (operands[1]))"
1568   [(parallel [(set (match_dup 6)
1569                    (mult:SI (match_dup 2) (match_dup 3)))
1570               (clobber (match_dup 4))
1571               (clobber (match_dup 5))])
1572    (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 6)))]
1573   "")
1575 ;; Splitter to copy result of MSUB to a general register
1576 (define_split
1577   [(set (match_operand:SI 0 "register_operand")
1578         (minus:SI (match_operand:SI 1 "register_operand")
1579                   (mult:SI (match_operand:SI 2 "register_operand")
1580                            (match_operand:SI 3 "register_operand"))))
1581    (clobber (match_scratch:SI 4))
1582    (clobber (match_scratch:SI 5))
1583    (clobber (match_scratch:SI 6))]
1584   "reload_completed && !TARGET_DEBUG_D_MODE
1585    && GP_REG_P (true_regnum (operands[0]))
1586    && true_regnum (operands[1]) == LO_REGNUM"
1587   [(parallel [(set (match_dup 1)
1588                    (minus:SI (match_dup 1)
1589                              (mult:SI (match_dup 2) (match_dup 3))))
1590               (clobber (match_dup 4))
1591               (clobber (match_dup 5))
1592               (clobber (match_dup 6))])
1593    (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1594   "")
1596 (define_insn "*muls"
1597   [(set (match_operand:SI                  0 "register_operand" "=l,d")
1598         (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1599                          (match_operand:SI 2 "register_operand" "d,d"))))
1600    (clobber (match_scratch:SI              3                    "=h,h"))
1601    (clobber (match_scratch:SI              4                    "=X,l"))]
1602   "ISA_HAS_MULS"
1603   "@
1604    muls\t$0,%1,%2
1605    muls\t%0,%1,%2"
1606   [(set_attr "type"     "imul,imul3")
1607    (set_attr "mode"     "SI")])
1609 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1611 (define_expand "<u>mulsidi3"
1612   [(parallel
1613       [(set (match_operand:DI 0 "register_operand")
1614             (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1615                      (any_extend:DI (match_operand:SI 2 "register_operand"))))
1616        (clobber (scratch:DI))
1617        (clobber (scratch:DI))
1618        (clobber (scratch:DI))])]
1619   "!TARGET_64BIT || !TARGET_FIX_R4000"
1621   if (!TARGET_64BIT)
1622     {
1623       if (!TARGET_FIX_R4000)
1624         emit_insn (gen_<u>mulsidi3_32bit_internal (operands[0], operands[1],
1625                                                    operands[2]));
1626       else
1627         emit_insn (gen_<u>mulsidi3_32bit_r4000 (operands[0], operands[1],
1628                                                 operands[2]));
1629       DONE;
1630     }
1633 (define_insn "<u>mulsidi3_32bit_internal"
1634   [(set (match_operand:DI 0 "register_operand" "=x")
1635         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1636                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1637   "!TARGET_64BIT && !TARGET_FIX_R4000 && !ISA_HAS_DSPR2"
1638   "mult<u>\t%1,%2"
1639   [(set_attr "type" "imul")
1640    (set_attr "mode" "SI")])
1642 (define_insn "<u>mulsidi3_32bit_r4000"
1643   [(set (match_operand:DI 0 "register_operand" "=d")
1644         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1645                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1646    (clobber (match_scratch:DI 3 "=x"))]
1647   "!TARGET_64BIT && TARGET_FIX_R4000"
1648   "mult<u>\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1649   [(set_attr "type" "imul")
1650    (set_attr "mode" "SI")
1651    (set_attr "length" "12")])
1653 (define_insn_and_split "*<u>mulsidi3_64bit"
1654   [(set (match_operand:DI 0 "register_operand" "=d")
1655         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1656                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1657    (clobber (match_scratch:DI 3 "=l"))
1658    (clobber (match_scratch:DI 4 "=h"))
1659    (clobber (match_scratch:DI 5 "=d"))]
1660   "TARGET_64BIT && !TARGET_FIX_R4000"
1661   "#"
1662   "&& reload_completed"
1663   [(parallel
1664        [(set (match_dup 3)
1665              (sign_extend:DI
1666                 (mult:SI (match_dup 1)
1667                          (match_dup 2))))
1668         (set (match_dup 4)
1669              (ashiftrt:DI
1670                 (mult:DI (any_extend:DI (match_dup 1))
1671                          (any_extend:DI (match_dup 2)))
1672                 (const_int 32)))])
1674    ;; OP5 <- LO, OP0 <- HI
1675    (set (match_dup 5) (unspec:DI [(match_dup 3) (match_dup 4)] UNSPEC_MFHILO))
1676    (set (match_dup 0) (unspec:DI [(match_dup 4) (match_dup 3)] UNSPEC_MFHILO))
1678    ;; Zero-extend OP5.
1679    (set (match_dup 5)
1680         (ashift:DI (match_dup 5)
1681                    (const_int 32)))
1682    (set (match_dup 5)
1683         (lshiftrt:DI (match_dup 5)
1684                      (const_int 32)))
1686    ;; Shift OP0 into place.
1687    (set (match_dup 0)
1688         (ashift:DI (match_dup 0)
1689                    (const_int 32)))
1691    ;; OR the two halves together
1692    (set (match_dup 0)
1693         (ior:DI (match_dup 0)
1694                 (match_dup 5)))]
1695   ""
1696   [(set_attr "type" "imul")
1697    (set_attr "mode" "SI")
1698    (set_attr "length" "24")])
1700 (define_insn "*<u>mulsidi3_64bit_parts"
1701   [(set (match_operand:DI 0 "register_operand" "=l")
1702         (sign_extend:DI
1703            (mult:SI (match_operand:SI 2 "register_operand" "d")
1704                     (match_operand:SI 3 "register_operand" "d"))))
1705    (set (match_operand:DI 1 "register_operand" "=h")
1706         (ashiftrt:DI
1707            (mult:DI (any_extend:DI (match_dup 2))
1708                     (any_extend:DI (match_dup 3)))
1709            (const_int 32)))]
1710   "TARGET_64BIT && !TARGET_FIX_R4000"
1711   "mult<u>\t%2,%3"
1712   [(set_attr "type" "imul")
1713    (set_attr "mode" "SI")])
1715 ;; Widening multiply with negation.
1716 (define_insn "*muls<u>_di"
1717   [(set (match_operand:DI 0 "register_operand" "=x")
1718         (neg:DI
1719          (mult:DI
1720           (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1721           (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1722   "!TARGET_64BIT && ISA_HAS_MULS"
1723   "muls<u>\t$0,%1,%2"
1724   [(set_attr "type" "imul")
1725    (set_attr "mode" "SI")])
1727 (define_insn "<u>msubsidi4"
1728   [(set (match_operand:DI 0 "register_operand" "=ka")
1729         (minus:DI
1730            (match_operand:DI 3 "register_operand" "0")
1731            (mult:DI
1732               (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1733               (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1734   "!TARGET_64BIT && (ISA_HAS_MSAC || GENERATE_MADD_MSUB || ISA_HAS_DSPR2)"
1736   if (ISA_HAS_DSPR2)
1737     return "msub<u>\t%q0,%1,%2";
1738   else if (TARGET_MIPS5500 || GENERATE_MADD_MSUB)
1739     return "msub<u>\t%1,%2";
1740   else
1741     return "msac<u>\t$0,%1,%2";
1743   [(set_attr "type" "imadd")
1744    (set_attr "mode" "SI")])
1746 ;; _highpart patterns
1748 (define_expand "<su>mulsi3_highpart"
1749   [(set (match_operand:SI 0 "register_operand")
1750         (truncate:SI
1751          (lshiftrt:DI
1752           (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1753                    (any_extend:DI (match_operand:SI 2 "register_operand")))
1754           (const_int 32))))]
1755   "ISA_HAS_MULHI || !TARGET_FIX_R4000"
1757   if (ISA_HAS_MULHI)
1758     emit_insn (gen_<su>mulsi3_highpart_mulhi_internal (operands[0],
1759                                                        operands[1],
1760                                                        operands[2]));
1761   else
1762     emit_insn (gen_<su>mulsi3_highpart_internal (operands[0], operands[1],
1763                                                  operands[2]));
1764   DONE;
1767 (define_insn "<su>mulsi3_highpart_internal"
1768   [(set (match_operand:SI 0 "register_operand" "=h")
1769         (truncate:SI
1770          (lshiftrt:DI
1771           (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1772                    (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1773           (const_int 32))))
1774    (clobber (match_scratch:SI 3 "=l"))]
1775   "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
1776   "mult<u>\t%1,%2"
1777   [(set_attr "type" "imul")
1778    (set_attr "mode" "SI")])
1780 (define_insn "<su>mulsi3_highpart_mulhi_internal"
1781   [(set (match_operand:SI 0 "register_operand" "=h,d")
1782         (truncate:SI
1783          (lshiftrt:DI
1784           (mult:DI
1785            (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1786            (any_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
1787           (const_int 32))))
1788    (clobber (match_scratch:SI 3 "=l,l"))
1789    (clobber (match_scratch:SI 4 "=X,h"))]
1790   "ISA_HAS_MULHI"
1791   "@
1792    mult<u>\t%1,%2
1793    mulhi<u>\t%0,%1,%2"
1794   [(set_attr "type" "imul,imul3")
1795    (set_attr "mode" "SI")])
1797 (define_insn "*<su>mulsi3_highpart_neg_mulhi_internal"
1798   [(set (match_operand:SI 0 "register_operand" "=h,d")
1799         (truncate:SI
1800          (lshiftrt:DI
1801           (neg:DI
1802            (mult:DI
1803             (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1804             (any_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
1805           (const_int 32))))
1806    (clobber (match_scratch:SI 3 "=l,l"))
1807    (clobber (match_scratch:SI 4 "=X,h"))]
1808   "ISA_HAS_MULHI"
1809   "@
1810    mulshi<u>\t%.,%1,%2
1811    mulshi<u>\t%0,%1,%2"
1812   [(set_attr "type" "imul,imul3")
1813    (set_attr "mode" "SI")])
1815 ;; Disable unsigned multiplication for -mfix-vr4120.  This is for VR4120
1816 ;; errata MD(0), which says that dmultu does not always produce the
1817 ;; correct result.
1818 (define_insn "<su>muldi3_highpart"
1819   [(set (match_operand:DI 0 "register_operand" "=h")
1820         (truncate:DI
1821          (lshiftrt:TI
1822           (mult:TI
1823            (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
1824            (any_extend:TI (match_operand:DI 2 "register_operand" "d")))
1825           (const_int 64))))
1826    (clobber (match_scratch:DI 3 "=l"))]
1827   "TARGET_64BIT && !TARGET_FIX_R4000
1828    && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
1829   "dmult<u>\t%1,%2"
1830   [(set_attr "type" "imul")
1831    (set_attr "mode" "DI")])
1833 ;; The R4650 supports a 32-bit multiply/ 64-bit accumulate
1834 ;; instruction.  The HI/LO registers are used as a 64-bit accumulator.
1836 (define_insn "madsi"
1837   [(set (match_operand:SI 0 "register_operand" "+l")
1838         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1839                           (match_operand:SI 2 "register_operand" "d"))
1840                  (match_dup 0)))
1841    (clobber (match_scratch:SI 3 "=h"))]
1842   "TARGET_MAD"
1843   "mad\t%1,%2"
1844   [(set_attr "type"     "imadd")
1845    (set_attr "mode"     "SI")])
1847 (define_insn "<u>maddsidi4"
1848   [(set (match_operand:DI 0 "register_operand" "=ka")
1849         (plus:DI
1850          (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1851                   (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1852          (match_operand:DI 3 "register_operand" "0")))]
1853   "(TARGET_MAD || ISA_HAS_MACC || GENERATE_MADD_MSUB || ISA_HAS_DSPR2)
1854    && !TARGET_64BIT"
1856   if (TARGET_MAD)
1857     return "mad<u>\t%1,%2";
1858   else if (ISA_HAS_DSPR2)
1859     return "madd<u>\t%q0,%1,%2";
1860   else if (GENERATE_MADD_MSUB || TARGET_MIPS5500)
1861     return "madd<u>\t%1,%2";
1862   else
1863     /* See comment in *macc.  */
1864     return "%[macc<u>\t%@,%1,%2%]";
1866   [(set_attr "type" "imadd")
1867    (set_attr "mode" "SI")])
1869 ;; Floating point multiply accumulate instructions.
1871 (define_insn "*madd<mode>"
1872   [(set (match_operand:ANYF 0 "register_operand" "=f")
1873         (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1874                               (match_operand:ANYF 2 "register_operand" "f"))
1875                    (match_operand:ANYF 3 "register_operand" "f")))]
1876   "ISA_HAS_FP4 && TARGET_FUSED_MADD"
1877   "madd.<fmt>\t%0,%3,%1,%2"
1878   [(set_attr "type" "fmadd")
1879    (set_attr "mode" "<UNITMODE>")])
1881 (define_insn "*msub<mode>"
1882   [(set (match_operand:ANYF 0 "register_operand" "=f")
1883         (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1884                                (match_operand:ANYF 2 "register_operand" "f"))
1885                     (match_operand:ANYF 3 "register_operand" "f")))]
1886   "ISA_HAS_FP4 && TARGET_FUSED_MADD"
1887   "msub.<fmt>\t%0,%3,%1,%2"
1888   [(set_attr "type" "fmadd")
1889    (set_attr "mode" "<UNITMODE>")])
1891 (define_insn "*nmadd<mode>"
1892   [(set (match_operand:ANYF 0 "register_operand" "=f")
1893         (neg:ANYF (plus:ANYF
1894                    (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1895                               (match_operand:ANYF 2 "register_operand" "f"))
1896                    (match_operand:ANYF 3 "register_operand" "f"))))]
1897   "ISA_HAS_NMADD_NMSUB (<MODE>mode)
1898    && TARGET_FUSED_MADD
1899    && HONOR_SIGNED_ZEROS (<MODE>mode)
1900    && !HONOR_NANS (<MODE>mode)"
1901   "nmadd.<fmt>\t%0,%3,%1,%2"
1902   [(set_attr "type" "fmadd")
1903    (set_attr "mode" "<UNITMODE>")])
1905 (define_insn "*nmadd<mode>_fastmath"
1906   [(set (match_operand:ANYF 0 "register_operand" "=f")
1907         (minus:ANYF
1908          (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
1909                     (match_operand:ANYF 2 "register_operand" "f"))
1910          (match_operand:ANYF 3 "register_operand" "f")))]
1911   "ISA_HAS_NMADD_NMSUB (<MODE>mode)
1912    && TARGET_FUSED_MADD
1913    && !HONOR_SIGNED_ZEROS (<MODE>mode)
1914    && !HONOR_NANS (<MODE>mode)"
1915   "nmadd.<fmt>\t%0,%3,%1,%2"
1916   [(set_attr "type" "fmadd")
1917    (set_attr "mode" "<UNITMODE>")])
1919 (define_insn "*nmsub<mode>"
1920   [(set (match_operand:ANYF 0 "register_operand" "=f")
1921         (neg:ANYF (minus:ANYF
1922                    (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
1923                               (match_operand:ANYF 3 "register_operand" "f"))
1924                    (match_operand:ANYF 1 "register_operand" "f"))))]
1925   "ISA_HAS_NMADD_NMSUB (<MODE>mode)
1926    && TARGET_FUSED_MADD
1927    && HONOR_SIGNED_ZEROS (<MODE>mode)
1928    && !HONOR_NANS (<MODE>mode)"
1929   "nmsub.<fmt>\t%0,%1,%2,%3"
1930   [(set_attr "type" "fmadd")
1931    (set_attr "mode" "<UNITMODE>")])
1933 (define_insn "*nmsub<mode>_fastmath"
1934   [(set (match_operand:ANYF 0 "register_operand" "=f")
1935         (minus:ANYF
1936          (match_operand:ANYF 1 "register_operand" "f")
1937          (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
1938                     (match_operand:ANYF 3 "register_operand" "f"))))]
1939   "ISA_HAS_NMADD_NMSUB (<MODE>mode)
1940    && TARGET_FUSED_MADD
1941    && !HONOR_SIGNED_ZEROS (<MODE>mode)
1942    && !HONOR_NANS (<MODE>mode)"
1943   "nmsub.<fmt>\t%0,%1,%2,%3"
1944   [(set_attr "type" "fmadd")
1945    (set_attr "mode" "<UNITMODE>")])
1948 ;;  ....................
1950 ;;      DIVISION and REMAINDER
1952 ;;  ....................
1955 (define_expand "div<mode>3"
1956   [(set (match_operand:ANYF 0 "register_operand")
1957         (div:ANYF (match_operand:ANYF 1 "reg_or_1_operand")
1958                   (match_operand:ANYF 2 "register_operand")))]
1959   "<divide_condition>"
1961   if (const_1_operand (operands[1], <MODE>mode))
1962     if (!(<recip_condition> && flag_unsafe_math_optimizations))
1963       operands[1] = force_reg (<MODE>mode, operands[1]);
1966 ;; These patterns work around the early SB-1 rev2 core "F1" erratum:
1968 ;; If an mfc1 or dmfc1 happens to access the floating point register
1969 ;; file at the same time a long latency operation (div, sqrt, recip,
1970 ;; sqrt) iterates an intermediate result back through the floating
1971 ;; point register file bypass, then instead returning the correct
1972 ;; register value the mfc1 or dmfc1 operation returns the intermediate
1973 ;; result of the long latency operation.
1975 ;; The workaround is to insert an unconditional 'mov' from/to the
1976 ;; long latency op destination register.
1978 (define_insn "*div<mode>3"
1979   [(set (match_operand:ANYF 0 "register_operand" "=f")
1980         (div:ANYF (match_operand:ANYF 1 "register_operand" "f")
1981                   (match_operand:ANYF 2 "register_operand" "f")))]
1982   "<divide_condition>"
1984   if (TARGET_FIX_SB1)
1985     return "div.<fmt>\t%0,%1,%2\;mov.<fmt>\t%0,%0";
1986   else
1987     return "div.<fmt>\t%0,%1,%2";
1989   [(set_attr "type" "fdiv")
1990    (set_attr "mode" "<UNITMODE>")
1991    (set (attr "length")
1992         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1993                       (const_int 8)
1994                       (const_int 4)))])
1996 (define_insn "*recip<mode>3"
1997   [(set (match_operand:ANYF 0 "register_operand" "=f")
1998         (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
1999                   (match_operand:ANYF 2 "register_operand" "f")))]
2000   "<recip_condition> && flag_unsafe_math_optimizations"
2002   if (TARGET_FIX_SB1)
2003     return "recip.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
2004   else
2005     return "recip.<fmt>\t%0,%2";
2007   [(set_attr "type" "frdiv")
2008    (set_attr "mode" "<UNITMODE>")
2009    (set (attr "length")
2010         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2011                       (const_int 8)
2012                       (const_int 4)))])
2014 ;; VR4120 errata MD(A1): signed division instructions do not work correctly
2015 ;; with negative operands.  We use special libgcc functions instead.
2016 (define_insn "divmod<mode>4"
2017   [(set (match_operand:GPR 0 "register_operand" "=l")
2018         (div:GPR (match_operand:GPR 1 "register_operand" "d")
2019                  (match_operand:GPR 2 "register_operand" "d")))
2020    (set (match_operand:GPR 3 "register_operand" "=h")
2021         (mod:GPR (match_dup 1)
2022                  (match_dup 2)))]
2023   "!TARGET_FIX_VR4120"
2024   { return mips_output_division ("<d>div\t$0,%1,%2", operands); }
2025   [(set_attr "type" "idiv")
2026    (set_attr "mode" "<MODE>")])
2028 (define_insn "udivmod<mode>4"
2029   [(set (match_operand:GPR 0 "register_operand" "=l")
2030         (udiv:GPR (match_operand:GPR 1 "register_operand" "d")
2031                   (match_operand:GPR 2 "register_operand" "d")))
2032    (set (match_operand:GPR 3 "register_operand" "=h")
2033         (umod:GPR (match_dup 1)
2034                   (match_dup 2)))]
2035   ""
2036   { return mips_output_division ("<d>divu\t$0,%1,%2", operands); }
2037   [(set_attr "type" "idiv")
2038    (set_attr "mode" "<MODE>")])
2041 ;;  ....................
2043 ;;      SQUARE ROOT
2045 ;;  ....................
2047 ;; These patterns work around the early SB-1 rev2 core "F1" erratum (see
2048 ;; "*div[sd]f3" comment for details).
2050 (define_insn "sqrt<mode>2"
2051   [(set (match_operand:ANYF 0 "register_operand" "=f")
2052         (sqrt:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2053   "<sqrt_condition>"
2055   if (TARGET_FIX_SB1)
2056     return "sqrt.<fmt>\t%0,%1\;mov.<fmt>\t%0,%0";
2057   else
2058     return "sqrt.<fmt>\t%0,%1";
2060   [(set_attr "type" "fsqrt")
2061    (set_attr "mode" "<UNITMODE>")
2062    (set (attr "length")
2063         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2064                       (const_int 8)
2065                       (const_int 4)))])
2067 (define_insn "*rsqrt<mode>a"
2068   [(set (match_operand:ANYF 0 "register_operand" "=f")
2069         (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
2070                   (sqrt:ANYF (match_operand:ANYF 2 "register_operand" "f"))))]
2071   "<recip_condition> && flag_unsafe_math_optimizations"
2073   if (TARGET_FIX_SB1)
2074     return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
2075   else
2076     return "rsqrt.<fmt>\t%0,%2";
2078   [(set_attr "type" "frsqrt")
2079    (set_attr "mode" "<UNITMODE>")
2080    (set (attr "length")
2081         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2082                       (const_int 8)
2083                       (const_int 4)))])
2085 (define_insn "*rsqrt<mode>b"
2086   [(set (match_operand:ANYF 0 "register_operand" "=f")
2087         (sqrt:ANYF (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
2088                              (match_operand:ANYF 2 "register_operand" "f"))))]
2089   "<recip_condition> && flag_unsafe_math_optimizations"
2091   if (TARGET_FIX_SB1)
2092     return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
2093   else
2094     return "rsqrt.<fmt>\t%0,%2";
2096   [(set_attr "type" "frsqrt")
2097    (set_attr "mode" "<UNITMODE>")
2098    (set (attr "length")
2099         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2100                       (const_int 8)
2101                       (const_int 4)))])
2104 ;;  ....................
2106 ;;      ABSOLUTE VALUE
2108 ;;  ....................
2110 ;; Do not use the integer abs macro instruction, since that signals an
2111 ;; exception on -2147483648 (sigh).
2113 ;; abs.fmt is an arithmetic instruction and treats all NaN inputs as
2114 ;; invalid; it does not clear their sign bits.  We therefore can't use
2115 ;; abs.fmt if the signs of NaNs matter.
2117 (define_insn "abs<mode>2"
2118   [(set (match_operand:ANYF 0 "register_operand" "=f")
2119         (abs:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2120   "!HONOR_NANS (<MODE>mode)"
2121   "abs.<fmt>\t%0,%1"
2122   [(set_attr "type" "fabs")
2123    (set_attr "mode" "<UNITMODE>")])
2126 ;;  ...................
2128 ;;  Count leading zeroes.
2130 ;;  ...................
2133 (define_insn "clz<mode>2"
2134   [(set (match_operand:GPR 0 "register_operand" "=d")
2135         (clz:GPR (match_operand:GPR 1 "register_operand" "d")))]
2136   "ISA_HAS_CLZ_CLO"
2137   "<d>clz\t%0,%1"
2138   [(set_attr "type" "clz")
2139    (set_attr "mode" "<MODE>")])
2142 ;;  ....................
2144 ;;      NEGATION and ONE'S COMPLEMENT
2146 ;;  ....................
2148 (define_insn "negsi2"
2149   [(set (match_operand:SI 0 "register_operand" "=d")
2150         (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2151   ""
2153   if (TARGET_MIPS16)
2154     return "neg\t%0,%1";
2155   else
2156     return "subu\t%0,%.,%1";
2158   [(set_attr "type"     "arith")
2159    (set_attr "mode"     "SI")])
2161 (define_insn "negdi2"
2162   [(set (match_operand:DI 0 "register_operand" "=d")
2163         (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2164   "TARGET_64BIT && !TARGET_MIPS16"
2165   "dsubu\t%0,%.,%1"
2166   [(set_attr "type"     "arith")
2167    (set_attr "mode"     "DI")])
2169 ;; neg.fmt is an arithmetic instruction and treats all NaN inputs as
2170 ;; invalid; it does not flip their sign bit.  We therefore can't use
2171 ;; neg.fmt if the signs of NaNs matter.
2173 (define_insn "neg<mode>2"
2174   [(set (match_operand:ANYF 0 "register_operand" "=f")
2175         (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2176   "!HONOR_NANS (<MODE>mode)"
2177   "neg.<fmt>\t%0,%1"
2178   [(set_attr "type" "fneg")
2179    (set_attr "mode" "<UNITMODE>")])
2181 (define_insn "one_cmpl<mode>2"
2182   [(set (match_operand:GPR 0 "register_operand" "=d")
2183         (not:GPR (match_operand:GPR 1 "register_operand" "d")))]
2184   ""
2186   if (TARGET_MIPS16)
2187     return "not\t%0,%1";
2188   else
2189     return "nor\t%0,%.,%1";
2191   [(set_attr "type" "logical")
2192    (set_attr "mode" "<MODE>")])
2195 ;;  ....................
2197 ;;      LOGICAL
2199 ;;  ....................
2202 ;; Many of these instructions use trivial define_expands, because we
2203 ;; want to use a different set of constraints when TARGET_MIPS16.
2205 (define_expand "and<mode>3"
2206   [(set (match_operand:GPR 0 "register_operand")
2207         (and:GPR (match_operand:GPR 1 "register_operand")
2208                  (match_operand:GPR 2 "uns_arith_operand")))]
2209   ""
2211   if (TARGET_MIPS16)
2212     operands[2] = force_reg (<MODE>mode, operands[2]);
2215 (define_insn "*and<mode>3"
2216   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2217         (and:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2218                  (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2219   "!TARGET_MIPS16"
2220   "@
2221    and\t%0,%1,%2
2222    andi\t%0,%1,%x2"
2223   [(set_attr "type" "logical")
2224    (set_attr "mode" "<MODE>")])
2226 (define_insn "*and<mode>3_mips16"
2227   [(set (match_operand:GPR 0 "register_operand" "=d")
2228         (and:GPR (match_operand:GPR 1 "register_operand" "%0")
2229                  (match_operand:GPR 2 "register_operand" "d")))]
2230   "TARGET_MIPS16"
2231   "and\t%0,%2"
2232   [(set_attr "type" "logical")
2233    (set_attr "mode" "<MODE>")])
2235 (define_expand "ior<mode>3"
2236   [(set (match_operand:GPR 0 "register_operand")
2237         (ior:GPR (match_operand:GPR 1 "register_operand")
2238                  (match_operand:GPR 2 "uns_arith_operand")))]
2239   ""
2241   if (TARGET_MIPS16)
2242     operands[2] = force_reg (<MODE>mode, operands[2]);
2245 (define_insn "*ior<mode>3"
2246   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2247         (ior:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2248                  (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2249   "!TARGET_MIPS16"
2250   "@
2251    or\t%0,%1,%2
2252    ori\t%0,%1,%x2"
2253   [(set_attr "type" "logical")
2254    (set_attr "mode" "<MODE>")])
2256 (define_insn "*ior<mode>3_mips16"
2257   [(set (match_operand:GPR 0 "register_operand" "=d")
2258         (ior:GPR (match_operand:GPR 1 "register_operand" "%0")
2259                  (match_operand:GPR 2 "register_operand" "d")))]
2260   "TARGET_MIPS16"
2261   "or\t%0,%2"
2262   [(set_attr "type" "logical")
2263    (set_attr "mode" "<MODE>")])
2265 (define_expand "xor<mode>3"
2266   [(set (match_operand:GPR 0 "register_operand")
2267         (xor:GPR (match_operand:GPR 1 "register_operand")
2268                  (match_operand:GPR 2 "uns_arith_operand")))]
2269   ""
2270   "")
2272 (define_insn ""
2273   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2274         (xor:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2275                  (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2276   "!TARGET_MIPS16"
2277   "@
2278    xor\t%0,%1,%2
2279    xori\t%0,%1,%x2"
2280   [(set_attr "type" "logical")
2281    (set_attr "mode" "<MODE>")])
2283 (define_insn ""
2284   [(set (match_operand:GPR 0 "register_operand" "=d,t,t")
2285         (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d")
2286                  (match_operand:GPR 2 "uns_arith_operand" "d,K,d")))]
2287   "TARGET_MIPS16"
2288   "@
2289    xor\t%0,%2
2290    cmpi\t%1,%2
2291    cmp\t%1,%2"
2292   [(set_attr "type" "logical,arith,arith")
2293    (set_attr "mode" "<MODE>")
2294    (set_attr_alternative "length"
2295                 [(const_int 4)
2296                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2297                                (const_int 4)
2298                                (const_int 8))
2299                  (const_int 4)])])
2301 (define_insn "*nor<mode>3"
2302   [(set (match_operand:GPR 0 "register_operand" "=d")
2303         (and:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
2304                  (not:GPR (match_operand:GPR 2 "register_operand" "d"))))]
2305   "!TARGET_MIPS16"
2306   "nor\t%0,%1,%2"
2307   [(set_attr "type" "logical")
2308    (set_attr "mode" "<MODE>")])
2311 ;;  ....................
2313 ;;      TRUNCATION
2315 ;;  ....................
2319 (define_insn "truncdfsf2"
2320   [(set (match_operand:SF 0 "register_operand" "=f")
2321         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2322   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2323   "cvt.s.d\t%0,%1"
2324   [(set_attr "type"     "fcvt")
2325    (set_attr "cnv_mode" "D2S")   
2326    (set_attr "mode"     "SF")])
2328 ;; Integer truncation patterns.  Truncating SImode values to smaller
2329 ;; modes is a no-op, as it is for most other GCC ports.  Truncating
2330 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
2331 ;; need to make sure that the lower 32 bits are properly sign-extended
2332 ;; (see TRULY_NOOP_TRUNCATION).  Truncating DImode values into modes
2333 ;; smaller than SImode is equivalent to two separate truncations:
2335 ;;                        A       B
2336 ;;    DI ---> HI  ==  DI ---> SI ---> HI
2337 ;;    DI ---> QI  ==  DI ---> SI ---> QI
2339 ;; Step A needs a real instruction but step B does not.
2341 (define_insn "truncdisi2"
2342   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
2343         (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
2344   "TARGET_64BIT"
2345   "@
2346     sll\t%0,%1,0
2347     sw\t%1,%0"
2348   [(set_attr "type" "shift,store")
2349    (set_attr "mode" "SI")
2350    (set_attr "extended_mips16" "yes,*")])
2352 (define_insn "truncdihi2"
2353   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
2354         (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
2355   "TARGET_64BIT"
2356   "@
2357     sll\t%0,%1,0
2358     sh\t%1,%0"
2359   [(set_attr "type" "shift,store")
2360    (set_attr "mode" "SI")
2361    (set_attr "extended_mips16" "yes,*")])
2363 (define_insn "truncdiqi2"
2364   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
2365         (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
2366   "TARGET_64BIT"
2367   "@
2368     sll\t%0,%1,0
2369     sb\t%1,%0"
2370   [(set_attr "type" "shift,store")
2371    (set_attr "mode" "SI")
2372    (set_attr "extended_mips16" "yes,*")])
2374 ;; Combiner patterns to optimize shift/truncate combinations.
2376 (define_insn ""
2377   [(set (match_operand:SUBDI 0 "register_operand" "=d")
2378         (truncate:SUBDI
2379           (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2380                        (match_operand:DI 2 "const_arith_operand" ""))))]
2381   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
2382   "dsra\t%0,%1,%2"
2383   [(set_attr "type" "shift")
2384    (set_attr "mode" "SI")])
2386 (define_insn ""
2387   [(set (match_operand:SUBDI 0 "register_operand" "=d")
2388         (truncate:SUBDI
2389           (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2390                        (const_int 32))))]
2391   "TARGET_64BIT && !TARGET_MIPS16"
2392   "dsra\t%0,%1,32"
2393   [(set_attr "type" "shift")
2394    (set_attr "mode" "SI")])
2397 ;; Combiner patterns for truncate/sign_extend combinations.  The SI versions
2398 ;; use the shift/truncate patterns above.
2400 (define_insn_and_split "*extenddi_truncate<mode>"
2401   [(set (match_operand:DI 0 "register_operand" "=d")
2402         (sign_extend:DI
2403             (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
2404   "TARGET_64BIT && !TARGET_MIPS16"
2405   "#"
2406   "&& reload_completed"
2407   [(set (match_dup 2)
2408         (ashift:DI (match_dup 1)
2409                    (match_dup 3)))
2410    (set (match_dup 0)
2411         (ashiftrt:DI (match_dup 2)
2412                      (match_dup 3)))]
2414   operands[2] = gen_lowpart (DImode, operands[0]);
2415   operands[3] = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (<MODE>mode));
2418 (define_insn_and_split "*extendsi_truncate<mode>"
2419   [(set (match_operand:SI 0 "register_operand" "=d")
2420         (sign_extend:SI
2421             (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
2422   "TARGET_64BIT && !TARGET_MIPS16"
2423   "#"
2424   "&& reload_completed"
2425   [(set (match_dup 2)
2426         (ashift:DI (match_dup 1)
2427                    (match_dup 3)))
2428    (set (match_dup 0)
2429         (truncate:SI (ashiftrt:DI (match_dup 2)
2430                                   (match_dup 3))))]
2432   operands[2] = gen_lowpart (DImode, operands[0]);
2433   operands[3] = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (<MODE>mode));
2436 ;; Combiner patterns to optimize truncate/zero_extend combinations.
2438 (define_insn "*zero_extend<mode>_trunchi"
2439   [(set (match_operand:GPR 0 "register_operand" "=d")
2440         (zero_extend:GPR
2441             (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
2442   "TARGET_64BIT && !TARGET_MIPS16"
2443   "andi\t%0,%1,0xffff"
2444   [(set_attr "type" "logical")
2445    (set_attr "mode" "<MODE>")])
2447 (define_insn "*zero_extend<mode>_truncqi"
2448   [(set (match_operand:GPR 0 "register_operand" "=d")
2449         (zero_extend:GPR
2450             (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
2451   "TARGET_64BIT && !TARGET_MIPS16"
2452   "andi\t%0,%1,0xff"
2453   [(set_attr "type" "logical")
2454    (set_attr "mode" "<MODE>")])
2456 (define_insn ""
2457   [(set (match_operand:HI 0 "register_operand" "=d")
2458         (zero_extend:HI
2459             (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
2460   "TARGET_64BIT && !TARGET_MIPS16"
2461   "andi\t%0,%1,0xff"
2462   [(set_attr "type" "logical")
2463    (set_attr "mode" "HI")])
2466 ;;  ....................
2468 ;;      ZERO EXTENSION
2470 ;;  ....................
2472 ;; Extension insns.
2474 (define_insn_and_split "zero_extendsidi2"
2475   [(set (match_operand:DI 0 "register_operand" "=d,d")
2476         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,W")))]
2477   "TARGET_64BIT"
2478   "@
2479    #
2480    lwu\t%0,%1"
2481   "&& reload_completed && REG_P (operands[1])"
2482   [(set (match_dup 0)
2483         (ashift:DI (match_dup 1) (const_int 32)))
2484    (set (match_dup 0)
2485         (lshiftrt:DI (match_dup 0) (const_int 32)))]
2486   { operands[1] = gen_lowpart (DImode, operands[1]); }
2487   [(set_attr "type" "multi,load")
2488    (set_attr "mode" "DI")
2489    (set_attr "length" "8,*")])
2491 ;; Combine is not allowed to convert this insn into a zero_extendsidi2
2492 ;; because of TRULY_NOOP_TRUNCATION.
2494 (define_insn_and_split "*clear_upper32"
2495   [(set (match_operand:DI 0 "register_operand" "=d,d")
2496         (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,W")
2497                 (const_int 4294967295)))]
2498   "TARGET_64BIT"
2500   if (which_alternative == 0)
2501     return "#";
2503   operands[1] = gen_lowpart (SImode, operands[1]);
2504   return "lwu\t%0,%1";
2506   "&& reload_completed && REG_P (operands[1])"
2507   [(set (match_dup 0)
2508         (ashift:DI (match_dup 1) (const_int 32)))
2509    (set (match_dup 0)
2510         (lshiftrt:DI (match_dup 0) (const_int 32)))]
2511   ""
2512   [(set_attr "type" "multi,load")
2513    (set_attr "mode" "DI")
2514    (set_attr "length" "8,*")])
2516 (define_expand "zero_extend<SHORT:mode><GPR:mode>2"
2517   [(set (match_operand:GPR 0 "register_operand")
2518         (zero_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
2519   ""
2521   if (TARGET_MIPS16 && !GENERATE_MIPS16E
2522       && !memory_operand (operands[1], <SHORT:MODE>mode))
2523     {
2524       emit_insn (gen_and<GPR:mode>3 (operands[0],
2525                                      gen_lowpart (<GPR:MODE>mode, operands[1]),
2526                                      force_reg (<GPR:MODE>mode,
2527                                                 GEN_INT (<SHORT:mask>))));
2528       DONE;
2529     }
2532 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2"
2533   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2534         (zero_extend:GPR
2535              (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2536   "!TARGET_MIPS16"
2537   "@
2538    andi\t%0,%1,<SHORT:mask>
2539    l<SHORT:size>u\t%0,%1"
2540   [(set_attr "type" "logical,load")
2541    (set_attr "mode" "<GPR:MODE>")])
2543 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16e"
2544   [(set (match_operand:GPR 0 "register_operand" "=d")
2545         (zero_extend:GPR (match_operand:SHORT 1 "register_operand" "0")))]
2546   "GENERATE_MIPS16E"
2547   "ze<SHORT:size>\t%0"
2548   [(set_attr "type" "arith")
2549    (set_attr "mode" "<GPR:MODE>")])
2551 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16"
2552   [(set (match_operand:GPR 0 "register_operand" "=d")
2553         (zero_extend:GPR (match_operand:SHORT 1 "memory_operand" "m")))]
2554   "TARGET_MIPS16"
2555   "l<SHORT:size>u\t%0,%1"
2556   [(set_attr "type" "load")
2557    (set_attr "mode" "<GPR:MODE>")])
2559 (define_expand "zero_extendqihi2"
2560   [(set (match_operand:HI 0 "register_operand")
2561         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2562   ""
2564   if (TARGET_MIPS16 && !memory_operand (operands[1], QImode))
2565     {
2566       emit_insn (gen_zero_extendqisi2 (gen_lowpart (SImode, operands[0]),
2567                                        operands[1]));
2568       DONE;
2569     }
2572 (define_insn "*zero_extendqihi2"
2573   [(set (match_operand:HI 0 "register_operand" "=d,d")
2574         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2575   "!TARGET_MIPS16"
2576   "@
2577    andi\t%0,%1,0x00ff
2578    lbu\t%0,%1"
2579   [(set_attr "type" "logical,load")
2580    (set_attr "mode" "HI")])
2582 (define_insn "*zero_extendqihi2_mips16"
2583   [(set (match_operand:HI 0 "register_operand" "=d")
2584         (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2585   "TARGET_MIPS16"
2586   "lbu\t%0,%1"
2587   [(set_attr "type" "load")
2588    (set_attr "mode" "HI")])
2591 ;;  ....................
2593 ;;      SIGN EXTENSION
2595 ;;  ....................
2597 ;; Extension insns.
2598 ;; Those for integer source operand are ordered widest source type first.
2600 ;; When TARGET_64BIT, all SImode integer registers should already be in
2601 ;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2).  We can
2602 ;; therefore get rid of register->register instructions if we constrain
2603 ;; the source to be in the same register as the destination.
2605 ;; The register alternative has type "arith" so that the pre-reload
2606 ;; scheduler will treat it as a move.  This reflects what happens if
2607 ;; the register alternative needs a reload.
2608 (define_insn_and_split "extendsidi2"
2609   [(set (match_operand:DI 0 "register_operand" "=d,d")
2610         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,m")))]
2611   "TARGET_64BIT"
2612   "@
2613    #
2614    lw\t%0,%1"
2615   "&& reload_completed && register_operand (operands[1], VOIDmode)"
2616   [(const_int 0)]
2618   emit_note (NOTE_INSN_DELETED);
2619   DONE;
2621   [(set_attr "type" "arith,load")
2622    (set_attr "mode" "DI")])
2624 (define_expand "extend<SHORT:mode><GPR:mode>2"
2625   [(set (match_operand:GPR 0 "register_operand")
2626         (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
2627   "")
2629 (define_insn "*extend<SHORT:mode><GPR:mode>2_mips16e"
2630   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2631         (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand" "0,m")))]
2632   "GENERATE_MIPS16E"
2633   "@
2634    se<SHORT:size>\t%0
2635    l<SHORT:size>\t%0,%1"
2636   [(set_attr "type" "signext,load")
2637    (set_attr "mode" "<GPR:MODE>")])
2639 (define_insn_and_split "*extend<SHORT:mode><GPR:mode>2"
2640   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2641         (sign_extend:GPR
2642              (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2643   "!ISA_HAS_SEB_SEH && !GENERATE_MIPS16E"
2644   "@
2645    #
2646    l<SHORT:size>\t%0,%1"
2647   "&& reload_completed && REG_P (operands[1])"
2648   [(set (match_dup 0) (ashift:GPR (match_dup 1) (match_dup 2)))
2649    (set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))]
2651   operands[1] = gen_lowpart (<GPR:MODE>mode, operands[1]);
2652   operands[2] = GEN_INT (GET_MODE_BITSIZE (<GPR:MODE>mode)
2653                          - GET_MODE_BITSIZE (<SHORT:MODE>mode));
2655   [(set_attr "type" "arith,load")
2656    (set_attr "mode" "<GPR:MODE>")
2657    (set_attr "length" "8,*")])
2659 (define_insn "*extend<SHORT:mode><GPR:mode>2_se<SHORT:size>"
2660   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2661         (sign_extend:GPR
2662              (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2663   "ISA_HAS_SEB_SEH"
2664   "@
2665    se<SHORT:size>\t%0,%1
2666    l<SHORT:size>\t%0,%1"
2667   [(set_attr "type" "signext,load")
2668    (set_attr "mode" "<GPR:MODE>")])
2670 (define_expand "extendqihi2"
2671   [(set (match_operand:HI 0 "register_operand")
2672         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2673   "")
2675 (define_insn "*extendqihi2_mips16e"
2676   [(set (match_operand:HI 0 "register_operand" "=d,d")
2677         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,m")))]
2678   "GENERATE_MIPS16E"
2679   "@
2680    seb\t%0
2681    lb\t%0,%1"
2682   [(set_attr "type" "signext,load")
2683    (set_attr "mode" "SI")])
2685 (define_insn_and_split "*extendqihi2"
2686   [(set (match_operand:HI 0 "register_operand" "=d,d")
2687         (sign_extend:HI
2688              (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2689   "!ISA_HAS_SEB_SEH && !GENERATE_MIPS16E"
2690   "@
2691    #
2692    lb\t%0,%1"
2693   "&& reload_completed && REG_P (operands[1])"
2694   [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
2695    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
2697   operands[0] = gen_lowpart (SImode, operands[0]);
2698   operands[1] = gen_lowpart (SImode, operands[1]);
2699   operands[2] = GEN_INT (GET_MODE_BITSIZE (SImode)
2700                          - GET_MODE_BITSIZE (QImode));
2702   [(set_attr "type" "multi,load")
2703    (set_attr "mode" "SI")
2704    (set_attr "length" "8,*")])
2706 (define_insn "*extendqihi2_seb"
2707   [(set (match_operand:HI 0 "register_operand" "=d,d")
2708         (sign_extend:HI
2709              (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2710   "ISA_HAS_SEB_SEH"
2711   "@
2712    seb\t%0,%1
2713    lb\t%0,%1"
2714   [(set_attr "type" "signext,load")
2715    (set_attr "mode" "SI")])
2717 (define_insn "extendsfdf2"
2718   [(set (match_operand:DF 0 "register_operand" "=f")
2719         (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2720   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2721   "cvt.d.s\t%0,%1"
2722   [(set_attr "type"     "fcvt")
2723    (set_attr "cnv_mode" "S2D")   
2724    (set_attr "mode"     "DF")])
2727 ;;  ....................
2729 ;;      CONVERSIONS
2731 ;;  ....................
2733 (define_expand "fix_truncdfsi2"
2734   [(set (match_operand:SI 0 "register_operand")
2735         (fix:SI (match_operand:DF 1 "register_operand")))]
2736   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2738   if (!ISA_HAS_TRUNC_W)
2739     {
2740       emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
2741       DONE;
2742     }
2745 (define_insn "fix_truncdfsi2_insn"
2746   [(set (match_operand:SI 0 "register_operand" "=f")
2747         (fix:SI (match_operand:DF 1 "register_operand" "f")))]
2748   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
2749   "trunc.w.d %0,%1"
2750   [(set_attr "type"     "fcvt")
2751    (set_attr "mode"     "DF")
2752    (set_attr "cnv_mode" "D2I")
2753    (set_attr "length"   "4")])
2755 (define_insn "fix_truncdfsi2_macro"
2756   [(set (match_operand:SI 0 "register_operand" "=f")
2757         (fix:SI (match_operand:DF 1 "register_operand" "f")))
2758    (clobber (match_scratch:DF 2 "=d"))]
2759   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
2761   if (set_nomacro)
2762     return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
2763   else
2764     return "trunc.w.d %0,%1,%2";
2766   [(set_attr "type"     "fcvt")
2767    (set_attr "mode"     "DF")
2768    (set_attr "cnv_mode" "D2I")
2769    (set_attr "length"   "36")])
2771 (define_expand "fix_truncsfsi2"
2772   [(set (match_operand:SI 0 "register_operand")
2773         (fix:SI (match_operand:SF 1 "register_operand")))]
2774   "TARGET_HARD_FLOAT"
2776   if (!ISA_HAS_TRUNC_W)
2777     {
2778       emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
2779       DONE;
2780     }
2783 (define_insn "fix_truncsfsi2_insn"
2784   [(set (match_operand:SI 0 "register_operand" "=f")
2785         (fix:SI (match_operand:SF 1 "register_operand" "f")))]
2786   "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
2787   "trunc.w.s %0,%1"
2788   [(set_attr "type"     "fcvt")
2789    (set_attr "mode"     "SF")
2790    (set_attr "cnv_mode" "S2I")
2791    (set_attr "length"   "4")])
2793 (define_insn "fix_truncsfsi2_macro"
2794   [(set (match_operand:SI 0 "register_operand" "=f")
2795         (fix:SI (match_operand:SF 1 "register_operand" "f")))
2796    (clobber (match_scratch:SF 2 "=d"))]
2797   "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
2799   if (set_nomacro)
2800     return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
2801   else
2802     return "trunc.w.s %0,%1,%2";
2804   [(set_attr "type"     "fcvt")
2805    (set_attr "mode"     "SF")
2806    (set_attr "cnv_mode" "S2I")
2807    (set_attr "length"   "36")])
2810 (define_insn "fix_truncdfdi2"
2811   [(set (match_operand:DI 0 "register_operand" "=f")
2812         (fix:DI (match_operand:DF 1 "register_operand" "f")))]
2813   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2814   "trunc.l.d %0,%1"
2815   [(set_attr "type"     "fcvt")
2816    (set_attr "mode"     "DF")
2817    (set_attr "cnv_mode" "D2I")
2818    (set_attr "length"   "4")])
2821 (define_insn "fix_truncsfdi2"
2822   [(set (match_operand:DI 0 "register_operand" "=f")
2823         (fix:DI (match_operand:SF 1 "register_operand" "f")))]
2824   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2825   "trunc.l.s %0,%1"
2826   [(set_attr "type"     "fcvt")
2827    (set_attr "mode"     "SF")
2828    (set_attr "cnv_mode" "S2I")
2829    (set_attr "length"   "4")])
2832 (define_insn "floatsidf2"
2833   [(set (match_operand:DF 0 "register_operand" "=f")
2834         (float:DF (match_operand:SI 1 "register_operand" "f")))]
2835   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2836   "cvt.d.w\t%0,%1"
2837   [(set_attr "type"     "fcvt")
2838    (set_attr "mode"     "DF")
2839    (set_attr "cnv_mode" "I2D")   
2840    (set_attr "length"   "4")])
2843 (define_insn "floatdidf2"
2844   [(set (match_operand:DF 0 "register_operand" "=f")
2845         (float:DF (match_operand:DI 1 "register_operand" "f")))]
2846   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2847   "cvt.d.l\t%0,%1"
2848   [(set_attr "type"     "fcvt")
2849    (set_attr "mode"     "DF")
2850    (set_attr "cnv_mode" "I2D")   
2851    (set_attr "length"   "4")])
2854 (define_insn "floatsisf2"
2855   [(set (match_operand:SF 0 "register_operand" "=f")
2856         (float:SF (match_operand:SI 1 "register_operand" "f")))]
2857   "TARGET_HARD_FLOAT"
2858   "cvt.s.w\t%0,%1"
2859   [(set_attr "type"     "fcvt")
2860    (set_attr "mode"     "SF")
2861    (set_attr "cnv_mode" "I2S")   
2862    (set_attr "length"   "4")])
2865 (define_insn "floatdisf2"
2866   [(set (match_operand:SF 0 "register_operand" "=f")
2867         (float:SF (match_operand:DI 1 "register_operand" "f")))]
2868   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2869   "cvt.s.l\t%0,%1"
2870   [(set_attr "type"     "fcvt")
2871    (set_attr "mode"     "SF")
2872    (set_attr "cnv_mode" "I2S")   
2873    (set_attr "length"   "4")])
2876 (define_expand "fixuns_truncdfsi2"
2877   [(set (match_operand:SI 0 "register_operand")
2878         (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
2879   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2881   rtx reg1 = gen_reg_rtx (DFmode);
2882   rtx reg2 = gen_reg_rtx (DFmode);
2883   rtx reg3 = gen_reg_rtx (SImode);
2884   rtx label1 = gen_label_rtx ();
2885   rtx label2 = gen_label_rtx ();
2886   REAL_VALUE_TYPE offset;
2888   real_2expN (&offset, 31, DFmode);
2890   if (reg1)                     /* Turn off complaints about unreached code.  */
2891     {
2892       mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2893       do_pending_stack_adjust ();
2895       emit_insn (gen_cmpdf (operands[1], reg1));
2896       emit_jump_insn (gen_bge (label1));
2898       emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
2899       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2900                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
2901       emit_barrier ();
2903       emit_label (label1);
2904       mips_emit_move (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
2905       mips_emit_move (reg3, GEN_INT (trunc_int_for_mode
2906                                      (BITMASK_HIGH, SImode)));
2908       emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
2909       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2911       emit_label (label2);
2913       /* Allow REG_NOTES to be set on last insn (labels don't have enough
2914          fields, and can't be used for REG_NOTES anyway).  */
2915       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2916       DONE;
2917     }
2921 (define_expand "fixuns_truncdfdi2"
2922   [(set (match_operand:DI 0 "register_operand")
2923         (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
2924   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2926   rtx reg1 = gen_reg_rtx (DFmode);
2927   rtx reg2 = gen_reg_rtx (DFmode);
2928   rtx reg3 = gen_reg_rtx (DImode);
2929   rtx label1 = gen_label_rtx ();
2930   rtx label2 = gen_label_rtx ();
2931   REAL_VALUE_TYPE offset;
2933   real_2expN (&offset, 63, DFmode);
2935   mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2936   do_pending_stack_adjust ();
2938   emit_insn (gen_cmpdf (operands[1], reg1));
2939   emit_jump_insn (gen_bge (label1));
2941   emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
2942   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2943                                gen_rtx_LABEL_REF (VOIDmode, label2)));
2944   emit_barrier ();
2946   emit_label (label1);
2947   mips_emit_move (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
2948   mips_emit_move (reg3, GEN_INT (BITMASK_HIGH));
2949   emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
2951   emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
2952   emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
2954   emit_label (label2);
2956   /* Allow REG_NOTES to be set on last insn (labels don't have enough
2957      fields, and can't be used for REG_NOTES anyway).  */
2958   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2959   DONE;
2963 (define_expand "fixuns_truncsfsi2"
2964   [(set (match_operand:SI 0 "register_operand")
2965         (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
2966   "TARGET_HARD_FLOAT"
2968   rtx reg1 = gen_reg_rtx (SFmode);
2969   rtx reg2 = gen_reg_rtx (SFmode);
2970   rtx reg3 = gen_reg_rtx (SImode);
2971   rtx label1 = gen_label_rtx ();
2972   rtx label2 = gen_label_rtx ();
2973   REAL_VALUE_TYPE offset;
2975   real_2expN (&offset, 31, SFmode);
2977   mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
2978   do_pending_stack_adjust ();
2980   emit_insn (gen_cmpsf (operands[1], reg1));
2981   emit_jump_insn (gen_bge (label1));
2983   emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
2984   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2985                                gen_rtx_LABEL_REF (VOIDmode, label2)));
2986   emit_barrier ();
2988   emit_label (label1);
2989   mips_emit_move (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
2990   mips_emit_move (reg3, GEN_INT (trunc_int_for_mode
2991                                  (BITMASK_HIGH, SImode)));
2993   emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
2994   emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2996   emit_label (label2);
2998   /* Allow REG_NOTES to be set on last insn (labels don't have enough
2999      fields, and can't be used for REG_NOTES anyway).  */
3000   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3001   DONE;
3005 (define_expand "fixuns_truncsfdi2"
3006   [(set (match_operand:DI 0 "register_operand")
3007         (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
3008   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3010   rtx reg1 = gen_reg_rtx (SFmode);
3011   rtx reg2 = gen_reg_rtx (SFmode);
3012   rtx reg3 = gen_reg_rtx (DImode);
3013   rtx label1 = gen_label_rtx ();
3014   rtx label2 = gen_label_rtx ();
3015   REAL_VALUE_TYPE offset;
3017   real_2expN (&offset, 63, SFmode);
3019   mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3020   do_pending_stack_adjust ();
3022   emit_insn (gen_cmpsf (operands[1], reg1));
3023   emit_jump_insn (gen_bge (label1));
3025   emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
3026   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3027                                gen_rtx_LABEL_REF (VOIDmode, label2)));
3028   emit_barrier ();
3030   emit_label (label1);
3031   mips_emit_move (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3032   mips_emit_move (reg3, GEN_INT (BITMASK_HIGH));
3033   emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3035   emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
3036   emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3038   emit_label (label2);
3040   /* Allow REG_NOTES to be set on last insn (labels don't have enough
3041      fields, and can't be used for REG_NOTES anyway).  */
3042   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3043   DONE;
3047 ;;  ....................
3049 ;;      DATA MOVEMENT
3051 ;;  ....................
3053 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
3055 (define_expand "extv"
3056   [(set (match_operand 0 "register_operand")
3057         (sign_extract (match_operand:QI 1 "memory_operand")
3058                       (match_operand 2 "immediate_operand")
3059                       (match_operand 3 "immediate_operand")))]
3060   "!TARGET_MIPS16"
3062   if (mips_expand_ext_as_unaligned_load (operands[0], operands[1],
3063                                          INTVAL (operands[2]),
3064                                          INTVAL (operands[3])))
3065     DONE;
3066   else
3067     FAIL;
3070 (define_expand "extzv"
3071   [(set (match_operand 0 "register_operand")
3072         (zero_extract (match_operand 1 "nonimmediate_operand")
3073                       (match_operand 2 "immediate_operand")
3074                       (match_operand 3 "immediate_operand")))]
3075   "!TARGET_MIPS16"
3077   if (mips_expand_ext_as_unaligned_load (operands[0], operands[1],
3078                                          INTVAL (operands[2]),
3079                                          INTVAL (operands[3])))
3080     DONE;
3081   else if (mips_use_ins_ext_p (operands[1], INTVAL (operands[2]),
3082                                INTVAL (operands[3])))
3083     {
3084       if (GET_MODE (operands[0]) == DImode)
3085         emit_insn (gen_extzvdi (operands[0], operands[1], operands[2],
3086                                 operands[3]));
3087       else
3088         emit_insn (gen_extzvsi (operands[0], operands[1], operands[2],
3089                                 operands[3]));
3090       DONE;
3091     }
3092   else
3093     FAIL;
3096 (define_insn "extzv<mode>"
3097   [(set (match_operand:GPR 0 "register_operand" "=d")
3098         (zero_extract:GPR (match_operand:GPR 1 "register_operand" "d")
3099                           (match_operand:SI 2 "immediate_operand" "I")
3100                           (match_operand:SI 3 "immediate_operand" "I")))]
3101   "mips_use_ins_ext_p (operands[1], INTVAL (operands[2]),
3102                        INTVAL (operands[3]))"
3103   "<d>ext\t%0,%1,%3,%2"
3104   [(set_attr "type"     "arith")
3105    (set_attr "mode"     "<MODE>")])
3108 (define_expand "insv"
3109   [(set (zero_extract (match_operand 0 "nonimmediate_operand")
3110                       (match_operand 1 "immediate_operand")
3111                       (match_operand 2 "immediate_operand"))
3112         (match_operand 3 "reg_or_0_operand"))]
3113   "!TARGET_MIPS16"
3115   if (mips_expand_ins_as_unaligned_store (operands[0], operands[3],
3116                                           INTVAL (operands[1]),
3117                                           INTVAL (operands[2])))
3118     DONE;
3119   else if (mips_use_ins_ext_p (operands[0], INTVAL (operands[1]),
3120                                INTVAL (operands[2])))
3121     {
3122       if (GET_MODE (operands[0]) == DImode)
3123         emit_insn (gen_insvdi (operands[0], operands[1], operands[2],
3124                                operands[3]));
3125       else
3126         emit_insn (gen_insvsi (operands[0], operands[1], operands[2],
3127                                operands[3]));
3128       DONE;
3129    }
3130    else
3131      FAIL;
3134 (define_insn "insv<mode>"
3135   [(set (zero_extract:GPR (match_operand:GPR 0 "register_operand" "+d")
3136                           (match_operand:SI 1 "immediate_operand" "I")
3137                           (match_operand:SI 2 "immediate_operand" "I"))
3138         (match_operand:GPR 3 "reg_or_0_operand" "dJ"))]
3139   "mips_use_ins_ext_p (operands[0], INTVAL (operands[1]),
3140                        INTVAL (operands[2]))"
3141   "<d>ins\t%0,%z3,%2,%1"
3142   [(set_attr "type"     "arith")
3143    (set_attr "mode"     "<MODE>")])
3145 ;; Unaligned word moves generated by the bit field patterns.
3147 ;; As far as the rtl is concerned, both the left-part and right-part
3148 ;; instructions can access the whole field.  However, the real operand
3149 ;; refers to just the first or the last byte (depending on endianness).
3150 ;; We therefore use two memory operands to each instruction, one to
3151 ;; describe the rtl effect and one to use in the assembly output.
3153 ;; Operands 0 and 1 are the rtl-level target and source respectively.
3154 ;; This allows us to use the standard length calculations for the "load"
3155 ;; and "store" type attributes.
3157 (define_insn "mov_<load>l"
3158   [(set (match_operand:GPR 0 "register_operand" "=d")
3159         (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
3160                      (match_operand:QI 2 "memory_operand" "m")]
3161                     UNSPEC_LOAD_LEFT))]
3162   "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
3163   "<load>l\t%0,%2"
3164   [(set_attr "type" "load")
3165    (set_attr "mode" "<MODE>")])
3167 (define_insn "mov_<load>r"
3168   [(set (match_operand:GPR 0 "register_operand" "=d")
3169         (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
3170                      (match_operand:QI 2 "memory_operand" "m")
3171                      (match_operand:GPR 3 "register_operand" "0")]
3172                     UNSPEC_LOAD_RIGHT))]
3173   "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
3174   "<load>r\t%0,%2"
3175   [(set_attr "type" "load")
3176    (set_attr "mode" "<MODE>")])
3178 (define_insn "mov_<store>l"
3179   [(set (match_operand:BLK 0 "memory_operand" "=m")
3180         (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3181                      (match_operand:QI 2 "memory_operand" "m")]
3182                     UNSPEC_STORE_LEFT))]
3183   "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
3184   "<store>l\t%z1,%2"
3185   [(set_attr "type" "store")
3186    (set_attr "mode" "<MODE>")])
3188 (define_insn "mov_<store>r"
3189   [(set (match_operand:BLK 0 "memory_operand" "+m")
3190         (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3191                      (match_operand:QI 2 "memory_operand" "m")
3192                      (match_dup 0)]
3193                     UNSPEC_STORE_RIGHT))]
3194   "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
3195   "<store>r\t%z1,%2"
3196   [(set_attr "type" "store")
3197    (set_attr "mode" "<MODE>")])
3199 ;; An instruction to calculate the high part of a 64-bit SYMBOL_ABSOLUTE.
3200 ;; The required value is:
3202 ;;      (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
3204 ;; which translates to:
3206 ;;      lui     op0,%highest(op1)
3207 ;;      daddiu  op0,op0,%higher(op1)
3208 ;;      dsll    op0,op0,16
3209 ;;      daddiu  op0,op0,%hi(op1)
3210 ;;      dsll    op0,op0,16
3212 ;; The split is deferred until after flow2 to allow the peephole2 below
3213 ;; to take effect.
3214 (define_insn_and_split "*lea_high64"
3215   [(set (match_operand:DI 0 "register_operand" "=d")
3216         (high:DI (match_operand:DI 1 "absolute_symbolic_operand" "")))]
3217   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3218   "#"
3219   "&& epilogue_completed"
3220   [(set (match_dup 0) (high:DI (match_dup 2)))
3221    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
3222    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
3223    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3224    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
3226   operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3227   operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
3229   [(set_attr "length" "20")])
3231 ;; Use a scratch register to reduce the latency of the above pattern
3232 ;; on superscalar machines.  The optimized sequence is:
3234 ;;      lui     op1,%highest(op2)
3235 ;;      lui     op0,%hi(op2)
3236 ;;      daddiu  op1,op1,%higher(op2)
3237 ;;      dsll32  op1,op1,0
3238 ;;      daddu   op1,op1,op0
3239 (define_peephole2
3240   [(set (match_operand:DI 1 "register_operand")
3241         (high:DI (match_operand:DI 2 "absolute_symbolic_operand")))
3242    (match_scratch:DI 0 "d")]
3243   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3244   [(set (match_dup 1) (high:DI (match_dup 3)))
3245    (set (match_dup 0) (high:DI (match_dup 4)))
3246    (set (match_dup 1) (lo_sum:DI (match_dup 1) (match_dup 3)))
3247    (set (match_dup 1) (ashift:DI (match_dup 1) (const_int 32)))
3248    (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 0)))]
3250   operands[3] = mips_unspec_address (operands[2], SYMBOL_64_HIGH);
3251   operands[4] = mips_unspec_address (operands[2], SYMBOL_64_LOW);
3254 ;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
3255 ;; SYMBOL_ABSOLUTE X will take 6 cycles.  This next pattern allows combine
3256 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
3257 ;; used once.  We can then use the sequence:
3259 ;;      lui     op0,%highest(op1)
3260 ;;      lui     op2,%hi(op1)
3261 ;;      daddiu  op0,op0,%higher(op1)
3262 ;;      daddiu  op2,op2,%lo(op1)
3263 ;;      dsll32  op0,op0,0
3264 ;;      daddu   op0,op0,op2
3266 ;; which takes 4 cycles on most superscalar targets.
3267 (define_insn_and_split "*lea64"
3268   [(set (match_operand:DI 0 "register_operand" "=d")
3269         (match_operand:DI 1 "absolute_symbolic_operand" ""))
3270    (clobber (match_scratch:DI 2 "=&d"))]
3271   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
3272   "#"
3273   "&& reload_completed"
3274   [(set (match_dup 0) (high:DI (match_dup 3)))
3275    (set (match_dup 2) (high:DI (match_dup 4)))
3276    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3277    (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
3278    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
3279    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
3281   operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3282   operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
3284   [(set_attr "length" "24")])
3286 ;; Split HIGHs into:
3288 ;;      li op0,%hi(sym)
3289 ;;      sll op0,16
3291 ;; on MIPS16 targets.
3292 (define_split
3293   [(set (match_operand:SI 0 "register_operand" "=d")
3294         (high:SI (match_operand:SI 1 "absolute_symbolic_operand" "")))]
3295   "TARGET_MIPS16 && reload_completed"
3296   [(set (match_dup 0) (match_dup 2))
3297    (set (match_dup 0) (ashift:SI (match_dup 0) (const_int 16)))]
3299   operands[2] = mips_unspec_address (operands[1], SYMBOL_32_HIGH);
3302 ;; Insns to fetch a symbol from a big GOT.
3304 (define_insn_and_split "*xgot_hi<mode>"
3305   [(set (match_operand:P 0 "register_operand" "=d")
3306         (high:P (match_operand:P 1 "got_disp_operand" "")))]
3307   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3308   "#"
3309   "&& reload_completed"
3310   [(set (match_dup 0) (high:P (match_dup 2)))
3311    (set (match_dup 0) (plus:P (match_dup 0) (match_dup 3)))]
3313   operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_DISP);
3314   operands[3] = pic_offset_table_rtx;
3316   [(set_attr "got" "xgot_high")
3317    (set_attr "mode" "<MODE>")])
3319 (define_insn_and_split "*xgot_lo<mode>"
3320   [(set (match_operand:P 0 "register_operand" "=d")
3321         (lo_sum:P (match_operand:P 1 "register_operand" "d")
3322                   (match_operand:P 2 "got_disp_operand" "")))]
3323   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3324   "#"
3325   "&& reload_completed"
3326   [(set (match_dup 0)
3327         (unspec:P [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3328   { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_DISP); }
3329   [(set_attr "got" "load")
3330    (set_attr "mode" "<MODE>")])
3332 ;; Insns to fetch a symbol from a normal GOT.
3334 (define_insn_and_split "*got_disp<mode>"
3335   [(set (match_operand:P 0 "register_operand" "=d")
3336         (match_operand:P 1 "got_disp_operand" ""))]
3337   "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3338   "#"
3339   "&& reload_completed"
3340   [(set (match_dup 0)
3341         (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3343   operands[2] = pic_offset_table_rtx;
3344   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_DISP);
3346   [(set_attr "got" "load")
3347    (set_attr "mode" "<MODE>")])
3349 ;; Insns for loading the "page" part of a page/ofst address from the GOT.
3351 (define_insn_and_split "*got_page<mode>"
3352   [(set (match_operand:P 0 "register_operand" "=d")
3353         (high:P (match_operand:P 1 "got_page_ofst_operand" "")))]
3354   "TARGET_EXPLICIT_RELOCS"
3355   "#"
3356   "&& reload_completed"
3357   [(set (match_dup 0)
3358         (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3360   operands[2] = pic_offset_table_rtx;
3361   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3363   [(set_attr "got" "load")
3364    (set_attr "mode" "<MODE>")])
3366 ;; Lower-level instructions for loading an address from the GOT.
3367 ;; We could use MEMs, but an unspec gives more optimization
3368 ;; opportunities.
3370 (define_insn "load_got<mode>"
3371   [(set (match_operand:P 0 "register_operand" "=d")
3372         (unspec:P [(match_operand:P 1 "register_operand" "d")
3373                    (match_operand:P 2 "immediate_operand" "")]
3374                   UNSPEC_LOAD_GOT))]
3375   ""
3376   "<load>\t%0,%R2(%1)"
3377   [(set_attr "type" "load")
3378    (set_attr "mode" "<MODE>")
3379    (set_attr "length" "4")])
3381 ;; Instructions for adding the low 16 bits of an address to a register.
3382 ;; Operand 2 is the address: mips_print_operand works out which relocation
3383 ;; should be applied.
3385 (define_insn "*low<mode>"
3386   [(set (match_operand:P 0 "register_operand" "=d")
3387         (lo_sum:P (match_operand:P 1 "register_operand" "d")
3388                   (match_operand:P 2 "immediate_operand" "")))]
3389   "!TARGET_MIPS16"
3390   "<d>addiu\t%0,%1,%R2"
3391   [(set_attr "type" "arith")
3392    (set_attr "mode" "<MODE>")])
3394 (define_insn "*low<mode>_mips16"
3395   [(set (match_operand:P 0 "register_operand" "=d")
3396         (lo_sum:P (match_operand:P 1 "register_operand" "0")
3397                   (match_operand:P 2 "immediate_operand" "")))]
3398   "TARGET_MIPS16"
3399   "<d>addiu\t%0,%R2"
3400   [(set_attr "type" "arith")
3401    (set_attr "mode" "<MODE>")
3402    (set_attr "length" "8")])
3404 ;; Allow combine to split complex const_int load sequences, using operand 2
3405 ;; to store the intermediate results.  See move_operand for details.
3406 (define_split
3407   [(set (match_operand:GPR 0 "register_operand")
3408         (match_operand:GPR 1 "splittable_const_int_operand"))
3409    (clobber (match_operand:GPR 2 "register_operand"))]
3410   ""
3411   [(const_int 0)]
3413   mips_move_integer (operands[2], operands[0], INTVAL (operands[1]));
3414   DONE;
3417 ;; Likewise, for symbolic operands.
3418 (define_split
3419   [(set (match_operand:P 0 "register_operand")
3420         (match_operand:P 1))
3421    (clobber (match_operand:P 2 "register_operand"))]
3422   "mips_split_symbol (operands[2], operands[1], MAX_MACHINE_MODE, NULL)"
3423   [(set (match_dup 0) (match_dup 3))]
3425   mips_split_symbol (operands[2], operands[1],
3426                      MAX_MACHINE_MODE, &operands[3]);
3429 ;; 64-bit integer moves
3431 ;; Unlike most other insns, the move insns can't be split with
3432 ;; different predicates, because register spilling and other parts of
3433 ;; the compiler, have memoized the insn number already.
3435 (define_expand "movdi"
3436   [(set (match_operand:DI 0 "")
3437         (match_operand:DI 1 ""))]
3438   ""
3440   if (mips_legitimize_move (DImode, operands[0], operands[1]))
3441     DONE;
3444 ;; For mips16, we need a special case to handle storing $31 into
3445 ;; memory, since we don't have a constraint to match $31.  This
3446 ;; instruction can be generated by save_restore_insns.
3448 (define_insn "*mov<mode>_ra"
3449   [(set (match_operand:GPR 0 "stack_operand" "=m")
3450         (reg:GPR 31))]
3451   "TARGET_MIPS16"
3452   "<store>\t$31,%0"
3453   [(set_attr "type" "store")
3454    (set_attr "mode" "<MODE>")])
3456 (define_insn "*movdi_32bit"
3457   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*a,*d,*B*C*D,*B*C*D,*d,*m")
3458         (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*a,*d,*m,*B*C*D,*B*C*D"))]
3459   "!TARGET_64BIT && !TARGET_FLOAT64 && !TARGET_MIPS16
3460    && (register_operand (operands[0], DImode)
3461        || reg_or_0_operand (operands[1], DImode))"
3462   { return mips_output_move (operands[0], operands[1]); }
3463   [(set_attr "type"     "multi,multi,load,store,mthilo,mfhilo,mtc,load,mfc,store")
3464    (set_attr "mode"     "DI")
3465    (set_attr "length"   "8,16,*,*,8,8,8,*,8,*")])
3467 (define_insn "*movdi_gp32_fp64"
3468   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*a,*d,*f,*f,*d,*m")
3469         (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*a,*J*d,*m,*f,*f"))]
3470   "!TARGET_64BIT && TARGET_FLOAT64 && !TARGET_MIPS16
3471    && (register_operand (operands[0], DImode)
3472        || reg_or_0_operand (operands[1], DImode))"
3473   { return mips_output_move (operands[0], operands[1]); }
3474   [(set_attr "type"     "multi,multi,load,store,mthilo,mfhilo,mtc,fpload,mfc,fpstore")
3475    (set_attr "mode"     "DI")
3476    (set_attr "length"   "8,16,*,*,8,8,8,*,8,*")])
3478 (define_insn "*movdi_32bit_mips16"
3479   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
3480         (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
3481   "!TARGET_64BIT && TARGET_MIPS16
3482    && (register_operand (operands[0], DImode)
3483        || register_operand (operands[1], DImode))"
3484   { return mips_output_move (operands[0], operands[1]); }
3485   [(set_attr "type"     "multi,multi,multi,multi,multi,load,store,mfhilo")
3486    (set_attr "mode"     "DI")
3487    (set_attr "length"   "8,8,8,8,12,*,*,8")])
3489 (define_insn "*movdi_64bit"
3490   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*d,*m,*x,*B*C*D,*B*C*D,*d,*m")
3491         (match_operand:DI 1 "move_operand" "d,U,T,m,dJ,*d*J,*m,*f,*f,*J*d,*d,*m,*B*C*D,*B*C*D"))]
3492   "TARGET_64BIT && !TARGET_MIPS16
3493    && (register_operand (operands[0], DImode)
3494        || reg_or_0_operand (operands[1], DImode))"
3495   { return mips_output_move (operands[0], operands[1]); }
3496   [(set_attr "type"     "move,const,const,load,store,mtc,fpload,mfc,fpstore,mthilo,mtc,load,mfc,store")
3497    (set_attr "mode"     "DI")
3498    (set_attr "length"   "4,*,*,*,*,4,*,4,*,4,8,*,8,*")])
3500 (define_insn "*movdi_64bit_mips16"
3501   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,m")
3502         (match_operand:DI 1 "move_operand" "d,d,y,K,N,kf,U,m,d"))]
3503   "TARGET_64BIT && TARGET_MIPS16
3504    && (register_operand (operands[0], DImode)
3505        || register_operand (operands[1], DImode))"
3506   { return mips_output_move (operands[0], operands[1]); }
3507   [(set_attr "type"     "move,move,move,arith,arith,load,const,load,store")
3508    (set_attr "mode"     "DI")
3509    (set_attr_alternative "length"
3510                 [(const_int 4)
3511                  (const_int 4)
3512                  (const_int 4)
3513                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3514                                (const_int 4)
3515                                (const_int 8))
3516                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3517                                (const_int 8)
3518                                (const_int 12))
3519                  (const_int 8)
3520                  (const_string "*")
3521                  (const_string "*")
3522                  (const_string "*")])])
3525 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
3526 ;; when the original load is a 4 byte instruction but the add and the
3527 ;; load are 2 2 byte instructions.
3529 (define_split
3530   [(set (match_operand:DI 0 "register_operand")
3531         (mem:DI (plus:DI (match_dup 0)
3532                          (match_operand:DI 1 "const_int_operand"))))]
3533   "TARGET_64BIT && TARGET_MIPS16 && reload_completed
3534    && !TARGET_DEBUG_D_MODE
3535    && REG_P (operands[0])
3536    && M16_REG_P (REGNO (operands[0]))
3537    && GET_CODE (operands[1]) == CONST_INT
3538    && ((INTVAL (operands[1]) < 0
3539         && INTVAL (operands[1]) >= -0x10)
3540        || (INTVAL (operands[1]) >= 32 * 8
3541            && INTVAL (operands[1]) <= 31 * 8 + 0x8)
3542        || (INTVAL (operands[1]) >= 0
3543            && INTVAL (operands[1]) < 32 * 8
3544            && (INTVAL (operands[1]) & 7) != 0))"
3545   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
3546    (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
3548   HOST_WIDE_INT val = INTVAL (operands[1]);
3550   if (val < 0)
3551     operands[2] = const0_rtx;
3552   else if (val >= 32 * 8)
3553     {
3554       int off = val & 7;
3556       operands[1] = GEN_INT (0x8 + off);
3557       operands[2] = GEN_INT (val - off - 0x8);
3558     }
3559   else
3560     {
3561       int off = val & 7;
3563       operands[1] = GEN_INT (off);
3564       operands[2] = GEN_INT (val - off);
3565     }
3568 ;; 32-bit Integer moves
3570 ;; Unlike most other insns, the move insns can't be split with
3571 ;; different predicates, because register spilling and other parts of
3572 ;; the compiler, have memoized the insn number already.
3574 (define_expand "movsi"
3575   [(set (match_operand:SI 0 "")
3576         (match_operand:SI 1 ""))]
3577   ""
3579   if (mips_legitimize_move (SImode, operands[0], operands[1]))
3580     DONE;
3583 ;; The difference between these two is whether or not ints are allowed
3584 ;; in FP registers (off by default, use -mdebugh to enable).
3586 (define_insn "*movsi_internal"
3587   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*d,*m,*d,*z,*a,*d,*B*C*D,*B*C*D,*d,*m")
3588         (match_operand:SI 1 "move_operand" "d,U,T,m,dJ,*d*J,*m,*f,*f,*z,*d,*J*d,*A,*d,*m,*B*C*D,*B*C*D"))]
3589   "!TARGET_MIPS16
3590    && (register_operand (operands[0], SImode)
3591        || reg_or_0_operand (operands[1], SImode))"
3592   { return mips_output_move (operands[0], operands[1]); }
3593   [(set_attr "type"     "move,const,const,load,store,mtc,fpload,mfc,fpstore,mfc,mtc,mthilo,mfhilo,mtc,load,mfc,store")
3594    (set_attr "mode"     "SI")
3595    (set_attr "length"   "4,*,*,*,*,4,*,4,*,4,4,4,4,4,*,4,*")])
3597 (define_insn "*movsi_mips16"
3598   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,m")
3599         (match_operand:SI 1 "move_operand" "d,d,y,K,N,kf,U,m,d"))]
3600   "TARGET_MIPS16
3601    && (register_operand (operands[0], SImode)
3602        || register_operand (operands[1], SImode))"
3603   { return mips_output_move (operands[0], operands[1]); }
3604   [(set_attr "type"     "move,move,move,arith,arith,load,const,load,store")
3605    (set_attr "mode"     "SI")
3606    (set_attr_alternative "length"
3607                 [(const_int 4)
3608                  (const_int 4)
3609                  (const_int 4)
3610                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3611                                (const_int 4)
3612                                (const_int 8))
3613                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3614                                (const_int 8)
3615                                (const_int 12))
3616                  (const_int 8)
3617                  (const_string "*")
3618                  (const_string "*")
3619                  (const_string "*")])])
3621 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
3622 ;; when the original load is a 4 byte instruction but the add and the
3623 ;; load are 2 2 byte instructions.
3625 (define_split
3626   [(set (match_operand:SI 0 "register_operand")
3627         (mem:SI (plus:SI (match_dup 0)
3628                          (match_operand:SI 1 "const_int_operand"))))]
3629   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3630    && REG_P (operands[0])
3631    && M16_REG_P (REGNO (operands[0]))
3632    && GET_CODE (operands[1]) == CONST_INT
3633    && ((INTVAL (operands[1]) < 0
3634         && INTVAL (operands[1]) >= -0x80)
3635        || (INTVAL (operands[1]) >= 32 * 4
3636            && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
3637        || (INTVAL (operands[1]) >= 0
3638            && INTVAL (operands[1]) < 32 * 4
3639            && (INTVAL (operands[1]) & 3) != 0))"
3640   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3641    (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
3643   HOST_WIDE_INT val = INTVAL (operands[1]);
3645   if (val < 0)
3646     operands[2] = const0_rtx;
3647   else if (val >= 32 * 4)
3648     {
3649       int off = val & 3;
3651       operands[1] = GEN_INT (0x7c + off);
3652       operands[2] = GEN_INT (val - off - 0x7c);
3653     }
3654   else
3655     {
3656       int off = val & 3;
3658       operands[1] = GEN_INT (off);
3659       operands[2] = GEN_INT (val - off);
3660     }
3663 ;; On the mips16, we can split a load of certain constants into a load
3664 ;; and an add.  This turns a 4 byte instruction into 2 2 byte
3665 ;; instructions.
3667 (define_split
3668   [(set (match_operand:SI 0 "register_operand")
3669         (match_operand:SI 1 "const_int_operand"))]
3670   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3671    && REG_P (operands[0])
3672    && M16_REG_P (REGNO (operands[0]))
3673    && GET_CODE (operands[1]) == CONST_INT
3674    && INTVAL (operands[1]) >= 0x100
3675    && INTVAL (operands[1]) <= 0xff + 0x7f"
3676   [(set (match_dup 0) (match_dup 1))
3677    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
3679   int val = INTVAL (operands[1]);
3681   operands[1] = GEN_INT (0xff);
3682   operands[2] = GEN_INT (val - 0xff);
3685 ;; This insn handles moving CCmode values.  It's really just a
3686 ;; slightly simplified copy of movsi_internal2, with additional cases
3687 ;; to move a condition register to a general register and to move
3688 ;; between the general registers and the floating point registers.
3690 (define_insn "movcc"
3691   [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m")
3692         (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))]
3693   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3694   { return mips_output_move (operands[0], operands[1]); }
3695   [(set_attr "type"     "multi,move,load,store,mfc,mtc,fmove,fpload,fpstore")
3696    (set_attr "mode"     "SI")
3697    (set_attr "length"   "8,4,*,*,4,4,4,*,*")])
3699 ;; Reload condition code registers.  reload_incc and reload_outcc
3700 ;; both handle moves from arbitrary operands into condition code
3701 ;; registers.  reload_incc handles the more common case in which
3702 ;; a source operand is constrained to be in a condition-code
3703 ;; register, but has not been allocated to one.
3705 ;; Sometimes, such as in movcc, we have a CCmode destination whose
3706 ;; constraints do not include 'z'.  reload_outcc handles the case
3707 ;; when such an operand is allocated to a condition-code register.
3709 ;; Note that reloads from a condition code register to some
3710 ;; other location can be done using ordinary moves.  Moving
3711 ;; into a GPR takes a single movcc, moving elsewhere takes
3712 ;; two.  We can leave these cases to the generic reload code.
3713 (define_expand "reload_incc"
3714   [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
3715         (match_operand:CC 1 "general_operand" ""))
3716    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3717   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3719   mips_expand_fcc_reload (operands[0], operands[1], operands[2]);
3720   DONE;
3723 (define_expand "reload_outcc"
3724   [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
3725         (match_operand:CC 1 "register_operand" ""))
3726    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3727   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3729   mips_expand_fcc_reload (operands[0], operands[1], operands[2]);
3730   DONE;
3733 ;; MIPS4 supports loading and storing a floating point register from
3734 ;; the sum of two general registers.  We use two versions for each of
3735 ;; these four instructions: one where the two general registers are
3736 ;; SImode, and one where they are DImode.  This is because general
3737 ;; registers will be in SImode when they hold 32-bit values, but,
3738 ;; since the 32-bit values are always sign extended, the [ls][wd]xc1
3739 ;; instructions will still work correctly.
3741 ;; ??? Perhaps it would be better to support these instructions by
3742 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends.  However, since
3743 ;; these instructions can only be used to load and store floating
3744 ;; point registers, that would probably cause trouble in reload.
3746 (define_insn "*<ANYF:loadx>_<P:mode>"
3747   [(set (match_operand:ANYF 0 "register_operand" "=f")
3748         (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d")
3749                           (match_operand:P 2 "register_operand" "d"))))]
3750   "ISA_HAS_FP4"
3751   "<ANYF:loadx>\t%0,%1(%2)"
3752   [(set_attr "type" "fpidxload")
3753    (set_attr "mode" "<ANYF:UNITMODE>")])
3755 (define_insn "*<ANYF:storex>_<P:mode>"
3756   [(set (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d")
3757                           (match_operand:P 2 "register_operand" "d")))
3758         (match_operand:ANYF 0 "register_operand" "f"))]
3759   "ISA_HAS_FP4"
3760   "<ANYF:storex>\t%0,%1(%2)"
3761   [(set_attr "type" "fpidxstore")
3762    (set_attr "mode" "<ANYF:UNITMODE>")])
3764 ;; Scaled indexed address load.
3765 ;; Per md.texi, we only need to look for a pattern with multiply in the
3766 ;; address expression, not shift.
3768 (define_insn "*lwxs"
3769   [(set (match_operand:SI 0 "register_operand" "=d")
3770         (mem:SI (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
3771                                   (const_int 4))
3772                          (match_operand:SI 2 "register_operand" "d"))))]
3773   "ISA_HAS_LWXS"
3774   "lwxs\t%0,%1(%2)"
3775   [(set_attr "type"     "load")
3776    (set_attr "mode"     "SI")
3777    (set_attr "length"   "4")])
3779 ;; 16-bit Integer moves
3781 ;; Unlike most other insns, the move insns can't be split with
3782 ;; different predicates, because register spilling and other parts of
3783 ;; the compiler, have memoized the insn number already.
3784 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
3786 (define_expand "movhi"
3787   [(set (match_operand:HI 0 "")
3788         (match_operand:HI 1 ""))]
3789   ""
3791   if (mips_legitimize_move (HImode, operands[0], operands[1]))
3792     DONE;
3795 (define_insn "*movhi_internal"
3796   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*x")
3797         (match_operand:HI 1 "move_operand"         "d,I,m,dJ,*d"))]
3798   "!TARGET_MIPS16
3799    && (register_operand (operands[0], HImode)
3800        || reg_or_0_operand (operands[1], HImode))"
3801   "@
3802     move\t%0,%1
3803     li\t%0,%1
3804     lhu\t%0,%1
3805     sh\t%z1,%0
3806     mt%0\t%1"
3807   [(set_attr "type"     "move,arith,load,store,mthilo")
3808    (set_attr "mode"     "HI")
3809    (set_attr "length"   "4,4,*,*,4")])
3811 (define_insn "*movhi_mips16"
3812   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
3813         (match_operand:HI 1 "move_operand"         "d,d,y,K,N,m,d"))]
3814   "TARGET_MIPS16
3815    && (register_operand (operands[0], HImode)
3816        || register_operand (operands[1], HImode))"
3817   "@
3818     move\t%0,%1
3819     move\t%0,%1
3820     move\t%0,%1
3821     li\t%0,%1
3822     #
3823     lhu\t%0,%1
3824     sh\t%1,%0"
3825   [(set_attr "type"     "move,move,move,arith,arith,load,store")
3826    (set_attr "mode"     "HI")
3827    (set_attr_alternative "length"
3828                 [(const_int 4)
3829                  (const_int 4)
3830                  (const_int 4)
3831                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3832                                (const_int 4)
3833                                (const_int 8))
3834                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3835                                (const_int 8)
3836                                (const_int 12))
3837                  (const_string "*")
3838                  (const_string "*")])])
3841 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
3842 ;; when the original load is a 4 byte instruction but the add and the
3843 ;; load are 2 2 byte instructions.
3845 (define_split
3846   [(set (match_operand:HI 0 "register_operand")
3847         (mem:HI (plus:SI (match_dup 0)
3848                          (match_operand:SI 1 "const_int_operand"))))]
3849   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3850    && REG_P (operands[0])
3851    && M16_REG_P (REGNO (operands[0]))
3852    && GET_CODE (operands[1]) == CONST_INT
3853    && ((INTVAL (operands[1]) < 0
3854         && INTVAL (operands[1]) >= -0x80)
3855        || (INTVAL (operands[1]) >= 32 * 2
3856            && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
3857        || (INTVAL (operands[1]) >= 0
3858            && INTVAL (operands[1]) < 32 * 2
3859            && (INTVAL (operands[1]) & 1) != 0))"
3860   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3861    (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
3863   HOST_WIDE_INT val = INTVAL (operands[1]);
3865   if (val < 0)
3866     operands[2] = const0_rtx;
3867   else if (val >= 32 * 2)
3868     {
3869       int off = val & 1;
3871       operands[1] = GEN_INT (0x7e + off);
3872       operands[2] = GEN_INT (val - off - 0x7e);
3873     }
3874   else
3875     {
3876       int off = val & 1;
3878       operands[1] = GEN_INT (off);
3879       operands[2] = GEN_INT (val - off);
3880     }
3883 ;; 8-bit Integer moves
3885 ;; Unlike most other insns, the move insns can't be split with
3886 ;; different predicates, because register spilling and other parts of
3887 ;; the compiler, have memoized the insn number already.
3888 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
3890 (define_expand "movqi"
3891   [(set (match_operand:QI 0 "")
3892         (match_operand:QI 1 ""))]
3893   ""
3895   if (mips_legitimize_move (QImode, operands[0], operands[1]))
3896     DONE;
3899 (define_insn "*movqi_internal"
3900   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*x")
3901         (match_operand:QI 1 "move_operand"         "d,I,m,dJ,*d"))]
3902   "!TARGET_MIPS16
3903    && (register_operand (operands[0], QImode)
3904        || reg_or_0_operand (operands[1], QImode))"
3905   "@
3906     move\t%0,%1
3907     li\t%0,%1
3908     lbu\t%0,%1
3909     sb\t%z1,%0
3910     mt%0\t%1"
3911   [(set_attr "type"     "move,arith,load,store,mthilo")
3912    (set_attr "mode"     "QI")
3913    (set_attr "length"   "4,4,*,*,4")])
3915 (define_insn "*movqi_mips16"
3916   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
3917         (match_operand:QI 1 "move_operand"         "d,d,y,K,N,m,d"))]
3918   "TARGET_MIPS16
3919    && (register_operand (operands[0], QImode)
3920        || register_operand (operands[1], QImode))"
3921   "@
3922     move\t%0,%1
3923     move\t%0,%1
3924     move\t%0,%1
3925     li\t%0,%1
3926     #
3927     lbu\t%0,%1
3928     sb\t%1,%0"
3929   [(set_attr "type"     "move,move,move,arith,arith,load,store")
3930    (set_attr "mode"     "QI")
3931    (set_attr "length"   "4,4,4,4,8,*,*")])
3933 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
3934 ;; when the original load is a 4 byte instruction but the add and the
3935 ;; load are 2 2 byte instructions.
3937 (define_split
3938   [(set (match_operand:QI 0 "register_operand")
3939         (mem:QI (plus:SI (match_dup 0)
3940                          (match_operand:SI 1 "const_int_operand"))))]
3941   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3942    && REG_P (operands[0])
3943    && M16_REG_P (REGNO (operands[0]))
3944    && GET_CODE (operands[1]) == CONST_INT
3945    && ((INTVAL (operands[1]) < 0
3946         && INTVAL (operands[1]) >= -0x80)
3947        || (INTVAL (operands[1]) >= 32
3948            && INTVAL (operands[1]) <= 31 + 0x7f))"
3949   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3950    (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
3952   HOST_WIDE_INT val = INTVAL (operands[1]);
3954   if (val < 0)
3955     operands[2] = const0_rtx;
3956   else
3957     {
3958       operands[1] = GEN_INT (0x7f);
3959       operands[2] = GEN_INT (val - 0x7f);
3960     }
3963 ;; 32-bit floating point moves
3965 (define_expand "movsf"
3966   [(set (match_operand:SF 0 "")
3967         (match_operand:SF 1 ""))]
3968   ""
3970   if (mips_legitimize_move (SFmode, operands[0], operands[1]))
3971     DONE;
3974 (define_insn "*movsf_hardfloat"
3975   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
3976         (match_operand:SF 1 "move_operand" "f,G,m,f,G,*d,*f,*G*d,*m,*d"))]
3977   "TARGET_HARD_FLOAT
3978    && (register_operand (operands[0], SFmode)
3979        || reg_or_0_operand (operands[1], SFmode))"
3980   { return mips_output_move (operands[0], operands[1]); }
3981   [(set_attr "type"     "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
3982    (set_attr "mode"     "SF")
3983    (set_attr "length"   "4,4,*,*,*,4,4,4,*,*")])
3985 (define_insn "*movsf_softfloat"
3986   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
3987         (match_operand:SF 1 "move_operand" "Gd,m,d"))]
3988   "TARGET_SOFT_FLOAT && !TARGET_MIPS16
3989    && (register_operand (operands[0], SFmode)
3990        || reg_or_0_operand (operands[1], SFmode))"
3991   { return mips_output_move (operands[0], operands[1]); }
3992   [(set_attr "type"     "move,load,store")
3993    (set_attr "mode"     "SF")
3994    (set_attr "length"   "4,*,*")])
3996 (define_insn "*movsf_mips16"
3997   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
3998         (match_operand:SF 1 "move_operand" "d,d,y,m,d"))]
3999   "TARGET_MIPS16
4000    && (register_operand (operands[0], SFmode)
4001        || register_operand (operands[1], SFmode))"
4002   { return mips_output_move (operands[0], operands[1]); }
4003   [(set_attr "type"     "move,move,move,load,store")
4004    (set_attr "mode"     "SF")
4005    (set_attr "length"   "4,4,4,*,*")])
4008 ;; 64-bit floating point moves
4010 (define_expand "movdf"
4011   [(set (match_operand:DF 0 "")
4012         (match_operand:DF 1 ""))]
4013   ""
4015   if (mips_legitimize_move (DFmode, operands[0], operands[1]))
4016     DONE;
4019 (define_insn "*movdf_hardfloat_64bit"
4020   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
4021         (match_operand:DF 1 "move_operand" "f,G,m,f,G,*d,*f,*d*G,*m,*d"))]
4022   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT
4023    && (register_operand (operands[0], DFmode)
4024        || reg_or_0_operand (operands[1], DFmode))"
4025   { return mips_output_move (operands[0], operands[1]); }
4026   [(set_attr "type"     "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
4027    (set_attr "mode"     "DF")
4028    (set_attr "length"   "4,4,*,*,*,4,4,4,*,*")])
4030 ;; This pattern applies to both !TARGET_FLOAT64 and TARGET_FLOAT64.
4031 (define_insn "*movdf_hardfloat_32bit"
4032   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
4033         (match_operand:DF 1 "move_operand" "f,G,m,f,G,*d,*f,*d*G,*m,*d"))]
4034   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT
4035    && (register_operand (operands[0], DFmode)
4036        || reg_or_0_operand (operands[1], DFmode))"
4037   { return mips_output_move (operands[0], operands[1]); }
4038   [(set_attr "type"     "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
4039    (set_attr "mode"     "DF")
4040    (set_attr "length"   "4,8,*,*,*,8,8,8,*,*")])
4042 (define_insn "*movdf_softfloat"
4043   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f")
4044         (match_operand:DF 1 "move_operand" "dG,m,dG,f,d,f"))]
4045   "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
4046    && (register_operand (operands[0], DFmode)
4047        || reg_or_0_operand (operands[1], DFmode))"
4048   { return mips_output_move (operands[0], operands[1]); }
4049   [(set_attr "type"     "multi,load,store,mfc,mtc,fmove")
4050    (set_attr "mode"     "DF")
4051    (set_attr "length"   "8,*,*,4,4,4")])
4053 (define_insn "*movdf_mips16"
4054   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
4055         (match_operand:DF 1 "move_operand" "d,d,y,m,d"))]
4056   "TARGET_MIPS16
4057    && (register_operand (operands[0], DFmode)
4058        || register_operand (operands[1], DFmode))"
4059   { return mips_output_move (operands[0], operands[1]); }
4060   [(set_attr "type"     "multi,multi,multi,load,store")
4061    (set_attr "mode"     "DF")
4062    (set_attr "length"   "8,8,8,*,*")])
4064 ;; 128-bit floating point moves
4066 (define_expand "movtf"
4067   [(set (match_operand:TF 0 "")
4068         (match_operand:TF 1 ""))]
4069   ""
4071   if (mips_legitimize_move (TFmode, operands[0], operands[1]))
4072     DONE;
4075 ;; This pattern handles both hard- and soft-float cases.
4076 (define_insn_and_split "*movtf_internal"
4077   [(set (match_operand:TF 0 "nonimmediate_operand" "=d,R,f,dR")
4078         (match_operand:TF 1 "move_operand" "dGR,dG,dGR,f"))]
4079   ""
4080   "#"
4081   "&& reload_completed"
4082   [(const_int 0)]
4084   mips_split_doubleword_move (operands[0], operands[1]);
4085   DONE;
4087   [(set_attr "type" "multi")
4088    (set_attr "length" "16")])
4090 (define_split
4091   [(set (match_operand:MOVE64 0 "nonimmediate_operand")
4092         (match_operand:MOVE64 1 "move_operand"))]
4093   "reload_completed && !TARGET_64BIT
4094    && mips_split_64bit_move_p (operands[0], operands[1])"
4095   [(const_int 0)]
4097   mips_split_doubleword_move (operands[0], operands[1]);
4098   DONE;
4101 ;; When generating mips16 code, split moves of negative constants into
4102 ;; a positive "li" followed by a negation.
4103 (define_split
4104   [(set (match_operand 0 "register_operand")
4105         (match_operand 1 "const_int_operand"))]
4106   "TARGET_MIPS16 && reload_completed && INTVAL (operands[1]) < 0"
4107   [(set (match_dup 2)
4108         (match_dup 3))
4109    (set (match_dup 2)
4110         (neg:SI (match_dup 2)))]
4112   operands[2] = gen_lowpart (SImode, operands[0]);
4113   operands[3] = GEN_INT (-INTVAL (operands[1]));
4116 ;; 64-bit paired-single floating point moves
4118 (define_expand "movv2sf"
4119   [(set (match_operand:V2SF 0)
4120         (match_operand:V2SF 1))]
4121   "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
4123   if (mips_legitimize_move (V2SFmode, operands[0], operands[1]))
4124     DONE;
4127 (define_insn "movv2sf_hardfloat_64bit"
4128   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
4129         (match_operand:V2SF 1 "move_operand" "f,YG,m,f,YG,*d,*f,*d*YG,*m,*d"))]
4130   "TARGET_HARD_FLOAT
4131    && TARGET_PAIRED_SINGLE_FLOAT
4132    && TARGET_64BIT
4133    && (register_operand (operands[0], V2SFmode)
4134        || reg_or_0_operand (operands[1], V2SFmode))"
4135   { return mips_output_move (operands[0], operands[1]); }
4136   [(set_attr "type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
4137    (set_attr "mode" "SF")
4138    (set_attr "length" "4,4,*,*,*,4,4,4,*,*")])
4140 (define_insn "movv2sf_hardfloat_32bit"
4141   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
4142         (match_operand:V2SF 1 "move_operand" "f,YG,m,f,YG,*d,*f,*d*YG,*m,*d"))]
4143   "TARGET_HARD_FLOAT
4144    && TARGET_PAIRED_SINGLE_FLOAT
4145    && !TARGET_64BIT
4146    && (register_operand (operands[0], V2SFmode)
4147        || reg_or_0_operand (operands[1], V2SFmode))"
4148   { return mips_output_move (operands[0], operands[1]); }
4149   [(set_attr "type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
4150    (set_attr "mode" "SF")
4151    (set_attr "length" "4,8,*,*,*,8,8,8,*,*")])
4153 ;; The HI and LO registers are not truly independent.  If we move an mthi
4154 ;; instruction before an mflo instruction, it will make the result of the
4155 ;; mflo unpredictable.  The same goes for mtlo and mfhi.
4157 ;; We cope with this by making the mflo and mfhi patterns use both HI and LO.
4158 ;; Operand 1 is the register we want, operand 2 is the other one.
4160 ;; When generating VR4120 or VR4130 code, we use macc{,hi} and
4161 ;; dmacc{,hi} instead of mfhi and mflo.  This avoids both the normal
4162 ;; MIPS III hi/lo hazards and the errata related to -mfix-vr4130.
4164 (define_expand "mfhilo_<mode>"
4165   [(set (match_operand:GPR 0 "register_operand")
4166         (unspec:GPR [(match_operand:GPR 1 "register_operand")
4167                      (match_operand:GPR 2 "register_operand")]
4168                     UNSPEC_MFHILO))])
4170 (define_insn "*mfhilo_<mode>"
4171   [(set (match_operand:GPR 0 "register_operand" "=d,d")
4172         (unspec:GPR [(match_operand:GPR 1 "register_operand" "h,l")
4173                      (match_operand:GPR 2 "register_operand" "l,h")]
4174                     UNSPEC_MFHILO))]
4175   "!ISA_HAS_MACCHI"
4176   "mf%1\t%0"
4177   [(set_attr "type" "mfhilo")
4178    (set_attr "mode" "<MODE>")])
4180 (define_insn "*mfhilo_<mode>_macc"
4181   [(set (match_operand:GPR 0 "register_operand" "=d,d")
4182         (unspec:GPR [(match_operand:GPR 1 "register_operand" "h,l")
4183                      (match_operand:GPR 2 "register_operand" "l,h")]
4184                     UNSPEC_MFHILO))]
4185   "ISA_HAS_MACCHI"
4186   "@
4187    <d>macchi\t%0,%.,%.
4188    <d>macc\t%0,%.,%."
4189   [(set_attr "type" "mfhilo")
4190    (set_attr "mode" "<MODE>")])
4192 ;; Emit a doubleword move in which exactly one of the operands is
4193 ;; a floating-point register.  We can't just emit two normal moves
4194 ;; because of the constraints imposed by the FPU register model;
4195 ;; see mips_cannot_change_mode_class for details.  Instead, we keep
4196 ;; the FPR whole and use special patterns to refer to each word of
4197 ;; the other operand.
4199 (define_expand "move_doubleword_fpr<mode>"
4200   [(set (match_operand:SPLITF 0)
4201         (match_operand:SPLITF 1))]
4202   ""
4204   if (FP_REG_RTX_P (operands[0]))
4205     {
4206       rtx low = mips_subword (operands[1], 0);
4207       rtx high = mips_subword (operands[1], 1);
4208       emit_insn (gen_load_low<mode> (operands[0], low));
4209       if (ISA_HAS_MXHC1)
4210         emit_insn (gen_mthc1<mode> (operands[0], high, operands[0]));
4211       else
4212         emit_insn (gen_load_high<mode> (operands[0], high, operands[0]));
4213     }
4214   else
4215     {
4216       rtx low = mips_subword (operands[0], 0);
4217       rtx high = mips_subword (operands[0], 1);
4218       emit_insn (gen_store_word<mode> (low, operands[1], const0_rtx));
4219       if (ISA_HAS_MXHC1)
4220         emit_insn (gen_mfhc1<mode> (high, operands[1]));
4221       else
4222         emit_insn (gen_store_word<mode> (high, operands[1], const1_rtx));
4223     }
4224   DONE;
4227 ;; Load the low word of operand 0 with operand 1.
4228 (define_insn "load_low<mode>"
4229   [(set (match_operand:SPLITF 0 "register_operand" "=f,f")
4230         (unspec:SPLITF [(match_operand:<HALFMODE> 1 "general_operand" "dJ,m")]
4231                        UNSPEC_LOAD_LOW))]
4232   "TARGET_HARD_FLOAT"
4234   operands[0] = mips_subword (operands[0], 0);
4235   return mips_output_move (operands[0], operands[1]);
4237   [(set_attr "type" "mtc,fpload")
4238    (set_attr "mode" "<HALFMODE>")])
4240 ;; Load the high word of operand 0 from operand 1, preserving the value
4241 ;; in the low word.
4242 (define_insn "load_high<mode>"
4243   [(set (match_operand:SPLITF 0 "register_operand" "=f,f")
4244         (unspec:SPLITF [(match_operand:<HALFMODE> 1 "general_operand" "dJ,m")
4245                         (match_operand:SPLITF 2 "register_operand" "0,0")]
4246                        UNSPEC_LOAD_HIGH))]
4247   "TARGET_HARD_FLOAT"
4249   operands[0] = mips_subword (operands[0], 1);
4250   return mips_output_move (operands[0], operands[1]);
4252   [(set_attr "type" "mtc,fpload")
4253    (set_attr "mode" "<HALFMODE>")])
4255 ;; Store one word of operand 1 in operand 0.  Operand 2 is 1 to store the
4256 ;; high word and 0 to store the low word.
4257 (define_insn "store_word<mode>"
4258   [(set (match_operand:<HALFMODE> 0 "nonimmediate_operand" "=d,m")
4259         (unspec:<HALFMODE> [(match_operand:SPLITF 1 "register_operand" "f,f")
4260                             (match_operand 2 "const_int_operand")]
4261                            UNSPEC_STORE_WORD))]
4262   "TARGET_HARD_FLOAT"
4264   operands[1] = mips_subword (operands[1], INTVAL (operands[2]));
4265   return mips_output_move (operands[0], operands[1]);
4267   [(set_attr "type" "mfc,fpstore")
4268    (set_attr "mode" "<HALFMODE>")])
4270 ;; Move operand 1 to the high word of operand 0 using mthc1, preserving the
4271 ;; value in the low word.
4272 (define_insn "mthc1<mode>"
4273   [(set (match_operand:SPLITF 0 "register_operand" "=f")
4274         (unspec:SPLITF [(match_operand:<HALFMODE> 1 "general_operand" "dJ")
4275                         (match_operand:SPLITF 2 "register_operand" "0")]
4276                        UNSPEC_MTHC1))]
4277   "TARGET_HARD_FLOAT && ISA_HAS_MXHC1"
4278   "mthc1\t%z1,%0"
4279   [(set_attr "type" "mtc")
4280    (set_attr "mode" "<HALFMODE>")])
4282 ;; Move high word of operand 1 to operand 0 using mfhc1.
4283 (define_insn "mfhc1<mode>"
4284   [(set (match_operand:<HALFMODE> 0 "register_operand" "=d")
4285         (unspec:<HALFMODE> [(match_operand:SPLITF 1 "register_operand" "f")]
4286                             UNSPEC_MFHC1))]
4287   "TARGET_HARD_FLOAT && ISA_HAS_MXHC1"
4288   "mfhc1\t%0,%1"
4289   [(set_attr "type" "mfc")
4290    (set_attr "mode" "<HALFMODE>")])
4292 ;; Move a constant that satisfies CONST_GP_P into operand 0.
4293 (define_expand "load_const_gp_<mode>"
4294   [(set (match_operand:P 0 "register_operand" "=d")
4295         (const:P (unspec:P [(const_int 0)] UNSPEC_GP)))])
4297 ;; Insn to initialize $gp for n32/n64 abicalls.  Operand 0 is the offset
4298 ;; of _gp from the start of this function.  Operand 1 is the incoming
4299 ;; function address.
4300 (define_insn_and_split "loadgp_newabi_<mode>"
4301   [(set (match_operand:P 0 "register_operand" "=d")
4302         (unspec_volatile:P [(match_operand:P 1)
4303                             (match_operand:P 2 "register_operand" "d")]
4304                            UNSPEC_LOADGP))]
4305   "mips_current_loadgp_style () == LOADGP_NEWABI"
4306   "#"
4307   ""
4308   [(set (match_dup 0) (match_dup 3))
4309    (set (match_dup 0) (match_dup 4))
4310    (set (match_dup 0) (match_dup 5))]
4312   operands[3] = gen_rtx_HIGH (Pmode, operands[1]);
4313   operands[4] = gen_rtx_PLUS (Pmode, operands[0], operands[2]);
4314   operands[5] = gen_rtx_LO_SUM (Pmode, operands[0], operands[1]);
4316   [(set_attr "length" "12")])
4318 ;; Likewise, for -mno-shared code.  Operand 0 is the __gnu_local_gp symbol.
4319 (define_insn_and_split "loadgp_absolute_<mode>"
4320   [(set (match_operand:P 0 "register_operand" "=d")
4321         (unspec_volatile:P [(match_operand:P 1)] UNSPEC_LOADGP))]
4322   "mips_current_loadgp_style () == LOADGP_ABSOLUTE"
4323   "#"
4324   ""
4325   [(const_int 0)]
4327   mips_emit_move (operands[0], operands[1]);
4328   DONE;
4330   [(set_attr "length" "8")])
4332 ;; The use of gp is hidden when not using explicit relocations.
4333 ;; This blockage instruction prevents the gp load from being
4334 ;; scheduled after an implicit use of gp.  It also prevents
4335 ;; the load from being deleted as dead.
4336 (define_insn "loadgp_blockage"
4337   [(unspec_volatile [(reg:DI 28)] UNSPEC_BLOCKAGE)]
4338   ""
4339   ""
4340   [(set_attr "type" "ghost")
4341    (set_attr "mode" "none")
4342    (set_attr "length" "0")])
4344 ;; Initialize $gp for RTP PIC.  Operand 0 is the __GOTT_BASE__ symbol
4345 ;; and operand 1 is the __GOTT_INDEX__ symbol.
4346 (define_insn_and_split "loadgp_rtp_<mode>"
4347   [(set (match_operand:P 0 "register_operand" "=d")
4348         (unspec_volatile:P [(match_operand:P 1 "symbol_ref_operand")
4349                             (match_operand:P 2 "symbol_ref_operand")]
4350                            UNSPEC_LOADGP))]
4351   "mips_current_loadgp_style () == LOADGP_RTP"
4352   "#"
4353   ""
4354   [(set (match_dup 0) (high:P (match_dup 3)))
4355    (set (match_dup 0) (unspec:P [(match_dup 0)
4356                                  (match_dup 3)] UNSPEC_LOAD_GOT))
4357    (set (match_dup 0) (unspec:P [(match_dup 0)
4358                                  (match_dup 4)] UNSPEC_LOAD_GOT))]
4360   operands[3] = mips_unspec_address (operands[1], SYMBOL_ABSOLUTE);
4361   operands[4] = mips_unspec_address (operands[2], SYMBOL_HALF);
4363   [(set_attr "length" "12")])
4365 ;; Emit a .cprestore directive, which normally expands to a single store
4366 ;; instruction.  Note that we continue to use .cprestore for explicit reloc
4367 ;; code so that jals inside inline asms will work correctly.
4368 (define_insn "cprestore"
4369   [(unspec_volatile [(match_operand 0 "const_int_operand" "I,i")
4370                      (use (reg:SI 28))]
4371                     UNSPEC_CPRESTORE)]
4372   ""
4374   if (set_nomacro && which_alternative == 1)
4375     return ".set\tmacro\;.cprestore\t%0\;.set\tnomacro";
4376   else
4377     return ".cprestore\t%0";
4379   [(set_attr "type" "store")
4380    (set_attr "length" "4,12")])
4382 ;; Expand in-line code to clear the instruction cache between operand[0] and
4383 ;; operand[1].
4384 (define_expand "clear_cache"
4385   [(match_operand 0 "pmode_register_operand")
4386    (match_operand 1 "pmode_register_operand")]
4387   ""
4388   "
4390   if (ISA_HAS_SYNCI)
4391     {
4392       mips_expand_synci_loop (operands[0], operands[1]);
4393       emit_insn (gen_sync ());
4394       emit_insn (gen_clear_hazard ());
4395     }
4396   else if (mips_cache_flush_func && mips_cache_flush_func[0])
4397     {
4398       rtx len = gen_reg_rtx (Pmode);
4399       emit_insn (gen_sub3_insn (len, operands[1], operands[0]));
4400       MIPS_ICACHE_SYNC (operands[0], len);
4401     }
4402   DONE;
4405 (define_insn "sync"
4406   [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)]
4407   "GENERATE_SYNC"
4408   "%|sync%-")
4410 (define_insn "synci"
4411   [(unspec_volatile [(match_operand 0 "pmode_register_operand" "d")]
4412                     UNSPEC_SYNCI)]
4413   "ISA_HAS_SYNCI"
4414   "synci\t0(%0)")
4416 (define_insn "rdhwr"
4417   [(set (match_operand:SI 0 "register_operand" "=d")
4418         (unspec_volatile [(match_operand:SI 1 "const_int_operand" "n")]
4419         UNSPEC_RDHWR))]
4420   "ISA_HAS_SYNCI"
4421   "rdhwr\t%0,$%1")
4423 (define_insn "clear_hazard"
4424   [(unspec_volatile [(const_int 0)] UNSPEC_CLEAR_HAZARD)
4425    (clobber (reg:SI 31))]
4426   "ISA_HAS_SYNCI"
4428   return "%(%<bal\t1f\n"
4429          "\tnop\n"
4430          "1:\taddiu\t$31,$31,12\n"
4431          "\tjr.hb\t$31\n"
4432          "\tnop%>%)";
4434   [(set_attr "length" "20")])
4436 ;; Atomic memory operations.
4438 (define_insn "memory_barrier"
4439   [(set (mem:BLK (scratch))
4440         (unspec:BLK [(const_int 0)] UNSPEC_MEMORY_BARRIER))]
4441   "GENERATE_SYNC"
4442   "%|sync%-")
4444 (define_insn "sync_compare_and_swap<mode>"
4445   [(set (match_operand:GPR 0 "register_operand" "=&d,&d")
4446         (match_operand:GPR 1 "memory_operand" "+R,R"))
4447    (set (match_dup 1)
4448         (unspec_volatile:GPR [(match_operand:GPR 2 "reg_or_0_operand" "dJ,dJ")
4449                               (match_operand:GPR 3 "arith_operand" "I,d")]
4450          UNSPEC_COMPARE_AND_SWAP))]
4451   "GENERATE_LL_SC"
4453   if (which_alternative == 0)
4454     return MIPS_COMPARE_AND_SWAP ("<d>", "li");
4455   else
4456     return MIPS_COMPARE_AND_SWAP ("<d>", "move");
4458   [(set_attr "length" "32")])
4460 (define_expand "sync_compare_and_swap<mode>"
4461   [(match_operand:SHORT 0 "register_operand")
4462    (match_operand:SHORT 1 "memory_operand")
4463    (match_operand:SHORT 2 "general_operand")
4464    (match_operand:SHORT 3 "general_operand")]
4465   "GENERATE_LL_SC"
4467   union mips_gen_fn_ptrs generator;
4468   generator.fn_6 = gen_compare_and_swap_12;
4469   mips_expand_atomic_qihi (generator,
4470                            operands[0], operands[1], operands[2], operands[3]);
4471   DONE;
4474 ;; Helper insn for mips_expand_atomic_qihi.
4475 (define_insn "compare_and_swap_12"
4476   [(set (match_operand:SI 0 "register_operand" "=&d,&d")
4477         (match_operand:SI 1 "memory_operand" "+R,R"))
4478    (set (match_dup 1)
4479         (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "d,d")
4480                              (match_operand:SI 3 "register_operand" "d,d")
4481                              (match_operand:SI 4 "reg_or_0_operand" "dJ,dJ")
4482                              (match_operand:SI 5 "reg_or_0_operand" "d,J")]
4483                             UNSPEC_COMPARE_AND_SWAP_12))]
4484   "GENERATE_LL_SC"
4486   if (which_alternative == 0)
4487     return MIPS_COMPARE_AND_SWAP_12 (MIPS_COMPARE_AND_SWAP_12_NONZERO_OP);
4488   else
4489     return MIPS_COMPARE_AND_SWAP_12 (MIPS_COMPARE_AND_SWAP_12_ZERO_OP);
4491   [(set_attr "length" "40,36")])
4493 (define_insn "sync_add<mode>"
4494   [(set (match_operand:GPR 0 "memory_operand" "+R,R")
4495         (unspec_volatile:GPR
4496           [(plus:GPR (match_dup 0)
4497                      (match_operand:GPR 1 "arith_operand" "I,d"))]
4498           UNSPEC_SYNC_OLD_OP))]
4499   "GENERATE_LL_SC"
4501   if (which_alternative == 0)
4502     return MIPS_SYNC_OP ("<d>", "<d>addiu");    
4503   else
4504     return MIPS_SYNC_OP ("<d>", "<d>addu");     
4506   [(set_attr "length" "28")])
4508 (define_expand "sync_<optab><mode>"
4509   [(set (match_operand:SHORT 0 "memory_operand")
4510         (unspec_volatile:SHORT
4511           [(atomic_hiqi_op:SHORT (match_dup 0)
4512                                  (match_operand:SHORT 1 "general_operand"))]
4513           UNSPEC_SYNC_OLD_OP))]
4514   "GENERATE_LL_SC"
4516   union mips_gen_fn_ptrs generator;
4517   generator.fn_4 = gen_sync_<optab>_12;
4518   mips_expand_atomic_qihi (generator,
4519                            NULL, operands[0], operands[1], NULL);
4520   DONE;
4523 ;; Helper insn for sync_<optab><mode>
4524 (define_insn "sync_<optab>_12"
4525   [(set (match_operand:SI 0 "memory_operand" "+R")
4526         (unspec_volatile:SI
4527           [(match_operand:SI 1 "register_operand" "d")
4528            (match_operand:SI 2 "register_operand" "d")
4529            (atomic_hiqi_op:SI (match_dup 0)
4530                               (match_operand:SI 3 "register_operand" "dJ"))]
4531           UNSPEC_SYNC_OLD_OP_12))
4532    (clobber (match_scratch:SI 4 "=&d"))]
4533   "GENERATE_LL_SC"
4535     return MIPS_SYNC_OP_12 ("<insn>", MIPS_SYNC_OP_12_NOT_NOP); 
4537   [(set_attr "length" "40")])
4539 (define_expand "sync_old_<optab><mode>"
4540   [(parallel [
4541      (set (match_operand:SHORT 0 "register_operand")
4542           (match_operand:SHORT 1 "memory_operand"))
4543      (set (match_dup 1)
4544           (unspec_volatile:SHORT [(atomic_hiqi_op:SHORT
4545                                     (match_dup 1)
4546                                     (match_operand:SHORT 2 "general_operand"))]
4547             UNSPEC_SYNC_OLD_OP))])]
4548   "GENERATE_LL_SC"
4550   union mips_gen_fn_ptrs generator;
4551   generator.fn_5 = gen_sync_old_<optab>_12;
4552   mips_expand_atomic_qihi (generator,
4553                            operands[0], operands[1], operands[2], NULL);
4554   DONE;
4557 ;; Helper insn for sync_old_<optab><mode>
4558 (define_insn "sync_old_<optab>_12"
4559   [(set (match_operand:SI 0 "register_operand" "=&d")
4560         (match_operand:SI 1 "memory_operand" "+R"))
4561    (set (match_dup 1)
4562         (unspec_volatile:SI
4563           [(match_operand:SI 2 "register_operand" "d")
4564            (match_operand:SI 3 "register_operand" "d")
4565            (atomic_hiqi_op:SI (match_dup 0)
4566                               (match_operand:SI 4 "register_operand" "dJ"))]
4567           UNSPEC_SYNC_OLD_OP_12))
4568    (clobber (match_scratch:SI 5 "=&d"))]
4569   "GENERATE_LL_SC"
4571     return MIPS_SYNC_OLD_OP_12 ("<insn>", MIPS_SYNC_OLD_OP_12_NOT_NOP,
4572                                 MIPS_SYNC_OLD_OP_12_NOT_NOP_REG);       
4574   [(set_attr "length" "40")])
4576 (define_expand "sync_new_<optab><mode>"
4577   [(parallel [
4578      (set (match_operand:SHORT 0 "register_operand")
4579           (unspec_volatile:SHORT [(atomic_hiqi_op:SHORT
4580                                     (match_operand:SHORT 1 "memory_operand")
4581                                     (match_operand:SHORT 2 "general_operand"))]
4582             UNSPEC_SYNC_NEW_OP))
4583      (set (match_dup 1)
4584           (unspec_volatile:SHORT [(match_dup 1) (match_dup 2)]
4585             UNSPEC_SYNC_NEW_OP))])]
4586   "GENERATE_LL_SC"
4588   union mips_gen_fn_ptrs generator;
4589   generator.fn_5 = gen_sync_new_<optab>_12;
4590   mips_expand_atomic_qihi (generator,
4591                            operands[0], operands[1], operands[2], NULL);
4592   DONE;
4595 ;; Helper insn for sync_new_<optab><mode>
4596 (define_insn "sync_new_<optab>_12"
4597   [(set (match_operand:SI 0 "register_operand" "=&d")
4598         (unspec_volatile:SI
4599           [(match_operand:SI 1 "memory_operand" "+R")
4600            (match_operand:SI 2 "register_operand" "d")
4601            (match_operand:SI 3 "register_operand" "d")
4602            (atomic_hiqi_op:SI (match_dup 0)
4603                               (match_operand:SI 4 "register_operand" "dJ"))]
4604           UNSPEC_SYNC_NEW_OP_12))
4605    (set (match_dup 1)
4606         (unspec_volatile:SI
4607           [(match_dup 1)
4608            (match_dup 2)
4609            (match_dup 3)
4610            (match_dup 4)] UNSPEC_SYNC_NEW_OP_12))]
4611   "GENERATE_LL_SC"
4613     return MIPS_SYNC_NEW_OP_12 ("<insn>", MIPS_SYNC_NEW_OP_12_NOT_NOP);
4615   [(set_attr "length" "40")])
4617 (define_expand "sync_nand<mode>"
4618   [(set (match_operand:SHORT 0 "memory_operand")
4619         (unspec_volatile:SHORT
4620           [(match_dup 0)
4621            (match_operand:SHORT 1 "general_operand")]
4622           UNSPEC_SYNC_OLD_OP))]
4623   "GENERATE_LL_SC"
4625   union mips_gen_fn_ptrs generator;
4626   generator.fn_4 = gen_sync_nand_12;
4627   mips_expand_atomic_qihi (generator,
4628                            NULL, operands[0], operands[1], NULL);
4629   DONE;
4632 ;; Helper insn for sync_nand<mode>
4633 (define_insn "sync_nand_12"
4634   [(set (match_operand:SI 0 "memory_operand" "+R")
4635         (unspec_volatile:SI
4636           [(match_operand:SI 1 "register_operand" "d")
4637            (match_operand:SI 2 "register_operand" "d")
4638            (match_dup 0)
4639            (match_operand:SI 3 "register_operand" "dJ")]
4640           UNSPEC_SYNC_OLD_OP_12))
4641    (clobber (match_scratch:SI 4 "=&d"))]
4642   "GENERATE_LL_SC"
4644     return MIPS_SYNC_OP_12 ("and", MIPS_SYNC_OP_12_NOT_NOT);    
4646   [(set_attr "length" "44")])
4648 (define_expand "sync_old_nand<mode>"
4649   [(parallel [
4650      (set (match_operand:SHORT 0 "register_operand")
4651           (match_operand:SHORT 1 "memory_operand"))
4652      (set (match_dup 1)
4653           (unspec_volatile:SHORT [(match_dup 1)
4654                                   (match_operand:SHORT 2 "general_operand")]
4655             UNSPEC_SYNC_OLD_OP))])]
4656   "GENERATE_LL_SC"
4658   union mips_gen_fn_ptrs generator;
4659   generator.fn_5 = gen_sync_old_nand_12;
4660   mips_expand_atomic_qihi (generator,
4661                            operands[0], operands[1], operands[2], NULL);
4662   DONE;
4665 ;; Helper insn for sync_old_nand<mode>
4666 (define_insn "sync_old_nand_12"
4667   [(set (match_operand:SI 0 "register_operand" "=&d")
4668         (match_operand:SI 1 "memory_operand" "+R"))
4669    (set (match_dup 1)
4670         (unspec_volatile:SI
4671           [(match_operand:SI 2 "register_operand" "d")
4672            (match_operand:SI 3 "register_operand" "d")
4673            (match_operand:SI 4 "register_operand" "dJ")]
4674           UNSPEC_SYNC_OLD_OP_12))
4675    (clobber (match_scratch:SI 5 "=&d"))]
4676   "GENERATE_LL_SC"
4678     return MIPS_SYNC_OLD_OP_12 ("and", MIPS_SYNC_OLD_OP_12_NOT_NOT,
4679                                 MIPS_SYNC_OLD_OP_12_NOT_NOT_REG);       
4681   [(set_attr "length" "44")])
4683 (define_expand "sync_new_nand<mode>"
4684   [(parallel [
4685      (set (match_operand:SHORT 0 "register_operand")
4686           (unspec_volatile:SHORT [(match_operand:SHORT 1 "memory_operand")
4687                                   (match_operand:SHORT 2 "general_operand")]
4688             UNSPEC_SYNC_NEW_OP))
4689      (set (match_dup 1)
4690           (unspec_volatile:SHORT [(match_dup 1) (match_dup 2)]
4691             UNSPEC_SYNC_NEW_OP))])]
4692   "GENERATE_LL_SC"
4694   union mips_gen_fn_ptrs generator;
4695   generator.fn_5 = gen_sync_new_nand_12;
4696   mips_expand_atomic_qihi (generator,
4697                            operands[0], operands[1], operands[2], NULL);
4698   DONE;
4701 ;; Helper insn for sync_new_nand<mode>
4702 (define_insn "sync_new_nand_12"
4703   [(set (match_operand:SI 0 "register_operand" "=&d")
4704         (unspec_volatile:SI
4705           [(match_operand:SI 1 "memory_operand" "+R")
4706            (match_operand:SI 2 "register_operand" "d")
4707            (match_operand:SI 3 "register_operand" "d")
4708            (match_operand:SI 4 "register_operand" "dJ")]
4709           UNSPEC_SYNC_NEW_OP_12))
4710    (set (match_dup 1)
4711         (unspec_volatile:SI
4712           [(match_dup 1)
4713            (match_dup 2)
4714            (match_dup 3)
4715            (match_dup 4)] UNSPEC_SYNC_NEW_OP_12))]
4716   "GENERATE_LL_SC"
4718     return MIPS_SYNC_NEW_OP_12 ("and", MIPS_SYNC_NEW_OP_12_NOT_NOT);
4720   [(set_attr "length" "40")])
4722 (define_insn "sync_sub<mode>"
4723   [(set (match_operand:GPR 0 "memory_operand" "+R")
4724         (unspec_volatile:GPR
4725           [(minus:GPR (match_dup 0)
4726                               (match_operand:GPR 1 "register_operand" "d"))]
4727          UNSPEC_SYNC_OLD_OP))]
4728   "GENERATE_LL_SC"
4730   return MIPS_SYNC_OP ("<d>", "<d>subu");       
4732   [(set_attr "length" "28")])
4734 (define_insn "sync_old_add<mode>"
4735   [(set (match_operand:GPR 0 "register_operand" "=&d,&d")
4736         (match_operand:GPR 1 "memory_operand" "+R,R"))
4737    (set (match_dup 1)
4738         (unspec_volatile:GPR
4739           [(plus:GPR (match_dup 1)
4740                      (match_operand:GPR 2 "arith_operand" "I,d"))]
4741          UNSPEC_SYNC_OLD_OP))]
4742   "GENERATE_LL_SC"
4744   if (which_alternative == 0)
4745     return MIPS_SYNC_OLD_OP ("<d>", "<d>addiu");        
4746   else
4747     return MIPS_SYNC_OLD_OP ("<d>", "<d>addu"); 
4749   [(set_attr "length" "28")])
4751 (define_insn "sync_old_sub<mode>"
4752   [(set (match_operand:GPR 0 "register_operand" "=&d")
4753         (match_operand:GPR 1 "memory_operand" "+R"))
4754    (set (match_dup 1)
4755         (unspec_volatile:GPR
4756           [(minus:GPR (match_dup 1)
4757                       (match_operand:GPR 2 "register_operand" "d"))]
4758          UNSPEC_SYNC_OLD_OP))]
4759   "GENERATE_LL_SC"
4761   return MIPS_SYNC_OLD_OP ("<d>", "<d>subu");   
4763   [(set_attr "length" "28")])
4765 (define_insn "sync_new_add<mode>"
4766   [(set (match_operand:GPR 0 "register_operand" "=&d,&d")
4767         (plus:GPR (match_operand:GPR 1 "memory_operand" "+R,R")
4768                   (match_operand:GPR 2 "arith_operand" "I,d")))
4769    (set (match_dup 1)
4770         (unspec_volatile:GPR
4771           [(plus:GPR (match_dup 1) (match_dup 2))]
4772          UNSPEC_SYNC_NEW_OP))]
4773   "GENERATE_LL_SC"
4775   if (which_alternative == 0)
4776     return MIPS_SYNC_NEW_OP ("<d>", "<d>addiu");        
4777   else
4778     return MIPS_SYNC_NEW_OP ("<d>", "<d>addu"); 
4780   [(set_attr "length" "28")])
4782 (define_insn "sync_new_sub<mode>"
4783   [(set (match_operand:GPR 0 "register_operand" "=&d")
4784         (minus:GPR (match_operand:GPR 1 "memory_operand" "+R")
4785                    (match_operand:GPR 2 "register_operand" "d")))
4786    (set (match_dup 1)
4787         (unspec_volatile:GPR
4788           [(minus:GPR (match_dup 1) (match_dup 2))]
4789          UNSPEC_SYNC_NEW_OP))]
4790   "GENERATE_LL_SC"
4792   return MIPS_SYNC_NEW_OP ("<d>", "<d>subu");   
4794   [(set_attr "length" "28")])
4796 (define_insn "sync_<optab><mode>"
4797   [(set (match_operand:GPR 0 "memory_operand" "+R,R")
4798         (unspec_volatile:GPR
4799           [(fetchop_bit:GPR (match_operand:GPR 1 "uns_arith_operand" "K,d")
4800                               (match_dup 0))]
4801          UNSPEC_SYNC_OLD_OP))]
4802   "GENERATE_LL_SC"
4804   if (which_alternative == 0)
4805     return MIPS_SYNC_OP ("<d>", "<immediate_insn>");    
4806   else
4807     return MIPS_SYNC_OP ("<d>", "<insn>");      
4809   [(set_attr "length" "28")])
4811 (define_insn "sync_old_<optab><mode>"
4812   [(set (match_operand:GPR 0 "register_operand" "=&d,&d")
4813         (match_operand:GPR 1 "memory_operand" "+R,R"))
4814    (set (match_dup 1)
4815         (unspec_volatile:GPR
4816           [(fetchop_bit:GPR (match_operand:GPR 2 "uns_arith_operand" "K,d")
4817                             (match_dup 1))]
4818          UNSPEC_SYNC_OLD_OP))]
4819   "GENERATE_LL_SC"
4821   if (which_alternative == 0)
4822     return MIPS_SYNC_OLD_OP ("<d>", "<immediate_insn>");        
4823   else
4824     return MIPS_SYNC_OLD_OP ("<d>", "<insn>");  
4826   [(set_attr "length" "28")])
4828 (define_insn "sync_new_<optab><mode>"
4829   [(set (match_operand:GPR 0 "register_operand" "=&d,&d")
4830         (match_operand:GPR 1 "memory_operand" "+R,R"))
4831    (set (match_dup 1)
4832         (unspec_volatile:GPR
4833           [(fetchop_bit:GPR (match_operand:GPR 2 "uns_arith_operand" "K,d")
4834                             (match_dup 1))]
4835          UNSPEC_SYNC_NEW_OP))]
4836   "GENERATE_LL_SC"
4838   if (which_alternative == 0)
4839     return MIPS_SYNC_NEW_OP ("<d>", "<immediate_insn>");        
4840   else
4841     return MIPS_SYNC_NEW_OP ("<d>", "<insn>");  
4843   [(set_attr "length" "28")])
4845 (define_insn "sync_nand<mode>"
4846   [(set (match_operand:GPR 0 "memory_operand" "+R,R")
4847         (unspec_volatile:GPR [(match_operand:GPR 1 "uns_arith_operand" "K,d")]
4848          UNSPEC_SYNC_OLD_OP))]
4849   "GENERATE_LL_SC"
4851   if (which_alternative == 0)
4852     return MIPS_SYNC_NAND ("<d>", "andi");      
4853   else
4854     return MIPS_SYNC_NAND ("<d>", "and");       
4856   [(set_attr "length" "32")])
4858 (define_insn "sync_old_nand<mode>"
4859   [(set (match_operand:GPR 0 "register_operand" "=&d,&d")
4860         (match_operand:GPR 1 "memory_operand" "+R,R"))
4861    (set (match_dup 1)
4862         (unspec_volatile:GPR [(match_operand:GPR 2 "uns_arith_operand" "K,d")]
4863          UNSPEC_SYNC_OLD_OP))]
4864   "GENERATE_LL_SC"
4866   if (which_alternative == 0)
4867     return MIPS_SYNC_OLD_NAND ("<d>", "andi");  
4868   else
4869     return MIPS_SYNC_OLD_NAND ("<d>", "and");   
4871   [(set_attr "length" "32")])
4873 (define_insn "sync_new_nand<mode>"
4874   [(set (match_operand:GPR 0 "register_operand" "=&d,&d")
4875         (match_operand:GPR 1 "memory_operand" "+R,R"))
4876    (set (match_dup 1)
4877         (unspec_volatile:GPR [(match_operand:GPR 2 "uns_arith_operand" "K,d")]
4878          UNSPEC_SYNC_NEW_OP))]
4879   "GENERATE_LL_SC"
4881   if (which_alternative == 0)
4882     return MIPS_SYNC_NEW_NAND ("<d>", "andi");  
4883   else
4884     return MIPS_SYNC_NEW_NAND ("<d>", "and");   
4886   [(set_attr "length" "32")])
4888 (define_insn "sync_lock_test_and_set<mode>"
4889   [(set (match_operand:GPR 0 "register_operand" "=&d,&d")
4890         (match_operand:GPR 1 "memory_operand" "+R,R"))
4891    (set (match_dup 1)
4892         (unspec_volatile:GPR [(match_operand:GPR 2 "arith_operand" "I,d")]
4893          UNSPEC_SYNC_EXCHANGE))]
4894   "GENERATE_LL_SC"
4896   if (which_alternative == 0)
4897     return MIPS_SYNC_EXCHANGE ("<d>", "li");
4898   else
4899     return MIPS_SYNC_EXCHANGE ("<d>", "move");
4901   [(set_attr "length" "24")])
4903 (define_expand "sync_lock_test_and_set<mode>"
4904   [(match_operand:SHORT 0 "register_operand")
4905    (match_operand:SHORT 1 "memory_operand")
4906    (match_operand:SHORT 2 "general_operand")]
4907   "GENERATE_LL_SC"
4909   union mips_gen_fn_ptrs generator;
4910   generator.fn_5 = gen_test_and_set_12;
4911   mips_expand_atomic_qihi (generator,
4912                            operands[0], operands[1], operands[2], NULL);
4913   DONE;
4916 (define_insn "test_and_set_12"
4917   [(set (match_operand:SI 0 "register_operand" "=&d,&d")
4918         (match_operand:SI 1 "memory_operand" "+R,R"))
4919    (set (match_dup 1)
4920         (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "d,d")
4921                              (match_operand:SI 3 "register_operand" "d,d")
4922                              (match_operand:SI 4 "arith_operand" "d,J")]
4923           UNSPEC_SYNC_EXCHANGE_12))]
4924   "GENERATE_LL_SC"
4926   if (which_alternative == 0)
4927     return MIPS_SYNC_EXCHANGE_12 (MIPS_SYNC_EXCHANGE_12_NONZERO_OP);
4928   else
4929     return MIPS_SYNC_EXCHANGE_12 (MIPS_SYNC_EXCHANGE_12_ZERO_OP);
4931   [(set_attr "length" "28,24")])
4933 ;; Block moves, see mips.c for more details.
4934 ;; Argument 0 is the destination
4935 ;; Argument 1 is the source
4936 ;; Argument 2 is the length
4937 ;; Argument 3 is the alignment
4939 (define_expand "movmemsi"
4940   [(parallel [(set (match_operand:BLK 0 "general_operand")
4941                    (match_operand:BLK 1 "general_operand"))
4942               (use (match_operand:SI 2 ""))
4943               (use (match_operand:SI 3 "const_int_operand"))])]
4944   "!TARGET_MIPS16 && !TARGET_MEMCPY"
4946   if (mips_expand_block_move (operands[0], operands[1], operands[2]))
4947     DONE;
4948   else
4949     FAIL;
4953 ;;  ....................
4955 ;;      SHIFTS
4957 ;;  ....................
4959 (define_expand "<optab><mode>3"
4960   [(set (match_operand:GPR 0 "register_operand")
4961         (any_shift:GPR (match_operand:GPR 1 "register_operand")
4962                        (match_operand:SI 2 "arith_operand")))]
4963   ""
4965   /* On the mips16, a shift of more than 8 is a four byte instruction,
4966      so, for a shift between 8 and 16, it is just as fast to do two
4967      shifts of 8 or less.  If there is a lot of shifting going on, we
4968      may win in CSE.  Otherwise combine will put the shifts back
4969      together again.  This can be called by mips_function_arg, so we must
4970      be careful not to allocate a new register if we've reached the
4971      reload pass.  */
4972   if (TARGET_MIPS16
4973       && optimize
4974       && GET_CODE (operands[2]) == CONST_INT
4975       && INTVAL (operands[2]) > 8
4976       && INTVAL (operands[2]) <= 16
4977       && !reload_in_progress
4978       && !reload_completed)
4979     {
4980       rtx temp = gen_reg_rtx (<MODE>mode);
4982       emit_insn (gen_<optab><mode>3 (temp, operands[1], GEN_INT (8)));
4983       emit_insn (gen_<optab><mode>3 (operands[0], temp,
4984                                      GEN_INT (INTVAL (operands[2]) - 8)));
4985       DONE;
4986     }
4989 (define_insn "*<optab><mode>3"
4990   [(set (match_operand:GPR 0 "register_operand" "=d")
4991         (any_shift:GPR (match_operand:GPR 1 "register_operand" "d")
4992                        (match_operand:SI 2 "arith_operand" "dI")))]
4993   "!TARGET_MIPS16"
4995   if (GET_CODE (operands[2]) == CONST_INT)
4996     operands[2] = GEN_INT (INTVAL (operands[2])
4997                            & (GET_MODE_BITSIZE (<MODE>mode) - 1));
4999   return "<d><insn>\t%0,%1,%2";
5001   [(set_attr "type" "shift")
5002    (set_attr "mode" "<MODE>")])
5004 (define_insn "*<optab>si3_extend"
5005   [(set (match_operand:DI 0 "register_operand" "=d")
5006         (sign_extend:DI
5007            (any_shift:SI (match_operand:SI 1 "register_operand" "d")
5008                          (match_operand:SI 2 "arith_operand" "dI"))))]
5009   "TARGET_64BIT && !TARGET_MIPS16"
5011   if (GET_CODE (operands[2]) == CONST_INT)
5012     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5014   return "<insn>\t%0,%1,%2";
5016   [(set_attr "type" "shift")
5017    (set_attr "mode" "SI")])
5019 (define_insn "*<optab>si3_mips16"
5020   [(set (match_operand:SI 0 "register_operand" "=d,d")
5021         (any_shift:SI (match_operand:SI 1 "register_operand" "0,d")
5022                       (match_operand:SI 2 "arith_operand" "d,I")))]
5023   "TARGET_MIPS16"
5025   if (which_alternative == 0)
5026     return "<insn>\t%0,%2";
5028   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5029   return "<insn>\t%0,%1,%2";
5031   [(set_attr "type" "shift")
5032    (set_attr "mode" "SI")
5033    (set_attr_alternative "length"
5034                 [(const_int 4)
5035                  (if_then_else (match_operand 2 "m16_uimm3_b")
5036                                (const_int 4)
5037                                (const_int 8))])])
5039 ;; We need separate DImode MIPS16 patterns because of the irregularity
5040 ;; of right shifts.
5041 (define_insn "*ashldi3_mips16"
5042   [(set (match_operand:DI 0 "register_operand" "=d,d")
5043         (ashift:DI (match_operand:DI 1 "register_operand" "0,d")
5044                    (match_operand:SI 2 "arith_operand" "d,I")))]
5045   "TARGET_64BIT && TARGET_MIPS16"
5047   if (which_alternative == 0)
5048     return "dsll\t%0,%2";
5050   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5051   return "dsll\t%0,%1,%2";
5053   [(set_attr "type" "shift")
5054    (set_attr "mode" "DI")
5055    (set_attr_alternative "length"
5056                 [(const_int 4)
5057                  (if_then_else (match_operand 2 "m16_uimm3_b")
5058                                (const_int 4)
5059                                (const_int 8))])])
5061 (define_insn "*ashrdi3_mips16"
5062   [(set (match_operand:DI 0 "register_operand" "=d,d")
5063         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
5064                      (match_operand:SI 2 "arith_operand" "d,I")))]
5065   "TARGET_64BIT && TARGET_MIPS16"
5067   if (GET_CODE (operands[2]) == CONST_INT)
5068     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5070   return "dsra\t%0,%2";
5072   [(set_attr "type" "shift")
5073    (set_attr "mode" "DI")
5074    (set_attr_alternative "length"
5075                 [(const_int 4)
5076                  (if_then_else (match_operand 2 "m16_uimm3_b")
5077                                (const_int 4)
5078                                (const_int 8))])])
5080 (define_insn "*lshrdi3_mips16"
5081   [(set (match_operand:DI 0 "register_operand" "=d,d")
5082         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
5083                      (match_operand:SI 2 "arith_operand" "d,I")))]
5084   "TARGET_64BIT && TARGET_MIPS16"
5086   if (GET_CODE (operands[2]) == CONST_INT)
5087     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5089   return "dsrl\t%0,%2";
5091   [(set_attr "type" "shift")
5092    (set_attr "mode" "DI")
5093    (set_attr_alternative "length"
5094                 [(const_int 4)
5095                  (if_then_else (match_operand 2 "m16_uimm3_b")
5096                                (const_int 4)
5097                                (const_int 8))])])
5099 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5101 (define_split
5102   [(set (match_operand:GPR 0 "register_operand")
5103         (any_shift:GPR (match_operand:GPR 1 "register_operand")
5104                        (match_operand:GPR 2 "const_int_operand")))]
5105   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5106    && GET_CODE (operands[2]) == CONST_INT
5107    && INTVAL (operands[2]) > 8
5108    && INTVAL (operands[2]) <= 16"
5109   [(set (match_dup 0) (any_shift:GPR (match_dup 1) (const_int 8)))
5110    (set (match_dup 0) (any_shift:GPR (match_dup 0) (match_dup 2)))]
5111   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5113 ;; If we load a byte on the mips16 as a bitfield, the resulting
5114 ;; sequence of instructions is too complicated for combine, because it
5115 ;; involves four instructions: a load, a shift, a constant load into a
5116 ;; register, and an and (the key problem here is that the mips16 does
5117 ;; not have and immediate).  We recognize a shift of a load in order
5118 ;; to make it simple enough for combine to understand.
5120 ;; The length here is the worst case: the length of the split version
5121 ;; will be more accurate.
5122 (define_insn_and_split ""
5123   [(set (match_operand:SI 0 "register_operand" "=d")
5124         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
5125                      (match_operand:SI 2 "immediate_operand" "I")))]
5126   "TARGET_MIPS16"
5127   "#"
5128   ""
5129   [(set (match_dup 0) (match_dup 1))
5130    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
5131   ""
5132   [(set_attr "type"     "load")
5133    (set_attr "mode"     "SI")
5134    (set_attr "length"   "16")])
5136 (define_insn "rotr<mode>3"
5137   [(set (match_operand:GPR 0 "register_operand" "=d")
5138         (rotatert:GPR (match_operand:GPR 1 "register_operand" "d")
5139                       (match_operand:SI 2 "arith_operand" "dI")))]
5140   "ISA_HAS_ROR"
5142   if (GET_CODE (operands[2]) == CONST_INT)
5143     gcc_assert (INTVAL (operands[2]) >= 0
5144                 && INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode));
5146   return "<d>ror\t%0,%1,%2";
5148   [(set_attr "type" "shift")
5149    (set_attr "mode" "<MODE>")])
5152 ;;  ....................
5154 ;;      COMPARISONS
5156 ;;  ....................
5158 ;; Flow here is rather complex:
5160 ;;  1)  The cmp{si,di,sf,df} routine is called.  It deposits the arguments
5161 ;;      into cmp_operands[] but generates no RTL.
5163 ;;  2)  The appropriate branch define_expand is called, which then
5164 ;;      creates the appropriate RTL for the comparison and branch.
5165 ;;      Different CC modes are used, based on what type of branch is
5166 ;;      done, so that we can constrain things appropriately.  There
5167 ;;      are assumptions in the rest of GCC that break if we fold the
5168 ;;      operands into the branches for integer operations, and use cc0
5169 ;;      for floating point, so we use the fp status register instead.
5170 ;;      If needed, an appropriate temporary is created to hold the
5171 ;;      of the integer compare.
5173 (define_expand "cmp<mode>"
5174   [(set (cc0)
5175         (compare:CC (match_operand:GPR 0 "register_operand")
5176                     (match_operand:GPR 1 "nonmemory_operand")))]
5177   ""
5179   cmp_operands[0] = operands[0];
5180   cmp_operands[1] = operands[1];
5181   DONE;
5184 (define_expand "cmp<mode>"
5185   [(set (cc0)
5186         (compare:CC (match_operand:SCALARF 0 "register_operand")
5187                     (match_operand:SCALARF 1 "register_operand")))]
5188   ""
5190   cmp_operands[0] = operands[0];
5191   cmp_operands[1] = operands[1];
5192   DONE;
5196 ;;  ....................
5198 ;;      CONDITIONAL BRANCHES
5200 ;;  ....................
5202 ;; Conditional branches on floating-point equality tests.
5204 (define_insn "*branch_fp"
5205   [(set (pc)
5206         (if_then_else
5207          (match_operator 0 "equality_operator"
5208                          [(match_operand:CC 2 "register_operand" "z")
5209                           (const_int 0)])
5210          (label_ref (match_operand 1 "" ""))
5211          (pc)))]
5212   "TARGET_HARD_FLOAT"
5214   return mips_output_conditional_branch (insn, operands,
5215                                          MIPS_BRANCH ("b%F0", "%Z2%1"),
5216                                          MIPS_BRANCH ("b%W0", "%Z2%1"));
5218   [(set_attr "type" "branch")
5219    (set_attr "mode" "none")])
5221 (define_insn "*branch_fp_inverted"
5222   [(set (pc)
5223         (if_then_else
5224          (match_operator 0 "equality_operator"
5225                          [(match_operand:CC 2 "register_operand" "z")
5226                           (const_int 0)])
5227          (pc)
5228          (label_ref (match_operand 1 "" ""))))]
5229   "TARGET_HARD_FLOAT"
5231   return mips_output_conditional_branch (insn, operands,
5232                                          MIPS_BRANCH ("b%W0", "%Z2%1"),
5233                                          MIPS_BRANCH ("b%F0", "%Z2%1"));
5235   [(set_attr "type" "branch")
5236    (set_attr "mode" "none")])
5238 ;; Conditional branches on ordered comparisons with zero.
5240 (define_insn "*branch_order<mode>"
5241   [(set (pc)
5242         (if_then_else
5243          (match_operator 0 "order_operator"
5244                          [(match_operand:GPR 2 "register_operand" "d")
5245                           (const_int 0)])
5246          (label_ref (match_operand 1 "" ""))
5247          (pc)))]
5248   "!TARGET_MIPS16"
5249   { return mips_output_order_conditional_branch (insn, operands, false); }
5250   [(set_attr "type" "branch")
5251    (set_attr "mode" "none")])
5253 (define_insn "*branch_order<mode>_inverted"
5254   [(set (pc)
5255         (if_then_else
5256          (match_operator 0 "order_operator"
5257                          [(match_operand:GPR 2 "register_operand" "d")
5258                           (const_int 0)])
5259          (pc)
5260          (label_ref (match_operand 1 "" ""))))]
5261   "!TARGET_MIPS16"
5262   { return mips_output_order_conditional_branch (insn, operands, true); }
5263   [(set_attr "type" "branch")
5264    (set_attr "mode" "none")])
5266 ;; Conditional branch on equality comparison.
5268 (define_insn "*branch_equality<mode>"
5269   [(set (pc)
5270         (if_then_else
5271          (match_operator 0 "equality_operator"
5272                          [(match_operand:GPR 2 "register_operand" "d")
5273                           (match_operand:GPR 3 "reg_or_0_operand" "dJ")])
5274          (label_ref (match_operand 1 "" ""))
5275          (pc)))]
5276   "!TARGET_MIPS16"
5278   return mips_output_conditional_branch (insn, operands,
5279                                          MIPS_BRANCH ("b%C0", "%2,%z3,%1"),
5280                                          MIPS_BRANCH ("b%N0", "%2,%z3,%1"));
5282   [(set_attr "type" "branch")
5283    (set_attr "mode" "none")])
5285 (define_insn "*branch_equality<mode>_inverted"
5286   [(set (pc)
5287         (if_then_else
5288          (match_operator 0 "equality_operator"
5289                          [(match_operand:GPR 2 "register_operand" "d")
5290                           (match_operand:GPR 3 "reg_or_0_operand" "dJ")])
5291          (pc)
5292          (label_ref (match_operand 1 "" ""))))]
5293   "!TARGET_MIPS16"
5295   return mips_output_conditional_branch (insn, operands,
5296                                          MIPS_BRANCH ("b%N0", "%2,%z3,%1"),
5297                                          MIPS_BRANCH ("b%C0", "%2,%z3,%1"));
5299   [(set_attr "type" "branch")
5300    (set_attr "mode" "none")])
5302 ;; MIPS16 branches
5304 (define_insn "*branch_equality<mode>_mips16"
5305   [(set (pc)
5306         (if_then_else
5307          (match_operator 0 "equality_operator"
5308                          [(match_operand:GPR 1 "register_operand" "d,t")
5309                           (const_int 0)])
5310          (match_operand 2 "pc_or_label_operand" "")
5311          (match_operand 3 "pc_or_label_operand" "")))]
5312   "TARGET_MIPS16"
5314   if (operands[2] != pc_rtx)
5315     {
5316       if (which_alternative == 0)
5317         return "b%C0z\t%1,%2";
5318       else
5319         return "bt%C0z\t%2";
5320     }
5321   else
5322     {
5323       if (which_alternative == 0)
5324         return "b%N0z\t%1,%3";
5325       else
5326         return "bt%N0z\t%3";
5327     }
5329   [(set_attr "type" "branch")
5330    (set_attr "mode" "none")
5331    (set_attr "length" "8")])
5333 (define_expand "b<code>"
5334   [(set (pc)
5335         (if_then_else (any_cond:CC (cc0)
5336                                    (const_int 0))
5337                       (label_ref (match_operand 0 ""))
5338                       (pc)))]
5339   ""
5341   mips_expand_conditional_branch (operands, <CODE>);
5342   DONE;
5345 ;; Used to implement built-in functions.
5346 (define_expand "condjump"
5347   [(set (pc)
5348         (if_then_else (match_operand 0)
5349                       (label_ref (match_operand 1))
5350                       (pc)))])
5353 ;;  ....................
5355 ;;      SETTING A REGISTER FROM A COMPARISON
5357 ;;  ....................
5359 ;; Destination is always set in SI mode.
5361 (define_expand "seq"
5362   [(set (match_operand:SI 0 "register_operand")
5363         (eq:SI (match_dup 1)
5364                (match_dup 2)))]
5365   ""
5366   { if (mips_expand_scc (EQ, operands[0])) DONE; else FAIL; })
5368 (define_insn "*seq_<GPR:mode><GPR2:mode>"
5369   [(set (match_operand:GPR2 0 "register_operand" "=d")
5370         (eq:GPR2 (match_operand:GPR 1 "register_operand" "d")
5371                  (const_int 0)))]
5372   "!TARGET_MIPS16"
5373   "sltu\t%0,%1,1"
5374   [(set_attr "type" "slt")
5375    (set_attr "mode" "<GPR:MODE>")])
5377 (define_insn "*seq_<GPR:mode><GPR2:mode>_mips16"
5378   [(set (match_operand:GPR2 0 "register_operand" "=t")
5379         (eq:GPR2 (match_operand:GPR 1 "register_operand" "d")
5380                  (const_int 0)))]
5381   "TARGET_MIPS16"
5382   "sltu\t%1,1"
5383   [(set_attr "type" "slt")
5384    (set_attr "mode" "<GPR:MODE>")])
5386 ;; "sne" uses sltu instructions in which the first operand is $0.
5387 ;; This isn't possible in mips16 code.
5389 (define_expand "sne"
5390   [(set (match_operand:SI 0 "register_operand")
5391         (ne:SI (match_dup 1)
5392                (match_dup 2)))]
5393   "!TARGET_MIPS16"
5394   { if (mips_expand_scc (NE, operands[0])) DONE; else FAIL; })
5396 (define_insn "*sne_<GPR:mode><GPR2:mode>"
5397   [(set (match_operand:GPR2 0 "register_operand" "=d")
5398         (ne:GPR2 (match_operand:GPR 1 "register_operand" "d")
5399                  (const_int 0)))]
5400   "!TARGET_MIPS16"
5401   "sltu\t%0,%.,%1"
5402   [(set_attr "type" "slt")
5403    (set_attr "mode" "<GPR:MODE>")])
5405 (define_expand "sgt<u>"
5406   [(set (match_operand:SI 0 "register_operand")
5407         (any_gt:SI (match_dup 1)
5408                    (match_dup 2)))]
5409   ""
5410   { if (mips_expand_scc (<CODE>, operands[0])) DONE; else FAIL; })
5412 (define_insn "*sgt<u>_<GPR:mode><GPR2:mode>"
5413   [(set (match_operand:GPR2 0 "register_operand" "=d")
5414         (any_gt:GPR2 (match_operand:GPR 1 "register_operand" "d")
5415                      (match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
5416   "!TARGET_MIPS16"
5417   "slt<u>\t%0,%z2,%1"
5418   [(set_attr "type" "slt")
5419    (set_attr "mode" "<GPR:MODE>")])
5421 (define_insn "*sgt<u>_<GPR:mode><GPR2:mode>_mips16"
5422   [(set (match_operand:GPR2 0 "register_operand" "=t")
5423         (any_gt:GPR2 (match_operand:GPR 1 "register_operand" "d")
5424                      (match_operand:GPR 2 "register_operand" "d")))]
5425   "TARGET_MIPS16"
5426   "slt<u>\t%2,%1"
5427   [(set_attr "type" "slt")
5428    (set_attr "mode" "<GPR:MODE>")])
5430 (define_expand "sge<u>"
5431   [(set (match_operand:SI 0 "register_operand")
5432         (any_ge:SI (match_dup 1)
5433                    (match_dup 2)))]
5434   ""
5435   { if (mips_expand_scc (<CODE>, operands[0])) DONE; else FAIL; })
5437 (define_insn "*sge<u>_<GPR:mode><GPR2:mode>"
5438   [(set (match_operand:GPR2 0 "register_operand" "=d")
5439         (any_ge:GPR2 (match_operand:GPR 1 "register_operand" "d")
5440                      (const_int 1)))]
5441   "!TARGET_MIPS16"
5442   "slt<u>\t%0,%.,%1"
5443   [(set_attr "type" "slt")
5444    (set_attr "mode" "<GPR:MODE>")])
5446 (define_expand "slt<u>"
5447   [(set (match_operand:SI 0 "register_operand")
5448         (any_lt:SI (match_dup 1)
5449                    (match_dup 2)))]
5450   ""
5451   { if (mips_expand_scc (<CODE>, operands[0])) DONE; else FAIL; })
5453 (define_insn "*slt<u>_<GPR:mode><GPR2:mode>"
5454   [(set (match_operand:GPR2 0 "register_operand" "=d")
5455         (any_lt:GPR2 (match_operand:GPR 1 "register_operand" "d")
5456                      (match_operand:GPR 2 "arith_operand" "dI")))]
5457   "!TARGET_MIPS16"
5458   "slt<u>\t%0,%1,%2"
5459   [(set_attr "type" "slt")
5460    (set_attr "mode" "<GPR:MODE>")])
5462 (define_insn "*slt<u>_<GPR:mode><GPR2:mode>_mips16"
5463   [(set (match_operand:GPR2 0 "register_operand" "=t,t")
5464         (any_lt:GPR2 (match_operand:GPR 1 "register_operand" "d,d")
5465                      (match_operand:GPR 2 "arith_operand" "d,I")))]
5466   "TARGET_MIPS16"
5467   "slt<u>\t%1,%2"
5468   [(set_attr "type" "slt")
5469    (set_attr "mode" "<GPR:MODE>")
5470    (set_attr_alternative "length"
5471                 [(const_int 4)
5472                  (if_then_else (match_operand 2 "m16_uimm8_1")
5473                                (const_int 4)
5474                                (const_int 8))])])
5476 (define_expand "sle<u>"
5477   [(set (match_operand:SI 0 "register_operand")
5478         (any_le:SI (match_dup 1)
5479                    (match_dup 2)))]
5480   ""
5481   { if (mips_expand_scc (<CODE>, operands[0])) DONE; else FAIL; })
5483 (define_insn "*sle<u>_<GPR:mode><GPR2:mode>"
5484   [(set (match_operand:GPR2 0 "register_operand" "=d")
5485         (any_le:GPR2 (match_operand:GPR 1 "register_operand" "d")
5486                      (match_operand:GPR 2 "sle_operand" "")))]
5487   "!TARGET_MIPS16"
5489   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5490   return "slt<u>\t%0,%1,%2";
5492   [(set_attr "type" "slt")
5493    (set_attr "mode" "<GPR:MODE>")])
5495 (define_insn "*sle<u>_<GPR:mode><GPR2:mode>_mips16"
5496   [(set (match_operand:GPR2 0 "register_operand" "=t")
5497         (any_le:GPR2 (match_operand:GPR 1 "register_operand" "d")
5498                      (match_operand:GPR 2 "sle_operand" "")))]
5499   "TARGET_MIPS16"
5501   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5502   return "slt<u>\t%1,%2";
5504   [(set_attr "type" "slt")
5505    (set_attr "mode" "<GPR:MODE>")
5506    (set (attr "length") (if_then_else (match_operand 2 "m16_uimm8_m1_1")
5507                                       (const_int 4)
5508                                       (const_int 8)))])
5511 ;;  ....................
5513 ;;      FLOATING POINT COMPARISONS
5515 ;;  ....................
5517 (define_insn "s<code>_<mode>"
5518   [(set (match_operand:CC 0 "register_operand" "=z")
5519         (fcond:CC (match_operand:SCALARF 1 "register_operand" "f")
5520                   (match_operand:SCALARF 2 "register_operand" "f")))]
5521   ""
5522   "c.<fcond>.<fmt>\t%Z0%1,%2"
5523   [(set_attr "type" "fcmp")
5524    (set_attr "mode" "FPSW")])
5526 (define_insn "s<code>_<mode>"
5527   [(set (match_operand:CC 0 "register_operand" "=z")
5528         (swapped_fcond:CC (match_operand:SCALARF 1 "register_operand" "f")
5529                           (match_operand:SCALARF 2 "register_operand" "f")))]
5530   ""
5531   "c.<swapped_fcond>.<fmt>\t%Z0%2,%1"
5532   [(set_attr "type" "fcmp")
5533    (set_attr "mode" "FPSW")])
5536 ;;  ....................
5538 ;;      UNCONDITIONAL BRANCHES
5540 ;;  ....................
5542 ;; Unconditional branches.
5544 (define_insn "jump"
5545   [(set (pc)
5546         (label_ref (match_operand 0 "" "")))]
5547   "!TARGET_MIPS16"
5549   if (flag_pic)
5550     {
5551       if (get_attr_length (insn) <= 8)
5552         return "%*b\t%l0%/";
5553       else
5554         {
5555           output_asm_insn (mips_output_load_label (), operands);
5556           return "%*jr\t%@%/%]";
5557         }
5558     }
5559   else
5560     return "%*j\t%l0%/";
5562   [(set_attr "type"     "jump")
5563    (set_attr "mode"     "none")
5564    (set (attr "length")
5565         ;; We can't use `j' when emitting PIC.  Emit a branch if it's
5566         ;; in range, otherwise load the address of the branch target into
5567         ;; $at and then jump to it.
5568         (if_then_else
5569          (ior (eq (symbol_ref "flag_pic") (const_int 0))
5570               (lt (abs (minus (match_dup 0)
5571                               (plus (pc) (const_int 4))))
5572                   (const_int 131072)))
5573          (const_int 4) (const_int 16)))])
5575 ;; We need a different insn for the mips16, because a mips16 branch
5576 ;; does not have a delay slot.
5578 (define_insn ""
5579   [(set (pc)
5580         (label_ref (match_operand 0 "" "")))]
5581   "TARGET_MIPS16"
5582   "b\t%l0"
5583   [(set_attr "type"     "branch")
5584    (set_attr "mode"     "none")
5585    (set_attr "length"   "8")])
5587 (define_expand "indirect_jump"
5588   [(set (pc) (match_operand 0 "register_operand"))]
5589   ""
5591   operands[0] = force_reg (Pmode, operands[0]);
5592   if (Pmode == SImode)
5593     emit_jump_insn (gen_indirect_jumpsi (operands[0]));
5594   else
5595     emit_jump_insn (gen_indirect_jumpdi (operands[0]));
5596   DONE;
5599 (define_insn "indirect_jump<mode>"
5600   [(set (pc) (match_operand:P 0 "register_operand" "d"))]
5601   ""
5602   "%*j\t%0%/"
5603   [(set_attr "type" "jump")
5604    (set_attr "mode" "none")])
5606 (define_expand "tablejump"
5607   [(set (pc)
5608         (match_operand 0 "register_operand"))
5609    (use (label_ref (match_operand 1 "")))]
5610   ""
5612   if (TARGET_MIPS16_SHORT_JUMP_TABLES)
5613     operands[0] = expand_binop (Pmode, add_optab,
5614                                 convert_to_mode (Pmode, operands[0], false),
5615                                 gen_rtx_LABEL_REF (Pmode, operands[1]),
5616                                 0, 0, OPTAB_WIDEN);
5617   else if (TARGET_GPWORD)
5618     operands[0] = expand_binop (Pmode, add_optab, operands[0],
5619                                 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
5620   else if (TARGET_RTP_PIC)
5621     {
5622       /* When generating RTP PIC, we use case table entries that are relative
5623          to the start of the function.  Add the function's address to the
5624          value we loaded.  */
5625       rtx start = get_hard_reg_initial_val (Pmode, PIC_FUNCTION_ADDR_REGNUM);
5626       operands[0] = expand_binop (ptr_mode, add_optab, operands[0],
5627                                   start, 0, 0, OPTAB_WIDEN);
5628     }
5630   if (Pmode == SImode)
5631     emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
5632   else
5633     emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
5634   DONE;
5637 (define_insn "tablejump<mode>"
5638   [(set (pc)
5639         (match_operand:P 0 "register_operand" "d"))
5640    (use (label_ref (match_operand 1 "" "")))]
5641   ""
5642   "%*j\t%0%/"
5643   [(set_attr "type" "jump")
5644    (set_attr "mode" "none")])
5646 ;; For TARGET_USE_GOT, we save the gp in the jmp_buf as well.
5647 ;; While it is possible to either pull it off the stack (in the
5648 ;; o32 case) or recalculate it given t9 and our target label,
5649 ;; it takes 3 or 4 insns to do so.
5651 (define_expand "builtin_setjmp_setup"
5652   [(use (match_operand 0 "register_operand"))]
5653   "TARGET_USE_GOT"
5655   rtx addr;
5657   addr = plus_constant (operands[0], GET_MODE_SIZE (Pmode) * 3);
5658   mips_emit_move (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
5659   DONE;
5662 ;; Restore the gp that we saved above.  Despite the earlier comment, it seems
5663 ;; that older code did recalculate the gp from $25.  Continue to jump through
5664 ;; $25 for compatibility (we lose nothing by doing so).
5666 (define_expand "builtin_longjmp"
5667   [(use (match_operand 0 "register_operand"))]
5668   "TARGET_USE_GOT"
5670   /* The elements of the buffer are, in order:  */
5671   int W = GET_MODE_SIZE (Pmode);
5672   rtx fp = gen_rtx_MEM (Pmode, operands[0]);
5673   rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
5674   rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
5675   rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
5676   rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
5677   /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
5678      The target is bound to be using $28 as the global pointer
5679      but the current function might not be.  */
5680   rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
5682   /* This bit is similar to expand_builtin_longjmp except that it
5683      restores $gp as well.  */
5684   mips_emit_move (hard_frame_pointer_rtx, fp);
5685   mips_emit_move (pv, lab);
5686   emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
5687   mips_emit_move (gp, gpv);
5688   emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
5689   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
5690   emit_insn (gen_rtx_USE (VOIDmode, gp));
5691   emit_indirect_jump (pv);
5692   DONE;
5696 ;;  ....................
5698 ;;      Function prologue/epilogue
5700 ;;  ....................
5703 (define_expand "prologue"
5704   [(const_int 1)]
5705   ""
5707   mips_expand_prologue ();
5708   DONE;
5711 ;; Block any insns from being moved before this point, since the
5712 ;; profiling call to mcount can use various registers that aren't
5713 ;; saved or used to pass arguments.
5715 (define_insn "blockage"
5716   [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
5717   ""
5718   ""
5719   [(set_attr "type" "ghost")
5720    (set_attr "mode" "none")
5721    (set_attr "length" "0")])
5723 (define_expand "epilogue"
5724   [(const_int 2)]
5725   ""
5727   mips_expand_epilogue (false);
5728   DONE;
5731 (define_expand "sibcall_epilogue"
5732   [(const_int 2)]
5733   ""
5735   mips_expand_epilogue (true);
5736   DONE;
5739 ;; Trivial return.  Make it look like a normal return insn as that
5740 ;; allows jump optimizations to work better.
5742 (define_insn "return"
5743   [(return)]
5744   "mips_can_use_return_insn ()"
5745   "%*j\t$31%/"
5746   [(set_attr "type"     "jump")
5747    (set_attr "mode"     "none")])
5749 ;; Normal return.
5751 (define_insn "return_internal"
5752   [(return)
5753    (use (match_operand 0 "pmode_register_operand" ""))]
5754   ""
5755   "%*j\t%0%/"
5756   [(set_attr "type"     "jump")
5757    (set_attr "mode"     "none")])
5759 ;; This is used in compiling the unwind routines.
5760 (define_expand "eh_return"
5761   [(use (match_operand 0 "general_operand"))]
5762   ""
5764   if (GET_MODE (operands[0]) != word_mode)
5765     operands[0] = convert_to_mode (word_mode, operands[0], 0);
5766   if (TARGET_64BIT)
5767     emit_insn (gen_eh_set_lr_di (operands[0]));
5768   else
5769     emit_insn (gen_eh_set_lr_si (operands[0]));
5770   DONE;
5773 ;; Clobber the return address on the stack.  We can't expand this
5774 ;; until we know where it will be put in the stack frame.
5776 (define_insn "eh_set_lr_si"
5777   [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
5778    (clobber (match_scratch:SI 1 "=&d"))]
5779   "! TARGET_64BIT"
5780   "#")
5782 (define_insn "eh_set_lr_di"
5783   [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
5784    (clobber (match_scratch:DI 1 "=&d"))]
5785   "TARGET_64BIT"
5786   "#")
5788 (define_split
5789   [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
5790    (clobber (match_scratch 1))]
5791   "reload_completed && !TARGET_DEBUG_D_MODE"
5792   [(const_int 0)]
5794   mips_set_return_address (operands[0], operands[1]);
5795   DONE;
5798 (define_expand "exception_receiver"
5799   [(const_int 0)]
5800   "TARGET_USE_GOT"
5802   /* See the comment above load_call<mode> for details.  */
5803   emit_insn (gen_set_got_version ());
5805   /* If we have a call-clobbered $gp, restore it from its save slot.  */
5806   if (HAVE_restore_gp)
5807     emit_insn (gen_restore_gp ());
5808   DONE;
5811 (define_expand "nonlocal_goto_receiver"
5812   [(const_int 0)]
5813   "TARGET_USE_GOT"
5815   /* See the comment above load_call<mode> for details.  */
5816   emit_insn (gen_set_got_version ());
5817   DONE;
5820 ;; Restore $gp from its .cprestore stack slot.  The instruction remains
5821 ;; volatile until all uses of $28 are exposed.
5822 (define_insn_and_split "restore_gp"
5823   [(set (reg:SI 28)
5824         (unspec_volatile:SI [(const_int 0)] UNSPEC_RESTORE_GP))]
5825   "TARGET_CALL_CLOBBERED_GP"
5826   "#"
5827   "&& reload_completed"
5828   [(const_int 0)]
5830   mips_restore_gp ();
5831   DONE;
5833   [(set_attr "type"   "load")
5834    (set_attr "length" "12")])
5837 ;;  ....................
5839 ;;      FUNCTION CALLS
5841 ;;  ....................
5843 ;; Instructions to load a call address from the GOT.  The address might
5844 ;; point to a function or to a lazy binding stub.  In the latter case,
5845 ;; the stub will use the dynamic linker to resolve the function, which
5846 ;; in turn will change the GOT entry to point to the function's real
5847 ;; address.
5849 ;; This means that every call, even pure and constant ones, can
5850 ;; potentially modify the GOT entry.  And once a stub has been called,
5851 ;; we must not call it again.
5853 ;; We represent this restriction using an imaginary, fixed, call-saved
5854 ;; register called GOT_VERSION_REGNUM.  The idea is to make the register
5855 ;; live throughout the function and to change its value after every
5856 ;; potential call site.  This stops any rtx value that uses the register
5857 ;; from being computed before an earlier call.  To do this, we:
5859 ;;    - Ensure that the register is live on entry to the function,
5860 ;;      so that it is never thought to be used uninitalized.
5862 ;;    - Ensure that the register is live on exit from the function,
5863 ;;      so that it is live throughout.
5865 ;;    - Make each call (lazily-bound or not) use the current value
5866 ;;      of GOT_VERSION_REGNUM, so that updates of the register are
5867 ;;      not moved across call boundaries.
5869 ;;    - Add "ghost" definitions of the register to the beginning of
5870 ;;      blocks reached by EH and ABNORMAL_CALL edges, because those
5871 ;;      edges may involve calls that normal paths don't.  (E.g. the
5872 ;;      unwinding code that handles a non-call exception may change
5873 ;;      lazily-bound GOT entries.)  We do this by making the
5874 ;;      exception_receiver and nonlocal_goto_receiver expanders emit
5875 ;;      a set_got_version instruction.
5877 ;;    - After each call (lazily-bound or not), use a "ghost"
5878 ;;      update_got_version instruction to change the register's value.
5879 ;;      This instruction mimics the _possible_ effect of the dynamic
5880 ;;      resolver during the call and it remains live even if the call
5881 ;;      itself becomes dead.
5883 ;;    - Leave GOT_VERSION_REGNUM out of all register classes.
5884 ;;      The register is therefore not a valid register_operand
5885 ;;      and cannot be moved to or from other registers.
5886 (define_insn "load_call<mode>"
5887   [(set (match_operand:P 0 "register_operand" "=d")
5888         (unspec:P [(match_operand:P 1 "register_operand" "r")
5889                    (match_operand:P 2 "immediate_operand" "")
5890                    (reg:SI GOT_VERSION_REGNUM)] UNSPEC_LOAD_CALL))]
5891   "TARGET_USE_GOT"
5892   "<load>\t%0,%R2(%1)"
5893   [(set_attr "type" "load")
5894    (set_attr "mode" "<MODE>")
5895    (set_attr "length" "4")])
5897 (define_insn "set_got_version"
5898   [(set (reg:SI GOT_VERSION_REGNUM)
5899         (unspec_volatile:SI [(const_int 0)] UNSPEC_SET_GOT_VERSION))]
5900   "TARGET_USE_GOT"
5901   ""
5902   [(set_attr "length" "0")
5903    (set_attr "type" "ghost")])
5905 (define_insn "update_got_version"
5906   [(set (reg:SI GOT_VERSION_REGNUM)
5907         (unspec:SI [(reg:SI GOT_VERSION_REGNUM)] UNSPEC_UPDATE_GOT_VERSION))]
5908   "TARGET_USE_GOT"
5909   ""
5910   [(set_attr "length" "0")
5911    (set_attr "type" "ghost")])
5913 ;; Sibling calls.  All these patterns use jump instructions.
5915 ;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
5916 ;; addresses if a direct jump is acceptable.  Since the 'S' constraint
5917 ;; is defined in terms of call_insn_operand, the same is true of the
5918 ;; constraints.
5920 ;; When we use an indirect jump, we need a register that will be
5921 ;; preserved by the epilogue.  Since TARGET_USE_PIC_FN_ADDR_REG forces
5922 ;; us to use $25 for this purpose -- and $25 is never clobbered by the
5923 ;; epilogue -- we might as well use it for !TARGET_USE_PIC_FN_ADDR_REG
5924 ;; as well.
5926 (define_expand "sibcall"
5927   [(parallel [(call (match_operand 0 "")
5928                     (match_operand 1 ""))
5929               (use (match_operand 2 ""))        ;; next_arg_reg
5930               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
5931   "TARGET_SIBCALLS"
5933   mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true);
5934   DONE;
5937 (define_insn "sibcall_internal"
5938   [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
5939          (match_operand 1 "" ""))]
5940   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5941   { return MIPS_CALL ("j", operands, 0); }
5942   [(set_attr "type" "call")])
5944 (define_expand "sibcall_value"
5945   [(parallel [(set (match_operand 0 "")
5946                    (call (match_operand 1 "")
5947                          (match_operand 2 "")))
5948               (use (match_operand 3 ""))])]             ;; next_arg_reg
5949   "TARGET_SIBCALLS"
5951   mips_expand_call (operands[0], XEXP (operands[1], 0),
5952                     operands[2], operands[3], true);
5953   DONE;
5956 (define_insn "sibcall_value_internal"
5957   [(set (match_operand 0 "register_operand" "")
5958         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
5959               (match_operand 2 "" "")))]
5960   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5961   { return MIPS_CALL ("j", operands, 1); }
5962   [(set_attr "type" "call")])
5964 (define_insn "sibcall_value_multiple_internal"
5965   [(set (match_operand 0 "register_operand" "")
5966         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
5967               (match_operand 2 "" "")))
5968    (set (match_operand 3 "register_operand" "")
5969         (call (mem:SI (match_dup 1))
5970               (match_dup 2)))]
5971   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5972   { return MIPS_CALL ("j", operands, 1); }
5973   [(set_attr "type" "call")])
5975 (define_expand "call"
5976   [(parallel [(call (match_operand 0 "")
5977                     (match_operand 1 ""))
5978               (use (match_operand 2 ""))        ;; next_arg_reg
5979               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
5980   ""
5982   mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false);
5983   DONE;
5986 ;; This instruction directly corresponds to an assembly-language "jal".
5987 ;; There are four cases:
5989 ;;    - -mno-abicalls:
5990 ;;        Both symbolic and register destinations are OK.  The pattern
5991 ;;        always expands to a single mips instruction.
5993 ;;    - -mabicalls/-mno-explicit-relocs:
5994 ;;        Again, both symbolic and register destinations are OK.
5995 ;;        The call is treated as a multi-instruction black box.
5997 ;;    - -mabicalls/-mexplicit-relocs with n32 or n64:
5998 ;;        Only "jal $25" is allowed.  This expands to a single "jalr $25"
5999 ;;        instruction.
6001 ;;    - -mabicalls/-mexplicit-relocs with o32 or o64:
6002 ;;        Only "jal $25" is allowed.  The call is actually two instructions:
6003 ;;        "jalr $25" followed by an insn to reload $gp.
6005 ;; In the last case, we can generate the individual instructions with
6006 ;; a define_split.  There are several things to be wary of:
6008 ;;   - We can't expose the load of $gp before reload.  If we did,
6009 ;;     it might get removed as dead, but reload can introduce new
6010 ;;     uses of $gp by rematerializing constants.
6012 ;;   - We shouldn't restore $gp after calls that never return.
6013 ;;     It isn't valid to insert instructions between a noreturn
6014 ;;     call and the following barrier.
6016 ;;   - The splitter deliberately changes the liveness of $gp.  The unsplit
6017 ;;     instruction preserves $gp and so have no effect on its liveness.
6018 ;;     But once we generate the separate insns, it becomes obvious that
6019 ;;     $gp is not live on entry to the call.
6021 ;; ??? The operands[2] = insn check is a hack to make the original insn
6022 ;; available to the splitter.
6023 (define_insn_and_split "call_internal"
6024   [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
6025          (match_operand 1 "" ""))
6026    (clobber (reg:SI 31))]
6027   ""
6028   { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 0); }
6029   "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)"
6030   [(const_int 0)]
6032   emit_call_insn (gen_call_split (operands[0], operands[1]));
6033   if (!find_reg_note (operands[2], REG_NORETURN, 0))
6034     mips_restore_gp ();
6035   DONE;
6037   [(set_attr "jal" "indirect,direct")
6038    (set_attr "extended_mips16" "no,yes")])
6040 ;; A pattern for calls that must be made directly.  It is used for
6041 ;; MIPS16 calls that the linker may need to redirect to a hard-float
6042 ;; stub; the linker relies on the call relocation type to detect when
6043 ;; such redirection is needed.
6044 (define_insn "call_internal_direct"
6045   [(call (mem:SI (match_operand 0 "const_call_insn_operand"))
6046          (match_operand 1))
6047    (const_int 1)
6048    (clobber (reg:SI 31))]
6049   ""
6050   { return MIPS_CALL ("jal", operands, 0); })
6052 (define_insn "call_split"
6053   [(call (mem:SI (match_operand 0 "call_insn_operand" "cS"))
6054          (match_operand 1 "" ""))
6055    (clobber (reg:SI 31))
6056    (clobber (reg:SI 28))]
6057   "TARGET_SPLIT_CALLS"
6058   { return MIPS_CALL ("jal", operands, 0); }
6059   [(set_attr "type" "call")])
6061 (define_expand "call_value"
6062   [(parallel [(set (match_operand 0 "")
6063                    (call (match_operand 1 "")
6064                          (match_operand 2 "")))
6065               (use (match_operand 3 ""))])]             ;; next_arg_reg
6066   ""
6068   mips_expand_call (operands[0], XEXP (operands[1], 0),
6069                     operands[2], operands[3], false);
6070   DONE;
6073 ;; See comment for call_internal.
6074 (define_insn_and_split "call_value_internal"
6075   [(set (match_operand 0 "register_operand" "")
6076         (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
6077               (match_operand 2 "" "")))
6078    (clobber (reg:SI 31))]
6079   ""
6080   { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1); }
6081   "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)"
6082   [(const_int 0)]
6084   emit_call_insn (gen_call_value_split (operands[0], operands[1],
6085                                         operands[2]));
6086   if (!find_reg_note (operands[3], REG_NORETURN, 0))
6087     mips_restore_gp ();
6088   DONE;
6090   [(set_attr "jal" "indirect,direct")
6091    (set_attr "extended_mips16" "no,yes")])
6093 (define_insn "call_value_split"
6094   [(set (match_operand 0 "register_operand" "")
6095         (call (mem:SI (match_operand 1 "call_insn_operand" "cS"))
6096               (match_operand 2 "" "")))
6097    (clobber (reg:SI 31))
6098    (clobber (reg:SI 28))]
6099   "TARGET_SPLIT_CALLS"
6100   { return MIPS_CALL ("jal", operands, 1); }
6101   [(set_attr "type" "call")])
6103 ;; See call_internal_direct.
6104 (define_insn "call_value_internal_direct"
6105   [(set (match_operand 0 "register_operand")
6106         (call (mem:SI (match_operand 1 "const_call_insn_operand"))
6107               (match_operand 2)))
6108    (const_int 1)
6109    (clobber (reg:SI 31))]
6110   ""
6111   { return MIPS_CALL ("jal", operands, 1); })
6113 ;; See comment for call_internal.
6114 (define_insn_and_split "call_value_multiple_internal"
6115   [(set (match_operand 0 "register_operand" "")
6116         (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
6117               (match_operand 2 "" "")))
6118    (set (match_operand 3 "register_operand" "")
6119         (call (mem:SI (match_dup 1))
6120               (match_dup 2)))
6121    (clobber (reg:SI 31))]
6122   ""
6123   { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1); }
6124   "reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)"
6125   [(const_int 0)]
6127   emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1],
6128                                                  operands[2], operands[3]));
6129   if (!find_reg_note (operands[4], REG_NORETURN, 0))
6130     mips_restore_gp ();
6131   DONE;
6133   [(set_attr "jal" "indirect,direct")
6134    (set_attr "extended_mips16" "no,yes")])
6136 (define_insn "call_value_multiple_split"
6137   [(set (match_operand 0 "register_operand" "")
6138         (call (mem:SI (match_operand 1 "call_insn_operand" "cS"))
6139               (match_operand 2 "" "")))
6140    (set (match_operand 3 "register_operand" "")
6141         (call (mem:SI (match_dup 1))
6142               (match_dup 2)))
6143    (clobber (reg:SI 31))
6144    (clobber (reg:SI 28))]
6145   "TARGET_SPLIT_CALLS"
6146   { return MIPS_CALL ("jal", operands, 1); }
6147   [(set_attr "type" "call")])
6149 ;; Call subroutine returning any type.
6151 (define_expand "untyped_call"
6152   [(parallel [(call (match_operand 0 "")
6153                     (const_int 0))
6154               (match_operand 1 "")
6155               (match_operand 2 "")])]
6156   ""
6158   int i;
6160   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
6162   for (i = 0; i < XVECLEN (operands[2], 0); i++)
6163     {
6164       rtx set = XVECEXP (operands[2], 0, i);
6165       mips_emit_move (SET_DEST (set), SET_SRC (set));
6166     }
6168   emit_insn (gen_blockage ());
6169   DONE;
6173 ;;  ....................
6175 ;;      MISC.
6177 ;;  ....................
6181 (define_insn "prefetch"
6182   [(prefetch (match_operand:QI 0 "address_operand" "p")
6183              (match_operand 1 "const_int_operand" "n")
6184              (match_operand 2 "const_int_operand" "n"))]
6185   "ISA_HAS_PREFETCH && TARGET_EXPLICIT_RELOCS"
6187   operands[1] = mips_prefetch_cookie (operands[1], operands[2]);
6188   return "pref\t%1,%a0";
6190   [(set_attr "type" "prefetch")])
6192 (define_insn "*prefetch_indexed_<mode>"
6193   [(prefetch (plus:P (match_operand:P 0 "register_operand" "d")
6194                      (match_operand:P 1 "register_operand" "d"))
6195              (match_operand 2 "const_int_operand" "n")
6196              (match_operand 3 "const_int_operand" "n"))]
6197   "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6199   operands[2] = mips_prefetch_cookie (operands[2], operands[3]);
6200   return "prefx\t%2,%1(%0)";
6202   [(set_attr "type" "prefetchx")])
6204 (define_insn "nop"
6205   [(const_int 0)]
6206   ""
6207   "%(nop%)"
6208   [(set_attr "type"     "nop")
6209    (set_attr "mode"     "none")])
6211 ;; Like nop, but commented out when outside a .set noreorder block.
6212 (define_insn "hazard_nop"
6213   [(const_int 1)]
6214   ""
6215   {
6216     if (set_noreorder)
6217       return "nop";
6218     else
6219       return "#nop";
6220   }
6221   [(set_attr "type"     "nop")])
6223 ;; MIPS4 Conditional move instructions.
6225 (define_insn "*mov<GPR:mode>_on_<MOVECC:mode>"
6226   [(set (match_operand:GPR 0 "register_operand" "=d,d")
6227         (if_then_else:GPR
6228          (match_operator:MOVECC 4 "equality_operator"
6229                 [(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>")
6230                  (const_int 0)])
6231          (match_operand:GPR 2 "reg_or_0_operand" "dJ,0")
6232          (match_operand:GPR 3 "reg_or_0_operand" "0,dJ")))]
6233   "ISA_HAS_CONDMOVE"
6234   "@
6235     mov%T4\t%0,%z2,%1
6236     mov%t4\t%0,%z3,%1"
6237   [(set_attr "type" "condmove")
6238    (set_attr "mode" "<GPR:MODE>")])
6240 (define_insn "*mov<SCALARF:mode>_on_<MOVECC:mode>"
6241   [(set (match_operand:SCALARF 0 "register_operand" "=f,f")
6242         (if_then_else:SCALARF
6243          (match_operator:MOVECC 4 "equality_operator"
6244                 [(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>")
6245                  (const_int 0)])
6246          (match_operand:SCALARF 2 "register_operand" "f,0")
6247          (match_operand:SCALARF 3 "register_operand" "0,f")))]
6248   "ISA_HAS_CONDMOVE"
6249   "@
6250     mov%T4.<fmt>\t%0,%2,%1
6251     mov%t4.<fmt>\t%0,%3,%1"
6252   [(set_attr "type" "condmove")
6253    (set_attr "mode" "<SCALARF:MODE>")])
6255 ;; These are the main define_expand's used to make conditional moves.
6257 (define_expand "mov<mode>cc"
6258   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
6259    (set (match_operand:GPR 0 "register_operand")
6260         (if_then_else:GPR (match_dup 5)
6261                           (match_operand:GPR 2 "reg_or_0_operand")
6262                           (match_operand:GPR 3 "reg_or_0_operand")))]
6263   "ISA_HAS_CONDMOVE"
6265   mips_expand_conditional_move (operands);
6266   DONE;
6269 (define_expand "mov<mode>cc"
6270   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
6271    (set (match_operand:SCALARF 0 "register_operand")
6272         (if_then_else:SCALARF (match_dup 5)
6273                               (match_operand:SCALARF 2 "register_operand")
6274                               (match_operand:SCALARF 3 "register_operand")))]
6275   "ISA_HAS_CONDMOVE"
6277   mips_expand_conditional_move (operands);
6278   DONE;
6282 ;;  ....................
6284 ;;      mips16 inline constant tables
6286 ;;  ....................
6289 (define_insn "consttable_int"
6290   [(unspec_volatile [(match_operand 0 "consttable_operand" "")
6291                      (match_operand 1 "const_int_operand" "")]
6292                     UNSPEC_CONSTTABLE_INT)]
6293   "TARGET_MIPS16"
6295   assemble_integer (operands[0], INTVAL (operands[1]),
6296                     BITS_PER_UNIT * INTVAL (operands[1]), 1);
6297   return "";
6299   [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
6301 (define_insn "consttable_float"
6302   [(unspec_volatile [(match_operand 0 "consttable_operand" "")]
6303                     UNSPEC_CONSTTABLE_FLOAT)]
6304   "TARGET_MIPS16"
6306   REAL_VALUE_TYPE d;
6308   gcc_assert (GET_CODE (operands[0]) == CONST_DOUBLE);
6309   REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
6310   assemble_real (d, GET_MODE (operands[0]),
6311                  GET_MODE_BITSIZE (GET_MODE (operands[0])));
6312   return "";
6314   [(set (attr "length")
6315         (symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))])
6317 (define_insn "align"
6318   [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)]
6319   ""
6320   ".align\t%0"
6321   [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))])
6323 (define_split
6324   [(match_operand 0 "small_data_pattern")]
6325   "reload_completed"
6326   [(match_dup 0)]
6327   { operands[0] = mips_rewrite_small_data (operands[0]); })
6330 ;;  ....................
6332 ;;      MIPS16e Save/Restore
6334 ;;  ....................
6337 (define_insn "*mips16e_save_restore"
6338   [(match_parallel 0 ""
6339        [(set (match_operand:SI 1 "register_operand")
6340              (plus:SI (match_dup 1)
6341                       (match_operand:SI 2 "const_int_operand")))])]
6342   "operands[1] == stack_pointer_rtx
6343    && mips16e_save_restore_pattern_p (operands[0], INTVAL (operands[2]), NULL)"
6344   { return mips16e_output_save_restore (operands[0], INTVAL (operands[2])); }
6345   [(set_attr "type" "arith")
6346    (set_attr "extended_mips16" "yes")])
6348 ; Thread-Local Storage
6350 ; The TLS base pointer is accessed via "rdhwr $v1, $29".  No current
6351 ; MIPS architecture defines this register, and no current
6352 ; implementation provides it; instead, any OS which supports TLS is
6353 ; expected to trap and emulate this instruction.  rdhwr is part of the
6354 ; MIPS 32r2 specification, but we use it on any architecture because
6355 ; we expect it to be emulated.  Use .set to force the assembler to
6356 ; accept it.
6358 (define_insn "tls_get_tp_<mode>"
6359   [(set (match_operand:P 0 "register_operand" "=v")
6360         (unspec:P [(const_int 0)]
6361                   UNSPEC_TLS_GET_TP))]
6362   "HAVE_AS_TLS && !TARGET_MIPS16"
6363   ".set\tpush\;.set\tmips32r2\t\;rdhwr\t%0,$29\;.set\tpop"
6364   [(set_attr "type" "unknown")
6365    ; Since rdhwr always generates a trap for now, putting it in a delay
6366    ; slot would make the kernel's emulation of it much slower.
6367    (set_attr "can_delay" "no")
6368    (set_attr "mode" "<MODE>")])
6370 ; The MIPS Paired-Single Floating Point and MIPS-3D Instructions.
6372 (include "mips-ps-3d.md")
6374 ; The MIPS DSP Instructions.
6376 (include "mips-dsp.md")
6378 ; The MIPS DSP REV 2 Instructions.
6380 (include "mips-dspr2.md")
6382 ; MIPS fixed-point instructions.
6383 (include "mips-fixed.md")