OSDN Git Service

2007-07-04 David Ung <davidu@mips.com>
[pf3gnuchains/gcc-fork.git] / gcc / config / mips / mips.md
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
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.
9
10 ;; This file is part of GCC.
11
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 2, or (at your option)
15 ;; any later version.
16
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.
21
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GCC; see the file COPYING.  If not, write to
24 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
25 ;; Boston, MA 02110-1301, USA.
26
27 (define_constants
28   [(UNSPEC_LOAD_DF_LOW           0)
29    (UNSPEC_LOAD_DF_HIGH          1)
30    (UNSPEC_STORE_DF_HIGH         2)
31    (UNSPEC_GET_FNADDR            3)
32    (UNSPEC_BLOCKAGE              4)
33    (UNSPEC_CPRESTORE             5)
34    (UNSPEC_NONLOCAL_GOTO_RECEIVER 6)
35    (UNSPEC_EH_RETURN             7)
36    (UNSPEC_CONSTTABLE_INT        8)
37    (UNSPEC_CONSTTABLE_FLOAT      9)
38    (UNSPEC_ALIGN                14)
39    (UNSPEC_HIGH                 17)
40    (UNSPEC_LOAD_LEFT            18)
41    (UNSPEC_LOAD_RIGHT           19)
42    (UNSPEC_STORE_LEFT           20)
43    (UNSPEC_STORE_RIGHT          21)
44    (UNSPEC_LOADGP               22)
45    (UNSPEC_LOAD_CALL            23)
46    (UNSPEC_LOAD_GOT             24)
47    (UNSPEC_GP                   25)
48    (UNSPEC_MFHILO               26)
49    (UNSPEC_TLS_LDM              27)
50    (UNSPEC_TLS_GET_TP           28)
51    (UNSPEC_MFHC1                31)
52    (UNSPEC_MTHC1                32)
53
54    (UNSPEC_ADDRESS_FIRST        100)
55
56    (FAKE_CALL_REGNO             79)
57
58    ;; For MIPS Paired-Singled Floating Point Instructions.
59
60    (UNSPEC_MOVE_TF_PS           200)
61    (UNSPEC_C                    201)
62
63    ;; MIPS64/MIPS32R2 alnv.ps
64    (UNSPEC_ALNV_PS              202)
65
66    ;; MIPS-3D instructions
67    (UNSPEC_CABS                 203)
68
69    (UNSPEC_ADDR_PS              204)
70    (UNSPEC_CVT_PW_PS            205)
71    (UNSPEC_CVT_PS_PW            206)
72    (UNSPEC_MULR_PS              207)
73    (UNSPEC_ABS_PS               208)
74
75    (UNSPEC_RSQRT1               209)
76    (UNSPEC_RSQRT2               210)
77    (UNSPEC_RECIP1               211)
78    (UNSPEC_RECIP2               212)
79    (UNSPEC_SINGLE_CC            213)
80    (UNSPEC_SCC                  214)
81
82    ;; MIPS DSP ASE Revision 0.98 3/24/2005
83    (UNSPEC_ADDQ                 300)
84    (UNSPEC_ADDQ_S               301)
85    (UNSPEC_SUBQ                 302)
86    (UNSPEC_SUBQ_S               303)
87    (UNSPEC_ADDSC                304)
88    (UNSPEC_ADDWC                305)
89    (UNSPEC_MODSUB               306)
90    (UNSPEC_RADDU_W_QB           307)
91    (UNSPEC_ABSQ_S               308)
92    (UNSPEC_PRECRQ_QB_PH         309)
93    (UNSPEC_PRECRQ_PH_W          310)
94    (UNSPEC_PRECRQ_RS_PH_W       311)
95    (UNSPEC_PRECRQU_S_QB_PH      312)
96    (UNSPEC_PRECEQ_W_PHL         313)
97    (UNSPEC_PRECEQ_W_PHR         314)
98    (UNSPEC_PRECEQU_PH_QBL       315)
99    (UNSPEC_PRECEQU_PH_QBR       316)
100    (UNSPEC_PRECEQU_PH_QBLA      317)
101    (UNSPEC_PRECEQU_PH_QBRA      318)
102    (UNSPEC_PRECEU_PH_QBL        319)
103    (UNSPEC_PRECEU_PH_QBR        320)
104    (UNSPEC_PRECEU_PH_QBLA       321)
105    (UNSPEC_PRECEU_PH_QBRA       322)
106    (UNSPEC_SHLL                 323)
107    (UNSPEC_SHLL_S               324)
108    (UNSPEC_SHRL_QB              325)
109    (UNSPEC_SHRA_PH              326)
110    (UNSPEC_SHRA_R               327)
111    (UNSPEC_MULEU_S_PH_QBL       328)
112    (UNSPEC_MULEU_S_PH_QBR       329)
113    (UNSPEC_MULQ_RS_PH           330)
114    (UNSPEC_MULEQ_S_W_PHL        331)
115    (UNSPEC_MULEQ_S_W_PHR        332)
116    (UNSPEC_DPAU_H_QBL           333)
117    (UNSPEC_DPAU_H_QBR           334)
118    (UNSPEC_DPSU_H_QBL           335)
119    (UNSPEC_DPSU_H_QBR           336)
120    (UNSPEC_DPAQ_S_W_PH          337)
121    (UNSPEC_DPSQ_S_W_PH          338)
122    (UNSPEC_MULSAQ_S_W_PH        339)
123    (UNSPEC_DPAQ_SA_L_W          340)
124    (UNSPEC_DPSQ_SA_L_W          341)
125    (UNSPEC_MAQ_S_W_PHL          342)
126    (UNSPEC_MAQ_S_W_PHR          343)
127    (UNSPEC_MAQ_SA_W_PHL         344)
128    (UNSPEC_MAQ_SA_W_PHR         345)
129    (UNSPEC_BITREV               346)
130    (UNSPEC_INSV                 347)
131    (UNSPEC_REPL_QB              348)
132    (UNSPEC_REPL_PH              349)
133    (UNSPEC_CMP_EQ               350)
134    (UNSPEC_CMP_LT               351)
135    (UNSPEC_CMP_LE               352)
136    (UNSPEC_CMPGU_EQ_QB          353)
137    (UNSPEC_CMPGU_LT_QB          354)
138    (UNSPEC_CMPGU_LE_QB          355)
139    (UNSPEC_PICK                 356)
140    (UNSPEC_PACKRL_PH            357)
141    (UNSPEC_EXTR_W               358)
142    (UNSPEC_EXTR_R_W             359)
143    (UNSPEC_EXTR_RS_W            360)
144    (UNSPEC_EXTR_S_H             361)
145    (UNSPEC_EXTP                 362)
146    (UNSPEC_EXTPDP               363)
147    (UNSPEC_SHILO                364)
148    (UNSPEC_MTHLIP               365)
149    (UNSPEC_WRDSP                366)
150    (UNSPEC_RDDSP                367)
151
152    ;; MIPS DSP ASE REV 2 Revision 0.02 11/24/2006
153    (UNSPEC_ABSQ_S_QB            400)
154    (UNSPEC_ADDU_PH              401)
155    (UNSPEC_ADDU_S_PH            402)
156    (UNSPEC_ADDUH_QB             403)
157    (UNSPEC_ADDUH_R_QB           404)
158    (UNSPEC_APPEND               405)
159    (UNSPEC_BALIGN               406)
160    (UNSPEC_CMPGDU_EQ_QB         407)
161    (UNSPEC_CMPGDU_LT_QB         408)
162    (UNSPEC_CMPGDU_LE_QB         409)
163    (UNSPEC_DPA_W_PH             410)
164    (UNSPEC_DPS_W_PH             411)
165    (UNSPEC_MADD                 412)
166    (UNSPEC_MADDU                413)
167    (UNSPEC_MSUB                 414)
168    (UNSPEC_MSUBU                415)
169    (UNSPEC_MUL_PH               416)
170    (UNSPEC_MUL_S_PH             417)
171    (UNSPEC_MULQ_RS_W            418)
172    (UNSPEC_MULQ_S_PH            419)
173    (UNSPEC_MULQ_S_W             420)
174    (UNSPEC_MULSA_W_PH           421)
175    (UNSPEC_MULT                 422)
176    (UNSPEC_MULTU                423)
177    (UNSPEC_PRECR_QB_PH          424)
178    (UNSPEC_PRECR_SRA_PH_W       425)
179    (UNSPEC_PRECR_SRA_R_PH_W     426)
180    (UNSPEC_PREPEND              427)
181    (UNSPEC_SHRA_QB              428)
182    (UNSPEC_SHRA_R_QB            429)
183    (UNSPEC_SHRL_PH              430)
184    (UNSPEC_SUBU_PH              431)
185    (UNSPEC_SUBU_S_PH            432)
186    (UNSPEC_SUBUH_QB             433)
187    (UNSPEC_SUBUH_R_QB           434)
188    (UNSPEC_ADDQH_PH             435)
189    (UNSPEC_ADDQH_R_PH           436)
190    (UNSPEC_ADDQH_W              437)
191    (UNSPEC_ADDQH_R_W            438)
192    (UNSPEC_SUBQH_PH             439)
193    (UNSPEC_SUBQH_R_PH           440)
194    (UNSPEC_SUBQH_W              441)
195    (UNSPEC_SUBQH_R_W            442)
196    (UNSPEC_DPAX_W_PH            443)
197    (UNSPEC_DPSX_W_PH            444)
198    (UNSPEC_DPAQX_S_W_PH         445)
199    (UNSPEC_DPAQX_SA_W_PH        446)
200    (UNSPEC_DPSQX_S_W_PH         447)
201    (UNSPEC_DPSQX_SA_W_PH        448)
202   ]
203 )
204
205 (include "predicates.md")
206 (include "constraints.md")
207 \f
208 ;; ....................
209 ;;
210 ;;      Attributes
211 ;;
212 ;; ....................
213
214 (define_attr "got" "unset,xgot_high,load"
215   (const_string "unset"))
216
217 ;; For jal instructions, this attribute is DIRECT when the target address
218 ;; is symbolic and INDIRECT when it is a register.
219 (define_attr "jal" "unset,direct,indirect"
220   (const_string "unset"))
221
222 ;; This attribute is YES if the instruction is a jal macro (not a
223 ;; real jal instruction).
224 ;;
225 ;; jal is always a macro for TARGET_CALL_CLOBBERED_GP because it includes
226 ;; an instruction to restore $gp.  Direct jals are also macros for
227 ;; flag_pic && !TARGET_ABSOLUTE_ABICALLS because they first load
228 ;; the target address into a register.
229 (define_attr "jal_macro" "no,yes"
230   (cond [(eq_attr "jal" "direct")
231          (symbol_ref "TARGET_CALL_CLOBBERED_GP
232                       || (flag_pic && !TARGET_ABSOLUTE_ABICALLS)")
233          (eq_attr "jal" "indirect")
234          (symbol_ref "TARGET_CALL_CLOBBERED_GP")]
235         (const_string "no")))
236
237 ;; Classification of each insn.
238 ;; branch       conditional branch
239 ;; jump         unconditional jump
240 ;; call         unconditional call
241 ;; load         load instruction(s)
242 ;; fpload       floating point load
243 ;; fpidxload    floating point indexed load
244 ;; store        store instruction(s)
245 ;; fpstore      floating point store
246 ;; fpidxstore   floating point indexed store
247 ;; prefetch     memory prefetch (register + offset)
248 ;; prefetchx    memory indexed prefetch (register + register)
249 ;; condmove     conditional moves
250 ;; mfc          transfer from coprocessor
251 ;; mtc          transfer to coprocessor
252 ;; mthilo       transfer to hi/lo registers
253 ;; mfhilo       transfer from hi/lo registers
254 ;; const        load constant
255 ;; arith        integer arithmetic instructions
256 ;; logical      integer logical instructions
257 ;; shift        integer shift instructions
258 ;; slt          set less than instructions
259 ;; signext      sign extend instuctions
260 ;; clz          the clz and clo instructions
261 ;; trap         trap if instructions
262 ;; imul         integer multiply 2 operands
263 ;; imul3        integer multiply 3 operands
264 ;; imadd        integer multiply-add
265 ;; idiv         integer divide
266 ;; move         integer register move ({,D}ADD{,U} with rt = 0)
267 ;; fmove        floating point register move
268 ;; fadd         floating point add/subtract
269 ;; fmul         floating point multiply
270 ;; fmadd        floating point multiply-add
271 ;; fdiv         floating point divide
272 ;; frdiv        floating point reciprocal divide
273 ;; frdiv1       floating point reciprocal divide step 1
274 ;; frdiv2       floating point reciprocal divide step 2
275 ;; fabs         floating point absolute value
276 ;; fneg         floating point negation
277 ;; fcmp         floating point compare
278 ;; fcvt         floating point convert
279 ;; fsqrt        floating point square root
280 ;; frsqrt       floating point reciprocal square root
281 ;; frsqrt1      floating point reciprocal square root step1
282 ;; frsqrt2      floating point reciprocal square root step2
283 ;; multi        multiword sequence (or user asm statements)
284 ;; nop          no operation
285 (define_attr "type"
286   "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"
287   (cond [(eq_attr "jal" "!unset") (const_string "call")
288          (eq_attr "got" "load") (const_string "load")]
289         (const_string "unknown")))
290
291 ;; Main data type used by the insn
292 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW"
293   (const_string "unknown"))
294
295 ;; Mode for conversion types (fcvt)
296 ;; I2S          integer to float single (SI/DI to SF)
297 ;; I2D          integer to float double (SI/DI to DF)
298 ;; S2I          float to integer (SF to SI/DI)
299 ;; D2I          float to integer (DF to SI/DI)
300 ;; D2S          double to float single
301 ;; S2D          float single to double
302
303 (define_attr "cnv_mode" "unknown,I2S,I2D,S2I,D2I,D2S,S2D" 
304   (const_string "unknown"))
305
306 ;; Is this an extended instruction in mips16 mode?
307 (define_attr "extended_mips16" "no,yes"
308   (const_string "no"))
309
310 ;; Length of instruction in bytes.
311 (define_attr "length" ""
312    (cond [;; Direct branch instructions have a range of [-0x40000,0x3fffc].
313           ;; If a branch is outside this range, we have a choice of two
314           ;; sequences.  For PIC, an out-of-range branch like:
315           ;;
316           ;;    bne     r1,r2,target
317           ;;    dslot
318           ;;
319           ;; becomes the equivalent of:
320           ;;
321           ;;    beq     r1,r2,1f
322           ;;    dslot
323           ;;    la      $at,target
324           ;;    jr      $at
325           ;;    nop
326           ;; 1:
327           ;;
328           ;; where the load address can be up to three instructions long
329           ;; (lw, nop, addiu).
330           ;;
331           ;; The non-PIC case is similar except that we use a direct
332           ;; jump instead of an la/jr pair.  Since the target of this
333           ;; jump is an absolute 28-bit bit address (the other bits
334           ;; coming from the address of the delay slot) this form cannot
335           ;; cross a 256MB boundary.  We could provide the option of
336           ;; using la/jr in this case too, but we do not do so at
337           ;; present.
338           ;;
339           ;; Note that this value does not account for the delay slot
340           ;; instruction, whose length is added separately.  If the RTL
341           ;; pattern has no explicit delay slot, mips_adjust_insn_length
342           ;; will add the length of the implicit nop.  The values for
343           ;; forward and backward branches will be different as well.
344           (eq_attr "type" "branch")
345           (cond [(and (le (minus (match_dup 1) (pc)) (const_int 131064))
346                       (le (minus (pc) (match_dup 1)) (const_int 131068)))
347                   (const_int 4)
348                  (ne (symbol_ref "flag_pic") (const_int 0))
349                  (const_int 24)
350                  ] (const_int 12))
351
352           (eq_attr "got" "load")
353           (const_int 4)
354           (eq_attr "got" "xgot_high")
355           (const_int 8)
356
357           (eq_attr "type" "const")
358           (symbol_ref "mips_const_insns (operands[1]) * 4")
359           (eq_attr "type" "load,fpload")
360           (symbol_ref "mips_fetch_insns (operands[1]) * 4")
361           (eq_attr "type" "store,fpstore")
362           (symbol_ref "mips_fetch_insns (operands[0]) * 4")
363
364           ;; In the worst case, a call macro will take 8 instructions:
365           ;;
366           ;;     lui $25,%call_hi(FOO)
367           ;;     addu $25,$25,$28
368           ;;     lw $25,%call_lo(FOO)($25)
369           ;;     nop
370           ;;     jalr $25
371           ;;     nop
372           ;;     lw $gp,X($sp)
373           ;;     nop
374           (eq_attr "jal_macro" "yes")
375           (const_int 32)
376
377           (and (eq_attr "extended_mips16" "yes")
378                (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
379           (const_int 8)
380
381           ;; Various VR4120 errata require a nop to be inserted after a macc
382           ;; instruction.  The assembler does this for us, so account for
383           ;; the worst-case length here.
384           (and (eq_attr "type" "imadd")
385                (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0)))
386           (const_int 8)
387
388           ;; VR4120 errata MD(4): if there are consecutive dmult instructions,
389           ;; the result of the second one is missed.  The assembler should work
390           ;; around this by inserting a nop after the first dmult.
391           (and (eq_attr "type" "imul,imul3")
392                (and (eq_attr "mode" "DI")
393                     (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0))))
394           (const_int 8)
395
396           (eq_attr "type" "idiv")
397           (symbol_ref "mips_idiv_insns () * 4")
398           ] (const_int 4)))
399
400 ;; Attribute describing the processor.  This attribute must match exactly
401 ;; with the processor_type enumeration in mips.h.
402 (define_attr "cpu"
403   "r3000,4kc,4kp,5kc,5kf,20kc,24kc,24kf2_1,24kf1_1,74kc,74kf2_1,74kf1_1,74kf3_2,m4k,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sb1a,sr71000"
404   (const (symbol_ref "mips_tune")))
405
406 ;; The type of hardware hazard associated with this instruction.
407 ;; DELAY means that the next instruction cannot read the result
408 ;; of this one.  HILO means that the next two instructions cannot
409 ;; write to HI or LO.
410 (define_attr "hazard" "none,delay,hilo"
411   (cond [(and (eq_attr "type" "load,fpload,fpidxload")
412               (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int 0)))
413          (const_string "delay")
414
415          (and (eq_attr "type" "mfc,mtc")
416               (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0)))
417          (const_string "delay")
418
419          (and (eq_attr "type" "fcmp")
420               (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0)))
421          (const_string "delay")
422
423          ;; The r4000 multiplication patterns include an mflo instruction.
424          (and (eq_attr "type" "imul")
425               (ne (symbol_ref "TARGET_FIX_R4000") (const_int 0)))
426          (const_string "hilo")
427
428          (and (eq_attr "type" "mfhilo")
429               (eq (symbol_ref "ISA_HAS_HILO_INTERLOCKS") (const_int 0)))
430          (const_string "hilo")]
431         (const_string "none")))
432
433 ;; Is it a single instruction?
434 (define_attr "single_insn" "no,yes"
435   (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)"))
436
437 ;; Can the instruction be put into a delay slot?
438 (define_attr "can_delay" "no,yes"
439   (if_then_else (and (eq_attr "type" "!branch,call,jump")
440                      (and (eq_attr "hazard" "none")
441                           (eq_attr "single_insn" "yes")))
442                 (const_string "yes")
443                 (const_string "no")))
444
445 ;; Attribute defining whether or not we can use the branch-likely instructions
446 (define_attr "branch_likely" "no,yes"
447   (const
448    (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
449                  (const_string "yes")
450                  (const_string "no"))))
451
452 ;; True if an instruction might assign to hi or lo when reloaded.
453 ;; This is used by the TUNE_MACC_CHAINS code.
454 (define_attr "may_clobber_hilo" "no,yes"
455   (if_then_else (eq_attr "type" "imul,imul3,imadd,idiv,mthilo")
456                 (const_string "yes")
457                 (const_string "no")))
458
459 ;; Describe a user's asm statement.
460 (define_asm_attributes
461   [(set_attr "type" "multi")
462    (set_attr "can_delay" "no")])
463 \f
464 ;; This mode macro allows 32-bit and 64-bit GPR patterns to be generated
465 ;; from the same template.
466 (define_mode_macro GPR [SI (DI "TARGET_64BIT")])
467
468 ;; This mode macro allows :P to be used for patterns that operate on
469 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
470 (define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
471
472 ;; This mode macro allows :MOVECC to be used anywhere that a
473 ;; conditional-move-type condition is needed.
474 (define_mode_macro MOVECC [SI (DI "TARGET_64BIT") (CC "TARGET_HARD_FLOAT")])
475
476 ;; This mode macro allows the QI and HI extension patterns to be defined from
477 ;; the same template.
478 (define_mode_macro SHORT [QI HI])
479
480 ;; This mode macro allows :ANYF to be used wherever a scalar or vector
481 ;; floating-point mode is allowed.
482 (define_mode_macro ANYF [(SF "TARGET_HARD_FLOAT")
483                          (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
484                          (V2SF "TARGET_PAIRED_SINGLE_FLOAT")])
485
486 ;; Like ANYF, but only applies to scalar modes.
487 (define_mode_macro SCALARF [(SF "TARGET_HARD_FLOAT")
488                             (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")])
489
490 ;; In GPR templates, a string like "<d>subu" will expand to "subu" in the
491 ;; 32-bit version and "dsubu" in the 64-bit version.
492 (define_mode_attr d [(SI "") (DI "d")])
493
494 ;; This attribute gives the length suffix for a sign- or zero-extension
495 ;; instruction.
496 (define_mode_attr size [(QI "b") (HI "h")])
497
498 ;; This attributes gives the mode mask of a SHORT.
499 (define_mode_attr mask [(QI "0x00ff") (HI "0xffff")])
500
501 ;; Mode attributes for GPR loads and stores.
502 (define_mode_attr load [(SI "lw") (DI "ld")])
503 (define_mode_attr store [(SI "sw") (DI "sd")])
504
505 ;; Similarly for MIPS IV indexed FPR loads and stores.
506 (define_mode_attr loadx [(SF "lwxc1") (DF "ldxc1") (V2SF "ldxc1")])
507 (define_mode_attr storex [(SF "swxc1") (DF "sdxc1") (V2SF "sdxc1")])
508
509 ;; The unextended ranges of the MIPS16 addiu and daddiu instructions
510 ;; are different.  Some forms of unextended addiu have an 8-bit immediate
511 ;; field but the equivalent daddiu has only a 5-bit field.
512 (define_mode_attr si8_di5 [(SI "8") (DI "5")])
513
514 ;; This attribute gives the best constraint to use for registers of
515 ;; a given mode.
516 (define_mode_attr reg [(SI "d") (DI "d") (CC "z")])
517
518 ;; This attribute gives the format suffix for floating-point operations.
519 (define_mode_attr fmt [(SF "s") (DF "d") (V2SF "ps")])
520
521 ;; This attribute gives the upper-case mode name for one unit of a
522 ;; floating-point mode.
523 (define_mode_attr UNITMODE [(SF "SF") (DF "DF") (V2SF "SF")])
524
525 ;; This attribute works around the early SB-1 rev2 core "F2" erratum:
526 ;;
527 ;; In certain cases, div.s and div.ps may have a rounding error
528 ;; and/or wrong inexact flag.
529 ;;
530 ;; Therefore, we only allow div.s if not working around SB-1 rev2
531 ;; errata or if a slight loss of precision is OK.
532 (define_mode_attr divide_condition
533   [DF (SF "!TARGET_FIX_SB1 || flag_unsafe_math_optimizations")
534    (V2SF "TARGET_SB1 && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)")])
535
536 ; This attribute gives the condition for which sqrt instructions exist.
537 (define_mode_attr sqrt_condition
538   [(SF "!ISA_MIPS1") (DF "!ISA_MIPS1") (V2SF "TARGET_SB1")])
539
540 ; This attribute gives the condition for which recip and rsqrt instructions
541 ; exist.
542 (define_mode_attr recip_condition
543   [(SF "ISA_HAS_FP4") (DF "ISA_HAS_FP4") (V2SF "TARGET_SB1")])
544
545 ;; This code macro allows all branch instructions to be generated from
546 ;; a single define_expand template.
547 (define_code_macro any_cond [unordered ordered unlt unge uneq ltgt unle ungt
548                              eq ne gt ge lt le gtu geu ltu leu])
549
550 ;; This code macro allows signed and unsigned widening multiplications
551 ;; to use the same template.
552 (define_code_macro any_extend [sign_extend zero_extend])
553
554 ;; This code macro allows the three shift instructions to be generated
555 ;; from the same template.
556 (define_code_macro any_shift [ashift ashiftrt lshiftrt])
557
558 ;; This code macro allows all native floating-point comparisons to be
559 ;; generated from the same template.
560 (define_code_macro fcond [unordered uneq unlt unle eq lt le])
561
562 ;; This code macro is used for comparisons that can be implemented
563 ;; by swapping the operands.
564 (define_code_macro swapped_fcond [ge gt unge ungt])
565
566 ;; <u> expands to an empty string when doing a signed operation and
567 ;; "u" when doing an unsigned operation.
568 (define_code_attr u [(sign_extend "") (zero_extend "u")])
569
570 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
571 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
572
573 ;; <optab> expands to the name of the optab for a particular code.
574 (define_code_attr optab [(ashift "ashl")
575                          (ashiftrt "ashr")
576                          (lshiftrt "lshr")])
577
578 ;; <insn> expands to the name of the insn that implements a particular code.
579 (define_code_attr insn [(ashift "sll")
580                         (ashiftrt "sra")
581                         (lshiftrt "srl")])
582
583 ;; <fcond> is the c.cond.fmt condition associated with a particular code.
584 (define_code_attr fcond [(unordered "un")
585                          (uneq "ueq")
586                          (unlt "ult")
587                          (unle "ule")
588                          (eq "eq")
589                          (lt "lt")
590                          (le "le")])
591
592 ;; Similar, but for swapped conditions.
593 (define_code_attr swapped_fcond [(ge "le")
594                                  (gt "lt")
595                                  (unge "ule")
596                                  (ungt "ult")])
597 \f
598 ;; .........................
599 ;;
600 ;;      Branch, call and jump delay slots
601 ;;
602 ;; .........................
603
604 (define_delay (and (eq_attr "type" "branch")
605                    (eq (symbol_ref "TARGET_MIPS16") (const_int 0)))
606   [(eq_attr "can_delay" "yes")
607    (nil)
608    (and (eq_attr "branch_likely" "yes")
609         (eq_attr "can_delay" "yes"))])
610
611 (define_delay (eq_attr "type" "jump")
612   [(eq_attr "can_delay" "yes")
613    (nil)
614    (nil)])
615
616 (define_delay (and (eq_attr "type" "call")
617                    (eq_attr "jal_macro" "no"))
618   [(eq_attr "can_delay" "yes")
619    (nil)
620    (nil)])
621 \f
622 ;; Pipeline descriptions.
623 ;;
624 ;; generic.md provides a fallback for processors without a specific
625 ;; pipeline description.  It is derived from the old define_function_unit
626 ;; version and uses the "alu" and "imuldiv" units declared below.
627 ;;
628 ;; Some of the processor-specific files are also derived from old
629 ;; define_function_unit descriptions and simply override the parts of
630 ;; generic.md that don't apply.  The other processor-specific files
631 ;; are self-contained.
632 (define_automaton "alu,imuldiv")
633
634 (define_cpu_unit "alu" "alu")
635 (define_cpu_unit "imuldiv" "imuldiv")
636
637 (include "4k.md")
638 (include "5k.md")
639 (include "24k.md")
640 (include "74k.md")
641 (include "3000.md")
642 (include "4000.md")
643 (include "4100.md")
644 (include "4130.md")
645 (include "4300.md")
646 (include "4600.md")
647 (include "5000.md")
648 (include "5400.md")
649 (include "5500.md")
650 (include "6000.md")
651 (include "7000.md")
652 (include "9000.md")
653 (include "sb1.md")
654 (include "sr71k.md")
655 (include "generic.md")
656 \f
657 ;;
658 ;;  ....................
659 ;;
660 ;;      CONDITIONAL TRAPS
661 ;;
662 ;;  ....................
663 ;;
664
665 (define_insn "trap"
666   [(trap_if (const_int 1) (const_int 0))]
667   ""
668 {
669   if (ISA_HAS_COND_TRAP)
670     return "teq\t$0,$0";
671   else if (TARGET_MIPS16)
672     return "break 0";
673   else
674     return "break";
675 }
676   [(set_attr "type" "trap")])
677
678 (define_expand "conditional_trap"
679   [(trap_if (match_operator 0 "comparison_operator"
680                             [(match_dup 2) (match_dup 3)])
681             (match_operand 1 "const_int_operand"))]
682   "ISA_HAS_COND_TRAP"
683 {
684   if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) == MODE_INT
685       && operands[1] == const0_rtx)
686     {
687       mips_gen_conditional_trap (operands);
688       DONE;
689     }
690   else
691     FAIL;
692 })
693
694 (define_insn "*conditional_trap<mode>"
695   [(trap_if (match_operator:GPR 0 "trap_comparison_operator"
696                                 [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
697                                  (match_operand:GPR 2 "arith_operand" "dI")])
698             (const_int 0))]
699   "ISA_HAS_COND_TRAP"
700   "t%C0\t%z1,%2"
701   [(set_attr "type" "trap")])
702 \f
703 ;;
704 ;;  ....................
705 ;;
706 ;;      ADDITION
707 ;;
708 ;;  ....................
709 ;;
710
711 (define_insn "add<mode>3"
712   [(set (match_operand:ANYF 0 "register_operand" "=f")
713         (plus:ANYF (match_operand:ANYF 1 "register_operand" "f")
714                    (match_operand:ANYF 2 "register_operand" "f")))]
715   ""
716   "add.<fmt>\t%0,%1,%2"
717   [(set_attr "type" "fadd")
718    (set_attr "mode" "<UNITMODE>")])
719
720 (define_expand "add<mode>3"
721   [(set (match_operand:GPR 0 "register_operand")
722         (plus:GPR (match_operand:GPR 1 "register_operand")
723                   (match_operand:GPR 2 "arith_operand")))]
724   "")
725
726 (define_insn "*add<mode>3"
727   [(set (match_operand:GPR 0 "register_operand" "=d,d")
728         (plus:GPR (match_operand:GPR 1 "register_operand" "d,d")
729                   (match_operand:GPR 2 "arith_operand" "d,Q")))]
730   "!TARGET_MIPS16"
731   "@
732     <d>addu\t%0,%1,%2
733     <d>addiu\t%0,%1,%2"
734   [(set_attr "type" "arith")
735    (set_attr "mode" "<MODE>")])
736
737 ;; We need to recognize MIPS16 stack pointer additions explicitly, since
738 ;; we don't have a constraint for $sp.  These insns will be generated by
739 ;; the save_restore_insns functions.
740
741 (define_insn "*add<mode>3_sp1"
742   [(set (reg:GPR 29)
743         (plus:GPR (reg:GPR 29)
744                   (match_operand:GPR 0 "const_arith_operand" "")))]
745   "TARGET_MIPS16"
746   "<d>addiu\t%$,%$,%0"
747   [(set_attr "type" "arith")
748    (set_attr "mode" "<MODE>")
749    (set (attr "length") (if_then_else (match_operand 0 "m16_simm8_8")
750                                       (const_int 4)
751                                       (const_int 8)))])
752
753 (define_insn "*add<mode>3_sp2"
754   [(set (match_operand:GPR 0 "register_operand" "=d")
755         (plus:GPR (reg:GPR 29)
756                   (match_operand:GPR 1 "const_arith_operand" "")))]
757   "TARGET_MIPS16"
758   "<d>addiu\t%0,%$,%1"
759   [(set_attr "type" "arith")
760    (set_attr "mode" "<MODE>")
761    (set (attr "length") (if_then_else (match_operand 1 "m16_uimm<si8_di5>_4")
762                                       (const_int 4)
763                                       (const_int 8)))])
764
765 (define_insn "*add<mode>3_mips16"
766   [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
767         (plus:GPR (match_operand:GPR 1 "register_operand" "0,d,d")
768                   (match_operand:GPR 2 "arith_operand" "Q,O,d")))]
769   "TARGET_MIPS16"
770   "@
771     <d>addiu\t%0,%2
772     <d>addiu\t%0,%1,%2
773     <d>addu\t%0,%1,%2"
774   [(set_attr "type" "arith")
775    (set_attr "mode" "<MODE>")
776    (set_attr_alternative "length"
777                 [(if_then_else (match_operand 2 "m16_simm<si8_di5>_1")
778                                (const_int 4)
779                                (const_int 8))
780                  (if_then_else (match_operand 2 "m16_simm4_1")
781                                (const_int 4)
782                                (const_int 8))
783                  (const_int 4)])])
784
785
786 ;; On the mips16, we can sometimes split an add of a constant which is
787 ;; a 4 byte instruction into two adds which are both 2 byte
788 ;; instructions.  There are two cases: one where we are adding a
789 ;; constant plus a register to another register, and one where we are
790 ;; simply adding a constant to a register.
791
792 (define_split
793   [(set (match_operand:SI 0 "register_operand")
794         (plus:SI (match_dup 0)
795                  (match_operand:SI 1 "const_int_operand")))]
796   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
797    && REG_P (operands[0])
798    && M16_REG_P (REGNO (operands[0]))
799    && GET_CODE (operands[1]) == CONST_INT
800    && ((INTVAL (operands[1]) > 0x7f
801         && INTVAL (operands[1]) <= 0x7f + 0x7f)
802        || (INTVAL (operands[1]) < - 0x80
803            && INTVAL (operands[1]) >= - 0x80 - 0x80))"
804   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
805    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
806 {
807   HOST_WIDE_INT val = INTVAL (operands[1]);
808
809   if (val >= 0)
810     {
811       operands[1] = GEN_INT (0x7f);
812       operands[2] = GEN_INT (val - 0x7f);
813     }
814   else
815     {
816       operands[1] = GEN_INT (- 0x80);
817       operands[2] = GEN_INT (val + 0x80);
818     }
819 })
820
821 (define_split
822   [(set (match_operand:SI 0 "register_operand")
823         (plus:SI (match_operand:SI 1 "register_operand")
824                  (match_operand:SI 2 "const_int_operand")))]
825   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
826    && REG_P (operands[0])
827    && M16_REG_P (REGNO (operands[0]))
828    && REG_P (operands[1])
829    && M16_REG_P (REGNO (operands[1]))
830    && REGNO (operands[0]) != REGNO (operands[1])
831    && GET_CODE (operands[2]) == CONST_INT
832    && ((INTVAL (operands[2]) > 0x7
833         && INTVAL (operands[2]) <= 0x7 + 0x7f)
834        || (INTVAL (operands[2]) < - 0x8
835            && INTVAL (operands[2]) >= - 0x8 - 0x80))"
836   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
837    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
838 {
839   HOST_WIDE_INT val = INTVAL (operands[2]);
840
841   if (val >= 0)
842     {
843       operands[2] = GEN_INT (0x7);
844       operands[3] = GEN_INT (val - 0x7);
845     }
846   else
847     {
848       operands[2] = GEN_INT (- 0x8);
849       operands[3] = GEN_INT (val + 0x8);
850     }
851 })
852
853 (define_split
854   [(set (match_operand:DI 0 "register_operand")
855         (plus:DI (match_dup 0)
856                  (match_operand:DI 1 "const_int_operand")))]
857   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
858    && REG_P (operands[0])
859    && M16_REG_P (REGNO (operands[0]))
860    && GET_CODE (operands[1]) == CONST_INT
861    && ((INTVAL (operands[1]) > 0xf
862         && INTVAL (operands[1]) <= 0xf + 0xf)
863        || (INTVAL (operands[1]) < - 0x10
864            && INTVAL (operands[1]) >= - 0x10 - 0x10))"
865   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
866    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
867 {
868   HOST_WIDE_INT val = INTVAL (operands[1]);
869
870   if (val >= 0)
871     {
872       operands[1] = GEN_INT (0xf);
873       operands[2] = GEN_INT (val - 0xf);
874     }
875   else
876     {
877       operands[1] = GEN_INT (- 0x10);
878       operands[2] = GEN_INT (val + 0x10);
879     }
880 })
881
882 (define_split
883   [(set (match_operand:DI 0 "register_operand")
884         (plus:DI (match_operand:DI 1 "register_operand")
885                  (match_operand:DI 2 "const_int_operand")))]
886   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
887    && REG_P (operands[0])
888    && M16_REG_P (REGNO (operands[0]))
889    && REG_P (operands[1])
890    && M16_REG_P (REGNO (operands[1]))
891    && REGNO (operands[0]) != REGNO (operands[1])
892    && GET_CODE (operands[2]) == CONST_INT
893    && ((INTVAL (operands[2]) > 0x7
894         && INTVAL (operands[2]) <= 0x7 + 0xf)
895        || (INTVAL (operands[2]) < - 0x8
896            && INTVAL (operands[2]) >= - 0x8 - 0x10))"
897   [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
898    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
899 {
900   HOST_WIDE_INT val = INTVAL (operands[2]);
901
902   if (val >= 0)
903     {
904       operands[2] = GEN_INT (0x7);
905       operands[3] = GEN_INT (val - 0x7);
906     }
907   else
908     {
909       operands[2] = GEN_INT (- 0x8);
910       operands[3] = GEN_INT (val + 0x8);
911     }
912 })
913
914 (define_insn "*addsi3_extended"
915   [(set (match_operand:DI 0 "register_operand" "=d,d")
916         (sign_extend:DI
917              (plus:SI (match_operand:SI 1 "register_operand" "d,d")
918                       (match_operand:SI 2 "arith_operand" "d,Q"))))]
919   "TARGET_64BIT && !TARGET_MIPS16"
920   "@
921     addu\t%0,%1,%2
922     addiu\t%0,%1,%2"
923   [(set_attr "type" "arith")
924    (set_attr "mode" "SI")])
925
926 ;; Split this insn so that the addiu splitters can have a crack at it.
927 ;; Use a conservative length estimate until the split.
928 (define_insn_and_split "*addsi3_extended_mips16"
929   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
930         (sign_extend:DI
931              (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
932                       (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
933   "TARGET_64BIT && TARGET_MIPS16"
934   "#"
935   "&& reload_completed"
936   [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))]
937   { operands[3] = gen_lowpart (SImode, operands[0]); }
938   [(set_attr "type" "arith")
939    (set_attr "mode" "SI")
940    (set_attr "extended_mips16" "yes")])
941 \f
942 ;;
943 ;;  ....................
944 ;;
945 ;;      SUBTRACTION
946 ;;
947 ;;  ....................
948 ;;
949
950 (define_insn "sub<mode>3"
951   [(set (match_operand:ANYF 0 "register_operand" "=f")
952         (minus:ANYF (match_operand:ANYF 1 "register_operand" "f")
953                     (match_operand:ANYF 2 "register_operand" "f")))]
954   ""
955   "sub.<fmt>\t%0,%1,%2"
956   [(set_attr "type" "fadd")
957    (set_attr "mode" "<UNITMODE>")])
958
959 (define_insn "sub<mode>3"
960   [(set (match_operand:GPR 0 "register_operand" "=d")
961         (minus:GPR (match_operand:GPR 1 "register_operand" "d")
962                    (match_operand:GPR 2 "register_operand" "d")))]
963   ""
964   "<d>subu\t%0,%1,%2"
965   [(set_attr "type" "arith")
966    (set_attr "mode" "<MODE>")])
967
968 (define_insn "*subsi3_extended"
969   [(set (match_operand:DI 0 "register_operand" "=d")
970         (sign_extend:DI
971             (minus:SI (match_operand:SI 1 "register_operand" "d")
972                       (match_operand:SI 2 "register_operand" "d"))))]
973   "TARGET_64BIT"
974   "subu\t%0,%1,%2"
975   [(set_attr "type" "arith")
976    (set_attr "mode" "DI")])
977 \f
978 ;;
979 ;;  ....................
980 ;;
981 ;;      MULTIPLICATION
982 ;;
983 ;;  ....................
984 ;;
985
986 (define_expand "mul<mode>3"
987   [(set (match_operand:SCALARF 0 "register_operand")
988         (mult:SCALARF (match_operand:SCALARF 1 "register_operand")
989                       (match_operand:SCALARF 2 "register_operand")))]
990   ""
991   "")
992
993 (define_insn "*mul<mode>3"
994   [(set (match_operand:SCALARF 0 "register_operand" "=f")
995         (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
996                       (match_operand:SCALARF 2 "register_operand" "f")))]
997   "!TARGET_4300_MUL_FIX"
998   "mul.<fmt>\t%0,%1,%2"
999   [(set_attr "type" "fmul")
1000    (set_attr "mode" "<MODE>")])
1001
1002 ;; Early VR4300 silicon has a CPU bug where multiplies with certain
1003 ;; operands may corrupt immediately following multiplies. This is a
1004 ;; simple fix to insert NOPs.
1005
1006 (define_insn "*mul<mode>3_r4300"
1007   [(set (match_operand:SCALARF 0 "register_operand" "=f")
1008         (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
1009                       (match_operand:SCALARF 2 "register_operand" "f")))]
1010   "TARGET_4300_MUL_FIX"
1011   "mul.<fmt>\t%0,%1,%2\;nop"
1012   [(set_attr "type" "fmul")
1013    (set_attr "mode" "<MODE>")
1014    (set_attr "length" "8")])
1015
1016 (define_insn "mulv2sf3"
1017   [(set (match_operand:V2SF 0 "register_operand" "=f")
1018         (mult:V2SF (match_operand:V2SF 1 "register_operand" "f")
1019                    (match_operand:V2SF 2 "register_operand" "f")))]
1020   "TARGET_PAIRED_SINGLE_FLOAT"
1021   "mul.ps\t%0,%1,%2"
1022   [(set_attr "type" "fmul")
1023    (set_attr "mode" "SF")])
1024
1025 ;; The original R4000 has a cpu bug.  If a double-word or a variable
1026 ;; shift executes while an integer multiplication is in progress, the
1027 ;; shift may give an incorrect result.  Avoid this by keeping the mflo
1028 ;; with the mult on the R4000.
1029 ;;
1030 ;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
1031 ;; (also valid for MIPS R4000MC processors):
1032 ;;
1033 ;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
1034 ;;      this errata description.
1035 ;;      The following code sequence causes the R4000 to incorrectly
1036 ;;      execute the Double Shift Right Arithmetic 32 (dsra32)
1037 ;;      instruction.  If the dsra32 instruction is executed during an
1038 ;;      integer multiply, the dsra32 will only shift by the amount in
1039 ;;      specified in the instruction rather than the amount plus 32
1040 ;;      bits.
1041 ;;      instruction 1:          mult    rs,rt           integer multiply
1042 ;;      instruction 2-12:       dsra32  rd,rt,rs        doubleword shift
1043 ;;                                                      right arithmetic + 32
1044 ;;      Workaround: A dsra32 instruction placed after an integer
1045 ;;      multiply should not be one of the 11 instructions after the
1046 ;;      multiply instruction."
1047 ;;
1048 ;; and:
1049 ;;
1050 ;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
1051 ;;      the following description.
1052 ;;      All extended shifts (shift by n+32) and variable shifts (32 and
1053 ;;      64-bit versions) may produce incorrect results under the
1054 ;;      following conditions:
1055 ;;      1) An integer multiply is currently executing
1056 ;;      2) These types of shift instructions are executed immediately
1057 ;;         following an integer divide instruction.
1058 ;;      Workaround:
1059 ;;      1) Make sure no integer multiply is running wihen these
1060 ;;         instruction are executed.  If this cannot be predicted at
1061 ;;         compile time, then insert a "mfhi" to R0 instruction
1062 ;;         immediately after the integer multiply instruction.  This
1063 ;;         will cause the integer multiply to complete before the shift
1064 ;;         is executed.
1065 ;;      2) Separate integer divide and these two classes of shift
1066 ;;         instructions by another instruction or a noop."
1067 ;;
1068 ;; These processors have PRId values of 0x00004220 and 0x00004300,
1069 ;; respectively.
1070
1071 (define_expand "mulsi3"
1072   [(set (match_operand:SI 0 "register_operand")
1073         (mult:SI (match_operand:SI 1 "register_operand")
1074                  (match_operand:SI 2 "register_operand")))]
1075   ""
1076 {
1077   if (ISA_HAS_MUL3)
1078     emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
1079   else if (TARGET_FIX_R4000)
1080     emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
1081   else
1082     emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
1083   DONE;
1084 })
1085
1086 (define_expand "muldi3"
1087   [(set (match_operand:DI 0 "register_operand")
1088         (mult:DI (match_operand:DI 1 "register_operand")
1089                  (match_operand:DI 2 "register_operand")))]
1090   "TARGET_64BIT"
1091 {
1092   if (TARGET_FIX_R4000)
1093     emit_insn (gen_muldi3_r4000 (operands[0], operands[1], operands[2]));
1094   else
1095     emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
1096   DONE;
1097 })
1098
1099 (define_insn "mulsi3_mult3"
1100   [(set (match_operand:SI 0 "register_operand" "=d,l")
1101         (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1102                  (match_operand:SI 2 "register_operand" "d,d")))
1103    (clobber (match_scratch:SI 3 "=h,h"))
1104    (clobber (match_scratch:SI 4 "=l,X"))]
1105   "ISA_HAS_MUL3"
1106 {
1107   if (which_alternative == 1)
1108     return "mult\t%1,%2";
1109   if (TARGET_MIPS3900)
1110     return "mult\t%0,%1,%2";
1111   return "mul\t%0,%1,%2";
1112 }
1113   [(set_attr "type" "imul3,imul")
1114    (set_attr "mode" "SI")])
1115
1116 ;; If a register gets allocated to LO, and we spill to memory, the reload
1117 ;; will include a move from LO to a GPR.  Merge it into the multiplication
1118 ;; if it can set the GPR directly.
1119 ;;
1120 ;; Operand 0: LO
1121 ;; Operand 1: GPR (1st multiplication operand)
1122 ;; Operand 2: GPR (2nd multiplication operand)
1123 ;; Operand 3: HI
1124 ;; Operand 4: GPR (destination)
1125 (define_peephole2
1126   [(parallel
1127        [(set (match_operand:SI 0 "register_operand")
1128              (mult:SI (match_operand:SI 1 "register_operand")
1129                       (match_operand:SI 2 "register_operand")))
1130         (clobber (match_operand:SI 3 "register_operand"))
1131         (clobber (scratch:SI))])
1132    (set (match_operand:SI 4 "register_operand")
1133         (unspec [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
1134   "ISA_HAS_MUL3 && peep2_reg_dead_p (2, operands[0])"
1135   [(parallel
1136        [(set (match_dup 4)
1137              (mult:SI (match_dup 1)
1138                       (match_dup 2)))
1139         (clobber (match_dup 3))
1140         (clobber (match_dup 0))])])
1141
1142 (define_insn "mul<mode>3_internal"
1143   [(set (match_operand:GPR 0 "register_operand" "=l")
1144         (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1145                   (match_operand:GPR 2 "register_operand" "d")))
1146    (clobber (match_scratch:GPR 3 "=h"))]
1147   "!TARGET_FIX_R4000"
1148   "<d>mult\t%1,%2"
1149   [(set_attr "type" "imul")
1150    (set_attr "mode" "<MODE>")])
1151
1152 (define_insn "mul<mode>3_r4000"
1153   [(set (match_operand:GPR 0 "register_operand" "=d")
1154         (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1155                   (match_operand:GPR 2 "register_operand" "d")))
1156    (clobber (match_scratch:GPR 3 "=h"))
1157    (clobber (match_scratch:GPR 4 "=l"))]
1158   "TARGET_FIX_R4000"
1159   "<d>mult\t%1,%2\;mflo\t%0"
1160   [(set_attr "type" "imul")
1161    (set_attr "mode" "<MODE>")
1162    (set_attr "length" "8")])
1163
1164 ;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
1165 ;; of "mult; mflo".  They have the same latency, but the first form gives
1166 ;; us an extra cycle to compute the operands.
1167
1168 ;; Operand 0: LO
1169 ;; Operand 1: GPR (1st multiplication operand)
1170 ;; Operand 2: GPR (2nd multiplication operand)
1171 ;; Operand 3: HI
1172 ;; Operand 4: GPR (destination)
1173 (define_peephole2
1174   [(parallel
1175        [(set (match_operand:SI 0 "register_operand")
1176              (mult:SI (match_operand:SI 1 "register_operand")
1177                       (match_operand:SI 2 "register_operand")))
1178         (clobber (match_operand:SI 3 "register_operand"))])
1179    (set (match_operand:SI 4 "register_operand")
1180         (unspec:SI [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
1181   "ISA_HAS_MACC && !ISA_HAS_MUL3"
1182   [(set (match_dup 0)
1183         (const_int 0))
1184    (parallel
1185        [(set (match_dup 0)
1186              (plus:SI (mult:SI (match_dup 1)
1187                                (match_dup 2))
1188                       (match_dup 0)))
1189         (set (match_dup 4)
1190              (plus:SI (mult:SI (match_dup 1)
1191                                (match_dup 2))
1192                       (match_dup 0)))
1193         (clobber (match_dup 3))])])
1194
1195 ;; Multiply-accumulate patterns
1196
1197 ;; For processors that can copy the output to a general register:
1198 ;;
1199 ;; The all-d alternative is needed because the combiner will find this
1200 ;; pattern and then register alloc/reload will move registers around to
1201 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
1202 ;;
1203 ;; The last alternative should be made slightly less desirable, but adding
1204 ;; "?" to the constraint is too strong, and causes values to be loaded into
1205 ;; LO even when that's more costly.  For now, using "*d" mostly does the
1206 ;; trick.
1207 (define_insn "*mul_acc_si"
1208   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1209         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1210                           (match_operand:SI 2 "register_operand" "d,d,d"))
1211                  (match_operand:SI 3 "register_operand" "0,l,*d")))
1212    (clobber (match_scratch:SI 4 "=h,h,h"))
1213    (clobber (match_scratch:SI 5 "=X,3,l"))
1214    (clobber (match_scratch:SI 6 "=X,X,&d"))]
1215   "(TARGET_MIPS3900
1216    || GENERATE_MADD_MSUB)
1217    && !TARGET_MIPS16"
1218 {
1219   static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" };
1220   if (which_alternative == 2)
1221     return "#";
1222   if (GENERATE_MADD_MSUB && which_alternative != 0)
1223     return "#";
1224   return madd[which_alternative];
1225 }
1226   [(set_attr "type"     "imadd,imadd,multi")
1227    (set_attr "mode"     "SI")
1228    (set_attr "length"   "4,4,8")])
1229
1230 ;; Split the above insn if we failed to get LO allocated.
1231 (define_split
1232   [(set (match_operand:SI 0 "register_operand")
1233         (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1234                           (match_operand:SI 2 "register_operand"))
1235                  (match_operand:SI 3 "register_operand")))
1236    (clobber (match_scratch:SI 4))
1237    (clobber (match_scratch:SI 5))
1238    (clobber (match_scratch:SI 6))]
1239   "reload_completed && !TARGET_DEBUG_D_MODE
1240    && GP_REG_P (true_regnum (operands[0]))
1241    && GP_REG_P (true_regnum (operands[3]))"
1242   [(parallel [(set (match_dup 6)
1243                    (mult:SI (match_dup 1) (match_dup 2)))
1244               (clobber (match_dup 4))
1245               (clobber (match_dup 5))])
1246    (set (match_dup 0) (plus:SI (match_dup 6) (match_dup 3)))]
1247   "")
1248
1249 ;; Splitter to copy result of MADD to a general register
1250 (define_split
1251   [(set (match_operand:SI                   0 "register_operand")
1252         (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1253                           (match_operand:SI 2 "register_operand"))
1254                  (match_operand:SI          3 "register_operand")))
1255    (clobber (match_scratch:SI               4))
1256    (clobber (match_scratch:SI               5))
1257    (clobber (match_scratch:SI               6))]
1258   "reload_completed && !TARGET_DEBUG_D_MODE
1259    && GP_REG_P (true_regnum (operands[0]))
1260    && true_regnum (operands[3]) == LO_REGNUM"
1261   [(parallel [(set (match_dup 3)
1262                    (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1263                             (match_dup 3)))
1264               (clobber (match_dup 4))
1265               (clobber (match_dup 5))
1266               (clobber (match_dup 6))])
1267    (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1268   "")
1269
1270 (define_insn "*macc"
1271   [(set (match_operand:SI 0 "register_operand" "=l,d")
1272         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1273                           (match_operand:SI 2 "register_operand" "d,d"))
1274                  (match_operand:SI 3 "register_operand" "0,l")))
1275    (clobber (match_scratch:SI 4 "=h,h"))
1276    (clobber (match_scratch:SI 5 "=X,3"))]
1277   "ISA_HAS_MACC"
1278 {
1279   if (which_alternative == 1)
1280     return "macc\t%0,%1,%2";
1281   else if (TARGET_MIPS5500)
1282     return "madd\t%1,%2";
1283   else
1284     /* The VR4130 assumes that there is a two-cycle latency between a macc
1285        that "writes" to $0 and an instruction that reads from it.  We avoid
1286        this by assigning to $1 instead.  */
1287     return "%[macc\t%@,%1,%2%]";
1288 }
1289   [(set_attr "type" "imadd")
1290    (set_attr "mode" "SI")])
1291
1292 (define_insn "*msac"
1293   [(set (match_operand:SI 0 "register_operand" "=l,d")
1294         (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1295                   (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1296                            (match_operand:SI 3 "register_operand" "d,d"))))
1297    (clobber (match_scratch:SI 4 "=h,h"))
1298    (clobber (match_scratch:SI 5 "=X,1"))]
1299   "ISA_HAS_MSAC"
1300 {
1301   if (which_alternative == 1)
1302     return "msac\t%0,%2,%3";
1303   else if (TARGET_MIPS5500)
1304     return "msub\t%2,%3";
1305   else
1306     return "msac\t$0,%2,%3";
1307 }
1308   [(set_attr "type"     "imadd")
1309    (set_attr "mode"     "SI")])
1310
1311 ;; An msac-like instruction implemented using negation and a macc.
1312 (define_insn_and_split "*msac_using_macc"
1313   [(set (match_operand:SI 0 "register_operand" "=l,d")
1314         (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1315                   (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1316                            (match_operand:SI 3 "register_operand" "d,d"))))
1317    (clobber (match_scratch:SI 4 "=h,h"))
1318    (clobber (match_scratch:SI 5 "=X,1"))
1319    (clobber (match_scratch:SI 6 "=d,d"))]
1320   "ISA_HAS_MACC && !ISA_HAS_MSAC"
1321   "#"
1322   "&& reload_completed"
1323   [(set (match_dup 6)
1324         (neg:SI (match_dup 3)))
1325    (parallel
1326        [(set (match_dup 0)
1327              (plus:SI (mult:SI (match_dup 2)
1328                                (match_dup 6))
1329                       (match_dup 1)))
1330         (clobber (match_dup 4))
1331         (clobber (match_dup 5))])]
1332   ""
1333   [(set_attr "type"     "imadd")
1334    (set_attr "length"   "8")])
1335
1336 ;; Patterns generated by the define_peephole2 below.
1337
1338 (define_insn "*macc2"
1339   [(set (match_operand:SI 0 "register_operand" "=l")
1340         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1341                           (match_operand:SI 2 "register_operand" "d"))
1342                  (match_dup 0)))
1343    (set (match_operand:SI 3 "register_operand" "=d")
1344         (plus:SI (mult:SI (match_dup 1)
1345                           (match_dup 2))
1346                  (match_dup 0)))
1347    (clobber (match_scratch:SI 4 "=h"))]
1348   "ISA_HAS_MACC && reload_completed"
1349   "macc\t%3,%1,%2"
1350   [(set_attr "type"     "imadd")
1351    (set_attr "mode"     "SI")])
1352
1353 (define_insn "*msac2"
1354   [(set (match_operand:SI 0 "register_operand" "=l")
1355         (minus:SI (match_dup 0)
1356                   (mult:SI (match_operand:SI 1 "register_operand" "d")
1357                            (match_operand:SI 2 "register_operand" "d"))))
1358    (set (match_operand:SI 3 "register_operand" "=d")
1359         (minus:SI (match_dup 0)
1360                   (mult:SI (match_dup 1)
1361                            (match_dup 2))))
1362    (clobber (match_scratch:SI 4 "=h"))]
1363   "ISA_HAS_MSAC && reload_completed"
1364   "msac\t%3,%1,%2"
1365   [(set_attr "type"     "imadd")
1366    (set_attr "mode"     "SI")])
1367
1368 ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1369 ;; Similarly msac.
1370 ;;
1371 ;; Operand 0: LO
1372 ;; Operand 1: macc/msac
1373 ;; Operand 2: HI
1374 ;; Operand 3: GPR (destination)
1375 (define_peephole2
1376   [(parallel
1377        [(set (match_operand:SI 0 "register_operand")
1378              (match_operand:SI 1 "macc_msac_operand"))
1379         (clobber (match_operand:SI 2 "register_operand"))
1380         (clobber (scratch:SI))])
1381    (set (match_operand:SI 3 "register_operand")
1382         (unspec:SI [(match_dup 0) (match_dup 2)] UNSPEC_MFHILO))]
1383   ""
1384   [(parallel [(set (match_dup 0)
1385                    (match_dup 1))
1386               (set (match_dup 3)
1387                    (match_dup 1))
1388               (clobber (match_dup 2))])]
1389   "")
1390
1391 ;; When we have a three-address multiplication instruction, it should
1392 ;; be faster to do a separate multiply and add, rather than moving
1393 ;; something into LO in order to use a macc instruction.
1394 ;;
1395 ;; This peephole needs a scratch register to cater for the case when one
1396 ;; of the multiplication operands is the same as the destination.
1397 ;;
1398 ;; Operand 0: GPR (scratch)
1399 ;; Operand 1: LO
1400 ;; Operand 2: GPR (addend)
1401 ;; Operand 3: GPR (destination)
1402 ;; Operand 4: macc/msac
1403 ;; Operand 5: HI
1404 ;; Operand 6: new multiplication
1405 ;; Operand 7: new addition/subtraction
1406 (define_peephole2
1407   [(match_scratch:SI 0 "d")
1408    (set (match_operand:SI 1 "register_operand")
1409         (match_operand:SI 2 "register_operand"))
1410    (match_dup 0)
1411    (parallel
1412        [(set (match_operand:SI 3 "register_operand")
1413              (match_operand:SI 4 "macc_msac_operand"))
1414         (clobber (match_operand:SI 5 "register_operand"))
1415         (clobber (match_dup 1))])]
1416   "ISA_HAS_MUL3
1417    && true_regnum (operands[1]) == LO_REGNUM
1418    && peep2_reg_dead_p (2, operands[1])
1419    && GP_REG_P (true_regnum (operands[3]))"
1420   [(parallel [(set (match_dup 0)
1421                    (match_dup 6))
1422               (clobber (match_dup 5))
1423               (clobber (match_dup 1))])
1424    (set (match_dup 3)
1425         (match_dup 7))]
1426 {
1427   operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1428   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1429                                 operands[2], operands[0]);
1430 })
1431
1432 ;; Same as above, except LO is the initial target of the macc.
1433 ;;
1434 ;; Operand 0: GPR (scratch)
1435 ;; Operand 1: LO
1436 ;; Operand 2: GPR (addend)
1437 ;; Operand 3: macc/msac
1438 ;; Operand 4: HI
1439 ;; Operand 5: GPR (destination)
1440 ;; Operand 6: new multiplication
1441 ;; Operand 7: new addition/subtraction
1442 (define_peephole2
1443   [(match_scratch:SI 0 "d")
1444    (set (match_operand:SI 1 "register_operand")
1445         (match_operand:SI 2 "register_operand"))
1446    (match_dup 0)
1447    (parallel
1448        [(set (match_dup 1)
1449              (match_operand:SI 3 "macc_msac_operand"))
1450         (clobber (match_operand:SI 4 "register_operand"))
1451         (clobber (scratch:SI))])
1452    (match_dup 0)
1453    (set (match_operand:SI 5 "register_operand")
1454         (unspec:SI [(match_dup 1) (match_dup 4)] UNSPEC_MFHILO))]
1455   "ISA_HAS_MUL3 && peep2_reg_dead_p (3, operands[1])"
1456   [(parallel [(set (match_dup 0)
1457                    (match_dup 6))
1458               (clobber (match_dup 4))
1459               (clobber (match_dup 1))])
1460    (set (match_dup 5)
1461         (match_dup 7))]
1462 {
1463   operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1464   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1465                                 operands[2], operands[0]);
1466 })
1467
1468 (define_insn "*mul_sub_si"
1469   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1470         (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1471                   (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1472                            (match_operand:SI 3 "register_operand" "d,d,d"))))
1473    (clobber (match_scratch:SI 4 "=h,h,h"))
1474    (clobber (match_scratch:SI 5 "=X,1,l"))
1475    (clobber (match_scratch:SI 6 "=X,X,&d"))]
1476   "GENERATE_MADD_MSUB"
1477   "@
1478    msub\t%2,%3
1479    #
1480    #"
1481   [(set_attr "type"     "imadd,multi,multi")
1482    (set_attr "mode"     "SI")
1483    (set_attr "length"   "4,8,8")])
1484
1485 ;; Split the above insn if we failed to get LO allocated.
1486 (define_split
1487   [(set (match_operand:SI 0 "register_operand")
1488         (minus:SI (match_operand:SI 1 "register_operand")
1489                   (mult:SI (match_operand:SI 2 "register_operand")
1490                            (match_operand:SI 3 "register_operand"))))
1491    (clobber (match_scratch:SI 4))
1492    (clobber (match_scratch:SI 5))
1493    (clobber (match_scratch:SI 6))]
1494   "reload_completed && !TARGET_DEBUG_D_MODE
1495    && GP_REG_P (true_regnum (operands[0]))
1496    && GP_REG_P (true_regnum (operands[1]))"
1497   [(parallel [(set (match_dup 6)
1498                    (mult:SI (match_dup 2) (match_dup 3)))
1499               (clobber (match_dup 4))
1500               (clobber (match_dup 5))])
1501    (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 6)))]
1502   "")
1503
1504 ;; Splitter to copy result of MSUB to a general register
1505 (define_split
1506   [(set (match_operand:SI 0 "register_operand")
1507         (minus:SI (match_operand:SI 1 "register_operand")
1508                   (mult:SI (match_operand:SI 2 "register_operand")
1509                            (match_operand:SI 3 "register_operand"))))
1510    (clobber (match_scratch:SI 4))
1511    (clobber (match_scratch:SI 5))
1512    (clobber (match_scratch:SI 6))]
1513   "reload_completed && !TARGET_DEBUG_D_MODE
1514    && GP_REG_P (true_regnum (operands[0]))
1515    && true_regnum (operands[1]) == LO_REGNUM"
1516   [(parallel [(set (match_dup 1)
1517                    (minus:SI (match_dup 1)
1518                              (mult:SI (match_dup 2) (match_dup 3))))
1519               (clobber (match_dup 4))
1520               (clobber (match_dup 5))
1521               (clobber (match_dup 6))])
1522    (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1523   "")
1524
1525 (define_insn "*muls"
1526   [(set (match_operand:SI                  0 "register_operand" "=l,d")
1527         (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1528                          (match_operand:SI 2 "register_operand" "d,d"))))
1529    (clobber (match_scratch:SI              3                    "=h,h"))
1530    (clobber (match_scratch:SI              4                    "=X,l"))]
1531   "ISA_HAS_MULS"
1532   "@
1533    muls\t$0,%1,%2
1534    muls\t%0,%1,%2"
1535   [(set_attr "type"     "imul,imul3")
1536    (set_attr "mode"     "SI")])
1537
1538 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1539
1540 (define_expand "<u>mulsidi3"
1541   [(parallel
1542       [(set (match_operand:DI 0 "register_operand")
1543             (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1544                      (any_extend:DI (match_operand:SI 2 "register_operand"))))
1545        (clobber (scratch:DI))
1546        (clobber (scratch:DI))
1547        (clobber (scratch:DI))])]
1548   "!TARGET_64BIT || !TARGET_FIX_R4000"
1549 {
1550   if (!TARGET_64BIT)
1551     {
1552       if (!TARGET_FIX_R4000)
1553         emit_insn (gen_<u>mulsidi3_32bit_internal (operands[0], operands[1],
1554                                                    operands[2]));
1555       else
1556         emit_insn (gen_<u>mulsidi3_32bit_r4000 (operands[0], operands[1],
1557                                                 operands[2]));
1558       DONE;
1559     }
1560 })
1561
1562 (define_insn "<u>mulsidi3_32bit_internal"
1563   [(set (match_operand:DI 0 "register_operand" "=x")
1564         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1565                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1566   "!TARGET_64BIT && !TARGET_FIX_R4000 && !TARGET_DSPR2"
1567   "mult<u>\t%1,%2"
1568   [(set_attr "type" "imul")
1569    (set_attr "mode" "SI")])
1570
1571 (define_insn "<u>mulsidi3_32bit_r4000"
1572   [(set (match_operand:DI 0 "register_operand" "=d")
1573         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1574                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1575    (clobber (match_scratch:DI 3 "=x"))]
1576   "!TARGET_64BIT && TARGET_FIX_R4000"
1577   "mult<u>\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1578   [(set_attr "type" "imul")
1579    (set_attr "mode" "SI")
1580    (set_attr "length" "12")])
1581
1582 (define_insn_and_split "*<u>mulsidi3_64bit"
1583   [(set (match_operand:DI 0 "register_operand" "=d")
1584         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1585                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1586    (clobber (match_scratch:DI 3 "=l"))
1587    (clobber (match_scratch:DI 4 "=h"))
1588    (clobber (match_scratch:DI 5 "=d"))]
1589   "TARGET_64BIT && !TARGET_FIX_R4000"
1590   "#"
1591   "&& reload_completed"
1592   [(parallel
1593        [(set (match_dup 3)
1594              (sign_extend:DI
1595                 (mult:SI (match_dup 1)
1596                          (match_dup 2))))
1597         (set (match_dup 4)
1598              (ashiftrt:DI
1599                 (mult:DI (any_extend:DI (match_dup 1))
1600                          (any_extend:DI (match_dup 2)))
1601                 (const_int 32)))])
1602
1603    ;; OP5 <- LO, OP0 <- HI
1604    (set (match_dup 5) (unspec:DI [(match_dup 3) (match_dup 4)] UNSPEC_MFHILO))
1605    (set (match_dup 0) (unspec:DI [(match_dup 4) (match_dup 3)] UNSPEC_MFHILO))
1606
1607    ;; Zero-extend OP5.
1608    (set (match_dup 5)
1609         (ashift:DI (match_dup 5)
1610                    (const_int 32)))
1611    (set (match_dup 5)
1612         (lshiftrt:DI (match_dup 5)
1613                      (const_int 32)))
1614
1615    ;; Shift OP0 into place.
1616    (set (match_dup 0)
1617         (ashift:DI (match_dup 0)
1618                    (const_int 32)))
1619
1620    ;; OR the two halves together
1621    (set (match_dup 0)
1622         (ior:DI (match_dup 0)
1623                 (match_dup 5)))]
1624   ""
1625   [(set_attr "type" "imul")
1626    (set_attr "mode" "SI")
1627    (set_attr "length" "24")])
1628
1629 (define_insn "*<u>mulsidi3_64bit_parts"
1630   [(set (match_operand:DI 0 "register_operand" "=l")
1631         (sign_extend:DI
1632            (mult:SI (match_operand:SI 2 "register_operand" "d")
1633                     (match_operand:SI 3 "register_operand" "d"))))
1634    (set (match_operand:DI 1 "register_operand" "=h")
1635         (ashiftrt:DI
1636            (mult:DI (any_extend:DI (match_dup 2))
1637                     (any_extend:DI (match_dup 3)))
1638            (const_int 32)))]
1639   "TARGET_64BIT && !TARGET_FIX_R4000"
1640   "mult<u>\t%2,%3"
1641   [(set_attr "type" "imul")
1642    (set_attr "mode" "SI")])
1643
1644 ;; Widening multiply with negation.
1645 (define_insn "*muls<u>_di"
1646   [(set (match_operand:DI 0 "register_operand" "=x")
1647         (neg:DI
1648          (mult:DI
1649           (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1650           (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1651   "!TARGET_64BIT && ISA_HAS_MULS"
1652   "muls<u>\t$0,%1,%2"
1653   [(set_attr "type" "imul")
1654    (set_attr "mode" "SI")])
1655
1656 (define_insn "<u>msubsidi4"
1657   [(set (match_operand:DI 0 "register_operand" "=ka")
1658         (minus:DI
1659            (match_operand:DI 3 "register_operand" "0")
1660            (mult:DI
1661               (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1662               (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1663   "!TARGET_64BIT && (ISA_HAS_MSAC || GENERATE_MADD_MSUB || TARGET_DSPR2)"
1664 {
1665   if (TARGET_DSPR2)
1666     return "msub<u>\t%q0,%1,%2";
1667   else if (TARGET_MIPS5500 || GENERATE_MADD_MSUB)
1668     return "msub<u>\t%1,%2";
1669   else
1670     return "msac<u>\t$0,%1,%2";
1671 }
1672   [(set_attr "type" "imadd")
1673    (set_attr "mode" "SI")])
1674
1675 ;; _highpart patterns
1676
1677 (define_expand "<su>mulsi3_highpart"
1678   [(set (match_operand:SI 0 "register_operand")
1679         (truncate:SI
1680          (lshiftrt:DI
1681           (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1682                    (any_extend:DI (match_operand:SI 2 "register_operand")))
1683           (const_int 32))))]
1684   "ISA_HAS_MULHI || !TARGET_FIX_R4000"
1685 {
1686   if (ISA_HAS_MULHI)
1687     emit_insn (gen_<su>mulsi3_highpart_mulhi_internal (operands[0],
1688                                                        operands[1],
1689                                                        operands[2]));
1690   else
1691     emit_insn (gen_<su>mulsi3_highpart_internal (operands[0], operands[1],
1692                                                  operands[2]));
1693   DONE;
1694 })
1695
1696 (define_insn "<su>mulsi3_highpart_internal"
1697   [(set (match_operand:SI 0 "register_operand" "=h")
1698         (truncate:SI
1699          (lshiftrt:DI
1700           (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1701                    (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1702           (const_int 32))))
1703    (clobber (match_scratch:SI 3 "=l"))]
1704   "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
1705   "mult<u>\t%1,%2"
1706   [(set_attr "type" "imul")
1707    (set_attr "mode" "SI")])
1708
1709 (define_insn "<su>mulsi3_highpart_mulhi_internal"
1710   [(set (match_operand:SI 0 "register_operand" "=h,d")
1711         (truncate:SI
1712          (lshiftrt:DI
1713           (mult:DI
1714            (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1715            (any_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
1716           (const_int 32))))
1717    (clobber (match_scratch:SI 3 "=l,l"))
1718    (clobber (match_scratch:SI 4 "=X,h"))]
1719   "ISA_HAS_MULHI"
1720   "@
1721    mult<u>\t%1,%2
1722    mulhi<u>\t%0,%1,%2"
1723   [(set_attr "type" "imul,imul3")
1724    (set_attr "mode" "SI")])
1725
1726 (define_insn "*<su>mulsi3_highpart_neg_mulhi_internal"
1727   [(set (match_operand:SI 0 "register_operand" "=h,d")
1728         (truncate:SI
1729          (lshiftrt:DI
1730           (neg:DI
1731            (mult:DI
1732             (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1733             (any_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
1734           (const_int 32))))
1735    (clobber (match_scratch:SI 3 "=l,l"))
1736    (clobber (match_scratch:SI 4 "=X,h"))]
1737   "ISA_HAS_MULHI"
1738   "@
1739    mulshi<u>\t%.,%1,%2
1740    mulshi<u>\t%0,%1,%2"
1741   [(set_attr "type" "imul,imul3")
1742    (set_attr "mode" "SI")])
1743
1744 ;; Disable unsigned multiplication for -mfix-vr4120.  This is for VR4120
1745 ;; errata MD(0), which says that dmultu does not always produce the
1746 ;; correct result.
1747 (define_insn "<su>muldi3_highpart"
1748   [(set (match_operand:DI 0 "register_operand" "=h")
1749         (truncate:DI
1750          (lshiftrt:TI
1751           (mult:TI
1752            (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
1753            (any_extend:TI (match_operand:DI 2 "register_operand" "d")))
1754           (const_int 64))))
1755    (clobber (match_scratch:DI 3 "=l"))]
1756   "TARGET_64BIT && !TARGET_FIX_R4000
1757    && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
1758   "dmult<u>\t%1,%2"
1759   [(set_attr "type" "imul")
1760    (set_attr "mode" "DI")])
1761
1762 ;; The R4650 supports a 32-bit multiply/ 64-bit accumulate
1763 ;; instruction.  The HI/LO registers are used as a 64-bit accumulator.
1764
1765 (define_insn "madsi"
1766   [(set (match_operand:SI 0 "register_operand" "+l")
1767         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1768                           (match_operand:SI 2 "register_operand" "d"))
1769                  (match_dup 0)))
1770    (clobber (match_scratch:SI 3 "=h"))]
1771   "TARGET_MAD"
1772   "mad\t%1,%2"
1773   [(set_attr "type"     "imadd")
1774    (set_attr "mode"     "SI")])
1775
1776 (define_insn "<u>maddsidi4"
1777   [(set (match_operand:DI 0 "register_operand" "=ka")
1778         (plus:DI
1779          (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1780                   (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1781          (match_operand:DI 3 "register_operand" "0")))]
1782   "(TARGET_MAD || ISA_HAS_MACC || GENERATE_MADD_MSUB || TARGET_DSPR2)
1783    && !TARGET_64BIT"
1784 {
1785   if (TARGET_MAD)
1786     return "mad<u>\t%1,%2";
1787   else if (TARGET_DSPR2)
1788     return "madd<u>\t%q0,%1,%2";
1789   else if (GENERATE_MADD_MSUB || TARGET_MIPS5500)
1790     return "madd<u>\t%1,%2";
1791   else
1792     /* See comment in *macc.  */
1793     return "%[macc<u>\t%@,%1,%2%]";
1794 }
1795   [(set_attr "type" "imadd")
1796    (set_attr "mode" "SI")])
1797
1798 ;; Floating point multiply accumulate instructions.
1799
1800 (define_insn "*madd<mode>"
1801   [(set (match_operand:ANYF 0 "register_operand" "=f")
1802         (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1803                               (match_operand:ANYF 2 "register_operand" "f"))
1804                    (match_operand:ANYF 3 "register_operand" "f")))]
1805   "ISA_HAS_FP4 && TARGET_FUSED_MADD"
1806   "madd.<fmt>\t%0,%3,%1,%2"
1807   [(set_attr "type" "fmadd")
1808    (set_attr "mode" "<UNITMODE>")])
1809
1810 (define_insn "*msub<mode>"
1811   [(set (match_operand:ANYF 0 "register_operand" "=f")
1812         (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1813                                (match_operand:ANYF 2 "register_operand" "f"))
1814                     (match_operand:ANYF 3 "register_operand" "f")))]
1815   "ISA_HAS_FP4 && TARGET_FUSED_MADD"
1816   "msub.<fmt>\t%0,%3,%1,%2"
1817   [(set_attr "type" "fmadd")
1818    (set_attr "mode" "<UNITMODE>")])
1819
1820 (define_insn "*nmadd<mode>"
1821   [(set (match_operand:ANYF 0 "register_operand" "=f")
1822         (neg:ANYF (plus:ANYF
1823                    (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1824                               (match_operand:ANYF 2 "register_operand" "f"))
1825                    (match_operand:ANYF 3 "register_operand" "f"))))]
1826   "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1827    && HONOR_SIGNED_ZEROS (<MODE>mode)
1828    && !HONOR_NANS (<MODE>mode)"
1829   "nmadd.<fmt>\t%0,%3,%1,%2"
1830   [(set_attr "type" "fmadd")
1831    (set_attr "mode" "<UNITMODE>")])
1832
1833 (define_insn "*nmadd<mode>_fastmath"
1834   [(set (match_operand:ANYF 0 "register_operand" "=f")
1835         (minus:ANYF
1836          (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
1837                     (match_operand:ANYF 2 "register_operand" "f"))
1838          (match_operand:ANYF 3 "register_operand" "f")))]
1839   "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1840    && !HONOR_SIGNED_ZEROS (<MODE>mode)
1841    && !HONOR_NANS (<MODE>mode)"
1842   "nmadd.<fmt>\t%0,%3,%1,%2"
1843   [(set_attr "type" "fmadd")
1844    (set_attr "mode" "<UNITMODE>")])
1845
1846 (define_insn "*nmsub<mode>"
1847   [(set (match_operand:ANYF 0 "register_operand" "=f")
1848         (neg:ANYF (minus:ANYF
1849                    (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
1850                               (match_operand:ANYF 3 "register_operand" "f"))
1851                    (match_operand:ANYF 1 "register_operand" "f"))))]
1852   "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1853    && HONOR_SIGNED_ZEROS (<MODE>mode)
1854    && !HONOR_NANS (<MODE>mode)"
1855   "nmsub.<fmt>\t%0,%1,%2,%3"
1856   [(set_attr "type" "fmadd")
1857    (set_attr "mode" "<UNITMODE>")])
1858
1859 (define_insn "*nmsub<mode>_fastmath"
1860   [(set (match_operand:ANYF 0 "register_operand" "=f")
1861         (minus:ANYF
1862          (match_operand:ANYF 1 "register_operand" "f")
1863          (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
1864                     (match_operand:ANYF 3 "register_operand" "f"))))]
1865   "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1866    && !HONOR_SIGNED_ZEROS (<MODE>mode)
1867    && !HONOR_NANS (<MODE>mode)"
1868   "nmsub.<fmt>\t%0,%1,%2,%3"
1869   [(set_attr "type" "fmadd")
1870    (set_attr "mode" "<UNITMODE>")])
1871 \f
1872 ;;
1873 ;;  ....................
1874 ;;
1875 ;;      DIVISION and REMAINDER
1876 ;;
1877 ;;  ....................
1878 ;;
1879
1880 (define_expand "div<mode>3"
1881   [(set (match_operand:ANYF 0 "register_operand")
1882         (div:ANYF (match_operand:ANYF 1 "reg_or_1_operand")
1883                   (match_operand:ANYF 2 "register_operand")))]
1884   "<divide_condition>"
1885 {
1886   if (const_1_operand (operands[1], <MODE>mode))
1887     if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
1888       operands[1] = force_reg (<MODE>mode, operands[1]);
1889 })
1890
1891 ;; These patterns work around the early SB-1 rev2 core "F1" erratum:
1892 ;;
1893 ;; If an mfc1 or dmfc1 happens to access the floating point register
1894 ;; file at the same time a long latency operation (div, sqrt, recip,
1895 ;; sqrt) iterates an intermediate result back through the floating
1896 ;; point register file bypass, then instead returning the correct
1897 ;; register value the mfc1 or dmfc1 operation returns the intermediate
1898 ;; result of the long latency operation.
1899 ;;
1900 ;; The workaround is to insert an unconditional 'mov' from/to the
1901 ;; long latency op destination register.
1902
1903 (define_insn "*div<mode>3"
1904   [(set (match_operand:ANYF 0 "register_operand" "=f")
1905         (div:ANYF (match_operand:ANYF 1 "register_operand" "f")
1906                   (match_operand:ANYF 2 "register_operand" "f")))]
1907   "<divide_condition>"
1908 {
1909   if (TARGET_FIX_SB1)
1910     return "div.<fmt>\t%0,%1,%2\;mov.<fmt>\t%0,%0";
1911   else
1912     return "div.<fmt>\t%0,%1,%2";
1913 }
1914   [(set_attr "type" "fdiv")
1915    (set_attr "mode" "<UNITMODE>")
1916    (set (attr "length")
1917         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1918                       (const_int 8)
1919                       (const_int 4)))])
1920
1921 (define_insn "*recip<mode>3"
1922   [(set (match_operand:ANYF 0 "register_operand" "=f")
1923         (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
1924                   (match_operand:ANYF 2 "register_operand" "f")))]
1925   "<recip_condition> && flag_unsafe_math_optimizations"
1926 {
1927   if (TARGET_FIX_SB1)
1928     return "recip.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
1929   else
1930     return "recip.<fmt>\t%0,%2";
1931 }
1932   [(set_attr "type" "frdiv")
1933    (set_attr "mode" "<UNITMODE>")
1934    (set (attr "length")
1935         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1936                       (const_int 8)
1937                       (const_int 4)))])
1938
1939 ;; VR4120 errata MD(A1): signed division instructions do not work correctly
1940 ;; with negative operands.  We use special libgcc functions instead.
1941 (define_insn "divmod<mode>4"
1942   [(set (match_operand:GPR 0 "register_operand" "=l")
1943         (div:GPR (match_operand:GPR 1 "register_operand" "d")
1944                  (match_operand:GPR 2 "register_operand" "d")))
1945    (set (match_operand:GPR 3 "register_operand" "=h")
1946         (mod:GPR (match_dup 1)
1947                  (match_dup 2)))]
1948   "!TARGET_FIX_VR4120"
1949   { return mips_output_division ("<d>div\t$0,%1,%2", operands); }
1950   [(set_attr "type" "idiv")
1951    (set_attr "mode" "<MODE>")])
1952
1953 (define_insn "udivmod<mode>4"
1954   [(set (match_operand:GPR 0 "register_operand" "=l")
1955         (udiv:GPR (match_operand:GPR 1 "register_operand" "d")
1956                   (match_operand:GPR 2 "register_operand" "d")))
1957    (set (match_operand:GPR 3 "register_operand" "=h")
1958         (umod:GPR (match_dup 1)
1959                   (match_dup 2)))]
1960   ""
1961   { return mips_output_division ("<d>divu\t$0,%1,%2", operands); }
1962   [(set_attr "type" "idiv")
1963    (set_attr "mode" "<MODE>")])
1964 \f
1965 ;;
1966 ;;  ....................
1967 ;;
1968 ;;      SQUARE ROOT
1969 ;;
1970 ;;  ....................
1971
1972 ;; These patterns work around the early SB-1 rev2 core "F1" erratum (see
1973 ;; "*div[sd]f3" comment for details).
1974
1975 (define_insn "sqrt<mode>2"
1976   [(set (match_operand:ANYF 0 "register_operand" "=f")
1977         (sqrt:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
1978   "<sqrt_condition>"
1979 {
1980   if (TARGET_FIX_SB1)
1981     return "sqrt.<fmt>\t%0,%1\;mov.<fmt>\t%0,%0";
1982   else
1983     return "sqrt.<fmt>\t%0,%1";
1984 }
1985   [(set_attr "type" "fsqrt")
1986    (set_attr "mode" "<UNITMODE>")
1987    (set (attr "length")
1988         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1989                       (const_int 8)
1990                       (const_int 4)))])
1991
1992 (define_insn "*rsqrt<mode>a"
1993   [(set (match_operand:ANYF 0 "register_operand" "=f")
1994         (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
1995                   (sqrt:ANYF (match_operand:ANYF 2 "register_operand" "f"))))]
1996   "<recip_condition> && flag_unsafe_math_optimizations"
1997 {
1998   if (TARGET_FIX_SB1)
1999     return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
2000   else
2001     return "rsqrt.<fmt>\t%0,%2";
2002 }
2003   [(set_attr "type" "frsqrt")
2004    (set_attr "mode" "<UNITMODE>")
2005    (set (attr "length")
2006         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2007                       (const_int 8)
2008                       (const_int 4)))])
2009
2010 (define_insn "*rsqrt<mode>b"
2011   [(set (match_operand:ANYF 0 "register_operand" "=f")
2012         (sqrt:ANYF (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
2013                              (match_operand:ANYF 2 "register_operand" "f"))))]
2014   "<recip_condition> && flag_unsafe_math_optimizations"
2015 {
2016   if (TARGET_FIX_SB1)
2017     return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
2018   else
2019     return "rsqrt.<fmt>\t%0,%2";
2020 }
2021   [(set_attr "type" "frsqrt")
2022    (set_attr "mode" "<UNITMODE>")
2023    (set (attr "length")
2024         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2025                       (const_int 8)
2026                       (const_int 4)))])
2027 \f
2028 ;;
2029 ;;  ....................
2030 ;;
2031 ;;      ABSOLUTE VALUE
2032 ;;
2033 ;;  ....................
2034
2035 ;; Do not use the integer abs macro instruction, since that signals an
2036 ;; exception on -2147483648 (sigh).
2037
2038 ;; abs.fmt is an arithmetic instruction and treats all NaN inputs as
2039 ;; invalid; it does not clear their sign bits.  We therefore can't use
2040 ;; abs.fmt if the signs of NaNs matter.
2041
2042 (define_insn "abs<mode>2"
2043   [(set (match_operand:ANYF 0 "register_operand" "=f")
2044         (abs:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2045   "!HONOR_NANS (<MODE>mode)"
2046   "abs.<fmt>\t%0,%1"
2047   [(set_attr "type" "fabs")
2048    (set_attr "mode" "<UNITMODE>")])
2049 \f
2050 ;;
2051 ;;  ...................
2052 ;;
2053 ;;  Count leading zeroes.
2054 ;;
2055 ;;  ...................
2056 ;;
2057
2058 (define_insn "clz<mode>2"
2059   [(set (match_operand:GPR 0 "register_operand" "=d")
2060         (clz:GPR (match_operand:GPR 1 "register_operand" "d")))]
2061   "ISA_HAS_CLZ_CLO"
2062   "<d>clz\t%0,%1"
2063   [(set_attr "type" "clz")
2064    (set_attr "mode" "<MODE>")])
2065 \f
2066 ;;
2067 ;;  ....................
2068 ;;
2069 ;;      NEGATION and ONE'S COMPLEMENT
2070 ;;
2071 ;;  ....................
2072
2073 (define_insn "negsi2"
2074   [(set (match_operand:SI 0 "register_operand" "=d")
2075         (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2076   ""
2077 {
2078   if (TARGET_MIPS16)
2079     return "neg\t%0,%1";
2080   else
2081     return "subu\t%0,%.,%1";
2082 }
2083   [(set_attr "type"     "arith")
2084    (set_attr "mode"     "SI")])
2085
2086 (define_insn "negdi2"
2087   [(set (match_operand:DI 0 "register_operand" "=d")
2088         (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2089   "TARGET_64BIT && !TARGET_MIPS16"
2090   "dsubu\t%0,%.,%1"
2091   [(set_attr "type"     "arith")
2092    (set_attr "mode"     "DI")])
2093
2094 ;; neg.fmt is an arithmetic instruction and treats all NaN inputs as
2095 ;; invalid; it does not flip their sign bit.  We therefore can't use
2096 ;; neg.fmt if the signs of NaNs matter.
2097
2098 (define_insn "neg<mode>2"
2099   [(set (match_operand:ANYF 0 "register_operand" "=f")
2100         (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2101   "!HONOR_NANS (<MODE>mode)"
2102   "neg.<fmt>\t%0,%1"
2103   [(set_attr "type" "fneg")
2104    (set_attr "mode" "<UNITMODE>")])
2105
2106 (define_insn "one_cmpl<mode>2"
2107   [(set (match_operand:GPR 0 "register_operand" "=d")
2108         (not:GPR (match_operand:GPR 1 "register_operand" "d")))]
2109   ""
2110 {
2111   if (TARGET_MIPS16)
2112     return "not\t%0,%1";
2113   else
2114     return "nor\t%0,%.,%1";
2115 }
2116   [(set_attr "type" "logical")
2117    (set_attr "mode" "<MODE>")])
2118 \f
2119 ;;
2120 ;;  ....................
2121 ;;
2122 ;;      LOGICAL
2123 ;;
2124 ;;  ....................
2125 ;;
2126
2127 ;; Many of these instructions use trivial define_expands, because we
2128 ;; want to use a different set of constraints when TARGET_MIPS16.
2129
2130 (define_expand "and<mode>3"
2131   [(set (match_operand:GPR 0 "register_operand")
2132         (and:GPR (match_operand:GPR 1 "register_operand")
2133                  (match_operand:GPR 2 "uns_arith_operand")))]
2134   ""
2135 {
2136   if (TARGET_MIPS16)
2137     operands[2] = force_reg (<MODE>mode, operands[2]);
2138 })
2139
2140 (define_insn "*and<mode>3"
2141   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2142         (and:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2143                  (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2144   "!TARGET_MIPS16"
2145   "@
2146    and\t%0,%1,%2
2147    andi\t%0,%1,%x2"
2148   [(set_attr "type" "logical")
2149    (set_attr "mode" "<MODE>")])
2150
2151 (define_insn "*and<mode>3_mips16"
2152   [(set (match_operand:GPR 0 "register_operand" "=d")
2153         (and:GPR (match_operand:GPR 1 "register_operand" "%0")
2154                  (match_operand:GPR 2 "register_operand" "d")))]
2155   "TARGET_MIPS16"
2156   "and\t%0,%2"
2157   [(set_attr "type" "logical")
2158    (set_attr "mode" "<MODE>")])
2159
2160 (define_expand "ior<mode>3"
2161   [(set (match_operand:GPR 0 "register_operand")
2162         (ior:GPR (match_operand:GPR 1 "register_operand")
2163                  (match_operand:GPR 2 "uns_arith_operand")))]
2164   ""
2165 {
2166   if (TARGET_MIPS16)
2167     operands[2] = force_reg (<MODE>mode, operands[2]);
2168 })
2169
2170 (define_insn "*ior<mode>3"
2171   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2172         (ior:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2173                  (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2174   "!TARGET_MIPS16"
2175   "@
2176    or\t%0,%1,%2
2177    ori\t%0,%1,%x2"
2178   [(set_attr "type" "logical")
2179    (set_attr "mode" "<MODE>")])
2180
2181 (define_insn "*ior<mode>3_mips16"
2182   [(set (match_operand:GPR 0 "register_operand" "=d")
2183         (ior:GPR (match_operand:GPR 1 "register_operand" "%0")
2184                  (match_operand:GPR 2 "register_operand" "d")))]
2185   "TARGET_MIPS16"
2186   "or\t%0,%2"
2187   [(set_attr "type" "logical")
2188    (set_attr "mode" "<MODE>")])
2189
2190 (define_expand "xor<mode>3"
2191   [(set (match_operand:GPR 0 "register_operand")
2192         (xor:GPR (match_operand:GPR 1 "register_operand")
2193                  (match_operand:GPR 2 "uns_arith_operand")))]
2194   ""
2195   "")
2196
2197 (define_insn ""
2198   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2199         (xor:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2200                  (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2201   "!TARGET_MIPS16"
2202   "@
2203    xor\t%0,%1,%2
2204    xori\t%0,%1,%x2"
2205   [(set_attr "type" "logical")
2206    (set_attr "mode" "<MODE>")])
2207
2208 (define_insn ""
2209   [(set (match_operand:GPR 0 "register_operand" "=d,t,t")
2210         (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d")
2211                  (match_operand:GPR 2 "uns_arith_operand" "d,K,d")))]
2212   "TARGET_MIPS16"
2213   "@
2214    xor\t%0,%2
2215    cmpi\t%1,%2
2216    cmp\t%1,%2"
2217   [(set_attr "type" "logical,arith,arith")
2218    (set_attr "mode" "<MODE>")
2219    (set_attr_alternative "length"
2220                 [(const_int 4)
2221                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2222                                (const_int 4)
2223                                (const_int 8))
2224                  (const_int 4)])])
2225
2226 (define_insn "*nor<mode>3"
2227   [(set (match_operand:GPR 0 "register_operand" "=d")
2228         (and:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
2229                  (not:GPR (match_operand:GPR 2 "register_operand" "d"))))]
2230   "!TARGET_MIPS16"
2231   "nor\t%0,%1,%2"
2232   [(set_attr "type" "logical")
2233    (set_attr "mode" "<MODE>")])
2234 \f
2235 ;;
2236 ;;  ....................
2237 ;;
2238 ;;      TRUNCATION
2239 ;;
2240 ;;  ....................
2241
2242
2243
2244 (define_insn "truncdfsf2"
2245   [(set (match_operand:SF 0 "register_operand" "=f")
2246         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2247   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2248   "cvt.s.d\t%0,%1"
2249   [(set_attr "type"     "fcvt")
2250    (set_attr "cnv_mode" "D2S")   
2251    (set_attr "mode"     "SF")])
2252
2253 ;; Integer truncation patterns.  Truncating SImode values to smaller
2254 ;; modes is a no-op, as it is for most other GCC ports.  Truncating
2255 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
2256 ;; need to make sure that the lower 32 bits are properly sign-extended
2257 ;; (see TRULY_NOOP_TRUNCATION).  Truncating DImode values into modes
2258 ;; smaller than SImode is equivalent to two separate truncations:
2259 ;;
2260 ;;                        A       B
2261 ;;    DI ---> HI  ==  DI ---> SI ---> HI
2262 ;;    DI ---> QI  ==  DI ---> SI ---> QI
2263 ;;
2264 ;; Step A needs a real instruction but step B does not.
2265
2266 (define_insn "truncdisi2"
2267   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
2268         (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
2269   "TARGET_64BIT"
2270   "@
2271     sll\t%0,%1,0
2272     sw\t%1,%0"
2273   [(set_attr "type" "shift,store")
2274    (set_attr "mode" "SI")
2275    (set_attr "extended_mips16" "yes,*")])
2276
2277 (define_insn "truncdihi2"
2278   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
2279         (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
2280   "TARGET_64BIT"
2281   "@
2282     sll\t%0,%1,0
2283     sh\t%1,%0"
2284   [(set_attr "type" "shift,store")
2285    (set_attr "mode" "SI")
2286    (set_attr "extended_mips16" "yes,*")])
2287
2288 (define_insn "truncdiqi2"
2289   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
2290         (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
2291   "TARGET_64BIT"
2292   "@
2293     sll\t%0,%1,0
2294     sb\t%1,%0"
2295   [(set_attr "type" "shift,store")
2296    (set_attr "mode" "SI")
2297    (set_attr "extended_mips16" "yes,*")])
2298
2299 ;; Combiner patterns to optimize shift/truncate combinations.
2300
2301 (define_insn ""
2302   [(set (match_operand:SI 0 "register_operand" "=d")
2303         (truncate:SI
2304           (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2305                        (match_operand:DI 2 "const_arith_operand" ""))))]
2306   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
2307   "dsra\t%0,%1,%2"
2308   [(set_attr "type" "shift")
2309    (set_attr "mode" "SI")])
2310
2311 (define_insn ""
2312   [(set (match_operand:SI 0 "register_operand" "=d")
2313         (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2314                                   (const_int 32))))]
2315   "TARGET_64BIT && !TARGET_MIPS16"
2316   "dsra\t%0,%1,32"
2317   [(set_attr "type" "shift")
2318    (set_attr "mode" "SI")])
2319
2320
2321 ;; Combiner patterns for truncate/sign_extend combinations.  They use
2322 ;; the shift/truncate patterns above.
2323
2324 (define_insn_and_split ""
2325   [(set (match_operand:SI 0 "register_operand" "=d")
2326         (sign_extend:SI
2327             (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
2328   "TARGET_64BIT && !TARGET_MIPS16"
2329   "#"
2330   "&& reload_completed"
2331   [(set (match_dup 2)
2332         (ashift:DI (match_dup 1)
2333                    (const_int 48)))
2334    (set (match_dup 0)
2335         (truncate:SI (ashiftrt:DI (match_dup 2)
2336                                   (const_int 48))))]
2337   { operands[2] = gen_lowpart (DImode, operands[0]); })
2338
2339 (define_insn_and_split ""
2340   [(set (match_operand:SI 0 "register_operand" "=d")
2341         (sign_extend:SI
2342             (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
2343   "TARGET_64BIT && !TARGET_MIPS16"
2344   "#"
2345   "&& reload_completed"
2346   [(set (match_dup 2)
2347         (ashift:DI (match_dup 1)
2348                    (const_int 56)))
2349    (set (match_dup 0)
2350         (truncate:SI (ashiftrt:DI (match_dup 2)
2351                                   (const_int 56))))]
2352   { operands[2] = gen_lowpart (DImode, operands[0]); })
2353
2354
2355 ;; Combiner patterns to optimize truncate/zero_extend combinations.
2356
2357 (define_insn ""
2358   [(set (match_operand:SI 0 "register_operand" "=d")
2359         (zero_extend:SI (truncate:HI
2360                          (match_operand:DI 1 "register_operand" "d"))))]
2361   "TARGET_64BIT && !TARGET_MIPS16"
2362   "andi\t%0,%1,0xffff"
2363   [(set_attr "type"     "logical")
2364    (set_attr "mode"     "SI")])
2365
2366 (define_insn ""
2367   [(set (match_operand:SI 0 "register_operand" "=d")
2368         (zero_extend:SI (truncate:QI
2369                          (match_operand:DI 1 "register_operand" "d"))))]
2370   "TARGET_64BIT && !TARGET_MIPS16"
2371   "andi\t%0,%1,0xff"
2372   [(set_attr "type"     "logical")
2373    (set_attr "mode"     "SI")])
2374
2375 (define_insn ""
2376   [(set (match_operand:HI 0 "register_operand" "=d")
2377         (zero_extend:HI (truncate:QI
2378                          (match_operand:DI 1 "register_operand" "d"))))]
2379   "TARGET_64BIT && !TARGET_MIPS16"
2380   "andi\t%0,%1,0xff"
2381   [(set_attr "type"     "logical")
2382    (set_attr "mode"     "HI")])
2383 \f
2384 ;;
2385 ;;  ....................
2386 ;;
2387 ;;      ZERO EXTENSION
2388 ;;
2389 ;;  ....................
2390
2391 ;; Extension insns.
2392
2393 (define_insn_and_split "zero_extendsidi2"
2394   [(set (match_operand:DI 0 "register_operand" "=d,d")
2395         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,W")))]
2396   "TARGET_64BIT"
2397   "@
2398    #
2399    lwu\t%0,%1"
2400   "&& reload_completed && REG_P (operands[1])"
2401   [(set (match_dup 0)
2402         (ashift:DI (match_dup 1) (const_int 32)))
2403    (set (match_dup 0)
2404         (lshiftrt:DI (match_dup 0) (const_int 32)))]
2405   { operands[1] = gen_lowpart (DImode, operands[1]); }
2406   [(set_attr "type" "multi,load")
2407    (set_attr "mode" "DI")
2408    (set_attr "length" "8,*")])
2409
2410 ;; Combine is not allowed to convert this insn into a zero_extendsidi2
2411 ;; because of TRULY_NOOP_TRUNCATION.
2412
2413 (define_insn_and_split "*clear_upper32"
2414   [(set (match_operand:DI 0 "register_operand" "=d,d")
2415         (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o")
2416                 (const_int 4294967295)))]
2417   "TARGET_64BIT"
2418 {
2419   if (which_alternative == 0)
2420     return "#";
2421
2422   operands[1] = gen_lowpart (SImode, operands[1]);
2423   return "lwu\t%0,%1";
2424 }
2425   "&& reload_completed && REG_P (operands[1])"
2426   [(set (match_dup 0)
2427         (ashift:DI (match_dup 1) (const_int 32)))
2428    (set (match_dup 0)
2429         (lshiftrt:DI (match_dup 0) (const_int 32)))]
2430   ""
2431   [(set_attr "type" "multi,load")
2432    (set_attr "mode" "DI")
2433    (set_attr "length" "8,*")])
2434
2435 (define_expand "zero_extend<SHORT:mode><GPR:mode>2"
2436   [(set (match_operand:GPR 0 "register_operand")
2437         (zero_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
2438   ""
2439 {
2440   if (TARGET_MIPS16 && !GENERATE_MIPS16E
2441       && !memory_operand (operands[1], <SHORT:MODE>mode))
2442     {
2443       emit_insn (gen_and<GPR:mode>3 (operands[0],
2444                                      gen_lowpart (<GPR:MODE>mode, operands[1]),
2445                                      force_reg (<GPR:MODE>mode,
2446                                                 GEN_INT (<SHORT:mask>))));
2447       DONE;
2448     }
2449 })
2450
2451 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2"
2452   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2453         (zero_extend:GPR
2454              (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2455   "!TARGET_MIPS16"
2456   "@
2457    andi\t%0,%1,<SHORT:mask>
2458    l<SHORT:size>u\t%0,%1"
2459   [(set_attr "type" "logical,load")
2460    (set_attr "mode" "<GPR:MODE>")])
2461
2462 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16e"
2463   [(set (match_operand:GPR 0 "register_operand" "=d")
2464         (zero_extend:GPR (match_operand:SHORT 1 "register_operand" "0")))]
2465   "GENERATE_MIPS16E"
2466   "ze<SHORT:size>\t%0"
2467   [(set_attr "type" "arith")
2468    (set_attr "mode" "<GPR:MODE>")])
2469
2470 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16"
2471   [(set (match_operand:GPR 0 "register_operand" "=d")
2472         (zero_extend:GPR (match_operand:SHORT 1 "memory_operand" "m")))]
2473   "TARGET_MIPS16"
2474   "l<SHORT:size>u\t%0,%1"
2475   [(set_attr "type" "load")
2476    (set_attr "mode" "<GPR:MODE>")])
2477
2478 (define_expand "zero_extendqihi2"
2479   [(set (match_operand:HI 0 "register_operand")
2480         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2481   ""
2482 {
2483   if (TARGET_MIPS16 && !memory_operand (operands[1], QImode))
2484     {
2485       emit_insn (gen_zero_extendqisi2 (gen_lowpart (SImode, operands[0]),
2486                                        operands[1]));
2487       DONE;
2488     }
2489 })
2490
2491 (define_insn "*zero_extendqihi2"
2492   [(set (match_operand:HI 0 "register_operand" "=d,d")
2493         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2494   "!TARGET_MIPS16"
2495   "@
2496    andi\t%0,%1,0x00ff
2497    lbu\t%0,%1"
2498   [(set_attr "type" "logical,load")
2499    (set_attr "mode" "HI")])
2500
2501 (define_insn "*zero_extendqihi2_mips16"
2502   [(set (match_operand:HI 0 "register_operand" "=d")
2503         (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2504   "TARGET_MIPS16"
2505   "lbu\t%0,%1"
2506   [(set_attr "type" "load")
2507    (set_attr "mode" "HI")])
2508 \f
2509 ;;
2510 ;;  ....................
2511 ;;
2512 ;;      SIGN EXTENSION
2513 ;;
2514 ;;  ....................
2515
2516 ;; Extension insns.
2517 ;; Those for integer source operand are ordered widest source type first.
2518
2519 ;; When TARGET_64BIT, all SImode integer registers should already be in
2520 ;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2).  We can
2521 ;; therefore get rid of register->register instructions if we constrain
2522 ;; the source to be in the same register as the destination.
2523 ;;
2524 ;; The register alternative has type "arith" so that the pre-reload
2525 ;; scheduler will treat it as a move.  This reflects what happens if
2526 ;; the register alternative needs a reload.
2527 (define_insn_and_split "extendsidi2"
2528   [(set (match_operand:DI 0 "register_operand" "=d,d")
2529         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,m")))]
2530   "TARGET_64BIT"
2531   "@
2532    #
2533    lw\t%0,%1"
2534   "&& reload_completed && register_operand (operands[1], VOIDmode)"
2535   [(const_int 0)]
2536 {
2537   emit_note (NOTE_INSN_DELETED);
2538   DONE;
2539 }
2540   [(set_attr "type" "arith,load")
2541    (set_attr "mode" "DI")])
2542
2543 (define_expand "extend<SHORT:mode><GPR:mode>2"
2544   [(set (match_operand:GPR 0 "register_operand")
2545         (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
2546   "")
2547
2548 (define_insn "*extend<SHORT:mode><GPR:mode>2_mips16e"
2549   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2550         (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand" "0,m")))]
2551   "GENERATE_MIPS16E"
2552   "@
2553    se<SHORT:size>\t%0
2554    l<SHORT:size>\t%0,%1"
2555   [(set_attr "type" "signext,load")
2556    (set_attr "mode" "<GPR:MODE>")])
2557
2558 (define_insn_and_split "*extend<SHORT:mode><GPR:mode>2"
2559   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2560         (sign_extend:GPR
2561              (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2562   "!ISA_HAS_SEB_SEH && !GENERATE_MIPS16E"
2563   "@
2564    #
2565    l<SHORT:size>\t%0,%1"
2566   "&& reload_completed && REG_P (operands[1])"
2567   [(set (match_dup 0) (ashift:GPR (match_dup 1) (match_dup 2)))
2568    (set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))]
2569 {
2570   operands[1] = gen_lowpart (<GPR:MODE>mode, operands[1]);
2571   operands[2] = GEN_INT (GET_MODE_BITSIZE (<GPR:MODE>mode)
2572                          - GET_MODE_BITSIZE (<SHORT:MODE>mode));
2573 }
2574   [(set_attr "type" "arith,load")
2575    (set_attr "mode" "<GPR:MODE>")
2576    (set_attr "length" "8,*")])
2577
2578 (define_insn "*extend<SHORT:mode><GPR:mode>2_se<SHORT:size>"
2579   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2580         (sign_extend:GPR
2581              (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2582   "ISA_HAS_SEB_SEH"
2583   "@
2584    se<SHORT:size>\t%0,%1
2585    l<SHORT:size>\t%0,%1"
2586   [(set_attr "type" "signext,load")
2587    (set_attr "mode" "<GPR:MODE>")])
2588
2589 (define_expand "extendqihi2"
2590   [(set (match_operand:HI 0 "register_operand")
2591         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2592   "")
2593
2594 (define_insn "*extendqihi2_mips16e"
2595   [(set (match_operand:HI 0 "register_operand" "=d,d")
2596         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,m")))]
2597   "GENERATE_MIPS16E"
2598   "@
2599    seb\t%0
2600    lb\t%0,%1"
2601   [(set_attr "type" "signext,load")
2602    (set_attr "mode" "SI")])
2603
2604 (define_insn_and_split "*extendqihi2"
2605   [(set (match_operand:HI 0 "register_operand" "=d,d")
2606         (sign_extend:HI
2607              (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2608   "!ISA_HAS_SEB_SEH && !GENERATE_MIPS16E"
2609   "@
2610    #
2611    lb\t%0,%1"
2612   "&& reload_completed && REG_P (operands[1])"
2613   [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
2614    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
2615 {
2616   operands[1] = gen_lowpart (SImode, operands[1]);
2617   operands[2] = GEN_INT (GET_MODE_BITSIZE (SImode)
2618                          - GET_MODE_BITSIZE (QImode));
2619 }
2620   [(set_attr "type" "multi,load")
2621    (set_attr "mode" "SI")
2622    (set_attr "length" "8,*")])
2623
2624 (define_insn "*extendqihi2_seb"
2625   [(set (match_operand:HI 0 "register_operand" "=d,d")
2626         (sign_extend:HI
2627              (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2628   "ISA_HAS_SEB_SEH"
2629   "@
2630    seb\t%0,%1
2631    lb\t%0,%1"
2632   [(set_attr "type" "signext,load")
2633    (set_attr "mode" "SI")])
2634
2635 (define_insn "extendsfdf2"
2636   [(set (match_operand:DF 0 "register_operand" "=f")
2637         (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2638   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2639   "cvt.d.s\t%0,%1"
2640   [(set_attr "type"     "fcvt")
2641    (set_attr "cnv_mode" "S2D")   
2642    (set_attr "mode"     "DF")])
2643 \f
2644 ;;
2645 ;;  ....................
2646 ;;
2647 ;;      CONVERSIONS
2648 ;;
2649 ;;  ....................
2650
2651 (define_expand "fix_truncdfsi2"
2652   [(set (match_operand:SI 0 "register_operand")
2653         (fix:SI (match_operand:DF 1 "register_operand")))]
2654   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2655 {
2656   if (!ISA_HAS_TRUNC_W)
2657     {
2658       emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
2659       DONE;
2660     }
2661 })
2662
2663 (define_insn "fix_truncdfsi2_insn"
2664   [(set (match_operand:SI 0 "register_operand" "=f")
2665         (fix:SI (match_operand:DF 1 "register_operand" "f")))]
2666   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
2667   "trunc.w.d %0,%1"
2668   [(set_attr "type"     "fcvt")
2669    (set_attr "mode"     "DF")
2670    (set_attr "cnv_mode" "D2I")
2671    (set_attr "length"   "4")])
2672
2673 (define_insn "fix_truncdfsi2_macro"
2674   [(set (match_operand:SI 0 "register_operand" "=f")
2675         (fix:SI (match_operand:DF 1 "register_operand" "f")))
2676    (clobber (match_scratch:DF 2 "=d"))]
2677   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
2678 {
2679   if (set_nomacro)
2680     return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
2681   else
2682     return "trunc.w.d %0,%1,%2";
2683 }
2684   [(set_attr "type"     "fcvt")
2685    (set_attr "mode"     "DF")
2686    (set_attr "cnv_mode" "D2I")
2687    (set_attr "length"   "36")])
2688
2689 (define_expand "fix_truncsfsi2"
2690   [(set (match_operand:SI 0 "register_operand")
2691         (fix:SI (match_operand:SF 1 "register_operand")))]
2692   "TARGET_HARD_FLOAT"
2693 {
2694   if (!ISA_HAS_TRUNC_W)
2695     {
2696       emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
2697       DONE;
2698     }
2699 })
2700
2701 (define_insn "fix_truncsfsi2_insn"
2702   [(set (match_operand:SI 0 "register_operand" "=f")
2703         (fix:SI (match_operand:SF 1 "register_operand" "f")))]
2704   "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
2705   "trunc.w.s %0,%1"
2706   [(set_attr "type"     "fcvt")
2707    (set_attr "mode"     "SF")
2708    (set_attr "cnv_mode" "S2I")
2709    (set_attr "length"   "4")])
2710
2711 (define_insn "fix_truncsfsi2_macro"
2712   [(set (match_operand:SI 0 "register_operand" "=f")
2713         (fix:SI (match_operand:SF 1 "register_operand" "f")))
2714    (clobber (match_scratch:SF 2 "=d"))]
2715   "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
2716 {
2717   if (set_nomacro)
2718     return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
2719   else
2720     return "trunc.w.s %0,%1,%2";
2721 }
2722   [(set_attr "type"     "fcvt")
2723    (set_attr "mode"     "SF")
2724    (set_attr "cnv_mode" "S2I")
2725    (set_attr "length"   "36")])
2726
2727
2728 (define_insn "fix_truncdfdi2"
2729   [(set (match_operand:DI 0 "register_operand" "=f")
2730         (fix:DI (match_operand:DF 1 "register_operand" "f")))]
2731   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2732   "trunc.l.d %0,%1"
2733   [(set_attr "type"     "fcvt")
2734    (set_attr "mode"     "DF")
2735    (set_attr "cnv_mode" "D2I")
2736    (set_attr "length"   "4")])
2737
2738
2739 (define_insn "fix_truncsfdi2"
2740   [(set (match_operand:DI 0 "register_operand" "=f")
2741         (fix:DI (match_operand:SF 1 "register_operand" "f")))]
2742   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2743   "trunc.l.s %0,%1"
2744   [(set_attr "type"     "fcvt")
2745    (set_attr "mode"     "SF")
2746    (set_attr "cnv_mode" "S2I")
2747    (set_attr "length"   "4")])
2748
2749
2750 (define_insn "floatsidf2"
2751   [(set (match_operand:DF 0 "register_operand" "=f")
2752         (float:DF (match_operand:SI 1 "register_operand" "f")))]
2753   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2754   "cvt.d.w\t%0,%1"
2755   [(set_attr "type"     "fcvt")
2756    (set_attr "mode"     "DF")
2757    (set_attr "cnv_mode" "I2D")   
2758    (set_attr "length"   "4")])
2759
2760
2761 (define_insn "floatdidf2"
2762   [(set (match_operand:DF 0 "register_operand" "=f")
2763         (float:DF (match_operand:DI 1 "register_operand" "f")))]
2764   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2765   "cvt.d.l\t%0,%1"
2766   [(set_attr "type"     "fcvt")
2767    (set_attr "mode"     "DF")
2768    (set_attr "cnv_mode" "I2D")   
2769    (set_attr "length"   "4")])
2770
2771
2772 (define_insn "floatsisf2"
2773   [(set (match_operand:SF 0 "register_operand" "=f")
2774         (float:SF (match_operand:SI 1 "register_operand" "f")))]
2775   "TARGET_HARD_FLOAT"
2776   "cvt.s.w\t%0,%1"
2777   [(set_attr "type"     "fcvt")
2778    (set_attr "mode"     "SF")
2779    (set_attr "cnv_mode" "I2S")   
2780    (set_attr "length"   "4")])
2781
2782
2783 (define_insn "floatdisf2"
2784   [(set (match_operand:SF 0 "register_operand" "=f")
2785         (float:SF (match_operand:DI 1 "register_operand" "f")))]
2786   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2787   "cvt.s.l\t%0,%1"
2788   [(set_attr "type"     "fcvt")
2789    (set_attr "mode"     "SF")
2790    (set_attr "cnv_mode" "I2S")   
2791    (set_attr "length"   "4")])
2792
2793
2794 (define_expand "fixuns_truncdfsi2"
2795   [(set (match_operand:SI 0 "register_operand")
2796         (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
2797   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2798 {
2799   rtx reg1 = gen_reg_rtx (DFmode);
2800   rtx reg2 = gen_reg_rtx (DFmode);
2801   rtx reg3 = gen_reg_rtx (SImode);
2802   rtx label1 = gen_label_rtx ();
2803   rtx label2 = gen_label_rtx ();
2804   REAL_VALUE_TYPE offset;
2805
2806   real_2expN (&offset, 31);
2807
2808   if (reg1)                     /* Turn off complaints about unreached code.  */
2809     {
2810       emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2811       do_pending_stack_adjust ();
2812
2813       emit_insn (gen_cmpdf (operands[1], reg1));
2814       emit_jump_insn (gen_bge (label1));
2815
2816       emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
2817       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2818                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
2819       emit_barrier ();
2820
2821       emit_label (label1);
2822       emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
2823       emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
2824                                      (BITMASK_HIGH, SImode)));
2825
2826       emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
2827       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2828
2829       emit_label (label2);
2830
2831       /* Allow REG_NOTES to be set on last insn (labels don't have enough
2832          fields, and can't be used for REG_NOTES anyway).  */
2833       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2834       DONE;
2835     }
2836 })
2837
2838
2839 (define_expand "fixuns_truncdfdi2"
2840   [(set (match_operand:DI 0 "register_operand")
2841         (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
2842   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2843 {
2844   rtx reg1 = gen_reg_rtx (DFmode);
2845   rtx reg2 = gen_reg_rtx (DFmode);
2846   rtx reg3 = gen_reg_rtx (DImode);
2847   rtx label1 = gen_label_rtx ();
2848   rtx label2 = gen_label_rtx ();
2849   REAL_VALUE_TYPE offset;
2850
2851   real_2expN (&offset, 63);
2852
2853   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2854   do_pending_stack_adjust ();
2855
2856   emit_insn (gen_cmpdf (operands[1], reg1));
2857   emit_jump_insn (gen_bge (label1));
2858
2859   emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
2860   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2861                                gen_rtx_LABEL_REF (VOIDmode, label2)));
2862   emit_barrier ();
2863
2864   emit_label (label1);
2865   emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
2866   emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
2867   emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
2868
2869   emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
2870   emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
2871
2872   emit_label (label2);
2873
2874   /* Allow REG_NOTES to be set on last insn (labels don't have enough
2875      fields, and can't be used for REG_NOTES anyway).  */
2876   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2877   DONE;
2878 })
2879
2880
2881 (define_expand "fixuns_truncsfsi2"
2882   [(set (match_operand:SI 0 "register_operand")
2883         (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
2884   "TARGET_HARD_FLOAT"
2885 {
2886   rtx reg1 = gen_reg_rtx (SFmode);
2887   rtx reg2 = gen_reg_rtx (SFmode);
2888   rtx reg3 = gen_reg_rtx (SImode);
2889   rtx label1 = gen_label_rtx ();
2890   rtx label2 = gen_label_rtx ();
2891   REAL_VALUE_TYPE offset;
2892
2893   real_2expN (&offset, 31);
2894
2895   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
2896   do_pending_stack_adjust ();
2897
2898   emit_insn (gen_cmpsf (operands[1], reg1));
2899   emit_jump_insn (gen_bge (label1));
2900
2901   emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
2902   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2903                                gen_rtx_LABEL_REF (VOIDmode, label2)));
2904   emit_barrier ();
2905
2906   emit_label (label1);
2907   emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
2908   emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
2909                                  (BITMASK_HIGH, SImode)));
2910
2911   emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
2912   emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2913
2914   emit_label (label2);
2915
2916   /* Allow REG_NOTES to be set on last insn (labels don't have enough
2917      fields, and can't be used for REG_NOTES anyway).  */
2918   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2919   DONE;
2920 })
2921
2922
2923 (define_expand "fixuns_truncsfdi2"
2924   [(set (match_operand:DI 0 "register_operand")
2925         (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
2926   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2927 {
2928   rtx reg1 = gen_reg_rtx (SFmode);
2929   rtx reg2 = gen_reg_rtx (SFmode);
2930   rtx reg3 = gen_reg_rtx (DImode);
2931   rtx label1 = gen_label_rtx ();
2932   rtx label2 = gen_label_rtx ();
2933   REAL_VALUE_TYPE offset;
2934
2935   real_2expN (&offset, 63);
2936
2937   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
2938   do_pending_stack_adjust ();
2939
2940   emit_insn (gen_cmpsf (operands[1], reg1));
2941   emit_jump_insn (gen_bge (label1));
2942
2943   emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
2944   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2945                                gen_rtx_LABEL_REF (VOIDmode, label2)));
2946   emit_barrier ();
2947
2948   emit_label (label1);
2949   emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
2950   emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
2951   emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
2952
2953   emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
2954   emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
2955
2956   emit_label (label2);
2957
2958   /* Allow REG_NOTES to be set on last insn (labels don't have enough
2959      fields, and can't be used for REG_NOTES anyway).  */
2960   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2961   DONE;
2962 })
2963 \f
2964 ;;
2965 ;;  ....................
2966 ;;
2967 ;;      DATA MOVEMENT
2968 ;;
2969 ;;  ....................
2970
2971 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
2972
2973 (define_expand "extv"
2974   [(set (match_operand 0 "register_operand")
2975         (sign_extract (match_operand:QI 1 "memory_operand")
2976                       (match_operand 2 "immediate_operand")
2977                       (match_operand 3 "immediate_operand")))]
2978   "!TARGET_MIPS16"
2979 {
2980   if (mips_expand_unaligned_load (operands[0], operands[1],
2981                                   INTVAL (operands[2]),
2982                                   INTVAL (operands[3])))
2983     DONE;
2984   else
2985     FAIL;
2986 })
2987
2988 (define_expand "extzv"
2989   [(set (match_operand 0 "register_operand")
2990         (zero_extract (match_operand 1 "nonimmediate_operand")
2991                       (match_operand 2 "immediate_operand")
2992                       (match_operand 3 "immediate_operand")))]
2993   "!TARGET_MIPS16"
2994 {
2995   if (mips_expand_unaligned_load (operands[0], operands[1],
2996                                   INTVAL (operands[2]),
2997                                   INTVAL (operands[3])))
2998     DONE;
2999   else if (mips_use_ins_ext_p (operands[1], operands[2], operands[3]))
3000     {
3001       if (GET_MODE (operands[0]) == DImode)
3002         emit_insn (gen_extzvdi (operands[0], operands[1], operands[2],
3003                                 operands[3]));
3004       else
3005         emit_insn (gen_extzvsi (operands[0], operands[1], operands[2],
3006                                 operands[3]));
3007       DONE;
3008     }
3009   else
3010     FAIL;
3011 })
3012
3013 (define_insn "extzv<mode>"
3014   [(set (match_operand:GPR 0 "register_operand" "=d")
3015         (zero_extract:GPR (match_operand:GPR 1 "register_operand" "d")
3016                           (match_operand:SI 2 "immediate_operand" "I")
3017                           (match_operand:SI 3 "immediate_operand" "I")))]
3018   "mips_use_ins_ext_p (operands[1], operands[2], operands[3])"
3019   "<d>ext\t%0,%1,%3,%2"
3020   [(set_attr "type"     "arith")
3021    (set_attr "mode"     "<MODE>")])
3022
3023
3024 (define_expand "insv"
3025   [(set (zero_extract (match_operand 0 "nonimmediate_operand")
3026                       (match_operand 1 "immediate_operand")
3027                       (match_operand 2 "immediate_operand"))
3028         (match_operand 3 "reg_or_0_operand"))]
3029   "!TARGET_MIPS16"
3030 {
3031   if (mips_expand_unaligned_store (operands[0], operands[3],
3032                                    INTVAL (operands[1]),
3033                                    INTVAL (operands[2])))
3034     DONE;
3035   else if (mips_use_ins_ext_p (operands[0], operands[1], operands[2]))
3036     {
3037       if (GET_MODE (operands[0]) == DImode)
3038         emit_insn (gen_insvdi (operands[0], operands[1], operands[2],
3039                                operands[3]));
3040       else
3041         emit_insn (gen_insvsi (operands[0], operands[1], operands[2],
3042                                operands[3]));
3043       DONE;
3044    }
3045    else
3046      FAIL;
3047 })
3048
3049 (define_insn "insv<mode>"
3050   [(set (zero_extract:GPR (match_operand:GPR 0 "register_operand" "+d")
3051                           (match_operand:SI 1 "immediate_operand" "I")
3052                           (match_operand:SI 2 "immediate_operand" "I"))
3053         (match_operand:GPR 3 "reg_or_0_operand" "dJ"))]
3054   "mips_use_ins_ext_p (operands[0], operands[1], operands[2])"
3055   "<d>ins\t%0,%z3,%2,%1"
3056   [(set_attr "type"     "arith")
3057    (set_attr "mode"     "<MODE>")])
3058
3059 ;; Unaligned word moves generated by the bit field patterns.
3060 ;;
3061 ;; As far as the rtl is concerned, both the left-part and right-part
3062 ;; instructions can access the whole field.  However, the real operand
3063 ;; refers to just the first or the last byte (depending on endianness).
3064 ;; We therefore use two memory operands to each instruction, one to
3065 ;; describe the rtl effect and one to use in the assembly output.
3066 ;;
3067 ;; Operands 0 and 1 are the rtl-level target and source respectively.
3068 ;; This allows us to use the standard length calculations for the "load"
3069 ;; and "store" type attributes.
3070
3071 (define_insn "mov_<load>l"
3072   [(set (match_operand:GPR 0 "register_operand" "=d")
3073         (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
3074                      (match_operand:QI 2 "memory_operand" "m")]
3075                     UNSPEC_LOAD_LEFT))]
3076   "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
3077   "<load>l\t%0,%2"
3078   [(set_attr "type" "load")
3079    (set_attr "mode" "<MODE>")])
3080
3081 (define_insn "mov_<load>r"
3082   [(set (match_operand:GPR 0 "register_operand" "=d")
3083         (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
3084                      (match_operand:QI 2 "memory_operand" "m")
3085                      (match_operand:GPR 3 "register_operand" "0")]
3086                     UNSPEC_LOAD_RIGHT))]
3087   "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
3088   "<load>r\t%0,%2"
3089   [(set_attr "type" "load")
3090    (set_attr "mode" "<MODE>")])
3091
3092 (define_insn "mov_<store>l"
3093   [(set (match_operand:BLK 0 "memory_operand" "=m")
3094         (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3095                      (match_operand:QI 2 "memory_operand" "m")]
3096                     UNSPEC_STORE_LEFT))]
3097   "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
3098   "<store>l\t%z1,%2"
3099   [(set_attr "type" "store")
3100    (set_attr "mode" "<MODE>")])
3101
3102 (define_insn "mov_<store>r"
3103   [(set (match_operand:BLK 0 "memory_operand" "+m")
3104         (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3105                      (match_operand:QI 2 "memory_operand" "m")
3106                      (match_dup 0)]
3107                     UNSPEC_STORE_RIGHT))]
3108   "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
3109   "<store>r\t%z1,%2"
3110   [(set_attr "type" "store")
3111    (set_attr "mode" "<MODE>")])
3112
3113 ;; An instruction to calculate the high part of a 64-bit SYMBOL_GENERAL.
3114 ;; The required value is:
3115 ;;
3116 ;;      (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
3117 ;;
3118 ;; which translates to:
3119 ;;
3120 ;;      lui     op0,%highest(op1)
3121 ;;      daddiu  op0,op0,%higher(op1)
3122 ;;      dsll    op0,op0,16
3123 ;;      daddiu  op0,op0,%hi(op1)
3124 ;;      dsll    op0,op0,16
3125 ;;
3126 ;; The split is deferred until after flow2 to allow the peephole2 below
3127 ;; to take effect.
3128 (define_insn_and_split "*lea_high64"
3129   [(set (match_operand:DI 0 "register_operand" "=d")
3130         (high:DI (match_operand:DI 1 "general_symbolic_operand" "")))]
3131   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3132   "#"
3133   "&& epilogue_completed"
3134   [(set (match_dup 0) (high:DI (match_dup 2)))
3135    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
3136    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
3137    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3138    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
3139 {
3140   operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3141   operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
3142 }
3143   [(set_attr "length" "20")])
3144
3145 ;; Use a scratch register to reduce the latency of the above pattern
3146 ;; on superscalar machines.  The optimized sequence is:
3147 ;;
3148 ;;      lui     op1,%highest(op2)
3149 ;;      lui     op0,%hi(op2)
3150 ;;      daddiu  op1,op1,%higher(op2)
3151 ;;      dsll32  op1,op1,0
3152 ;;      daddu   op1,op1,op0
3153 (define_peephole2
3154   [(set (match_operand:DI 1 "register_operand")
3155         (high:DI (match_operand:DI 2 "general_symbolic_operand")))
3156    (match_scratch:DI 0 "d")]
3157   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3158   [(set (match_dup 1) (high:DI (match_dup 3)))
3159    (set (match_dup 0) (high:DI (match_dup 4)))
3160    (set (match_dup 1) (lo_sum:DI (match_dup 1) (match_dup 3)))
3161    (set (match_dup 1) (ashift:DI (match_dup 1) (const_int 32)))
3162    (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 0)))]
3163 {
3164   operands[3] = mips_unspec_address (operands[2], SYMBOL_64_HIGH);
3165   operands[4] = mips_unspec_address (operands[2], SYMBOL_64_LOW);
3166 })
3167
3168 ;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
3169 ;; SYMBOL_GENERAL X will take 6 cycles.  This next pattern allows combine
3170 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
3171 ;; used once.  We can then use the sequence:
3172 ;;
3173 ;;      lui     op0,%highest(op1)
3174 ;;      lui     op2,%hi(op1)
3175 ;;      daddiu  op0,op0,%higher(op1)
3176 ;;      daddiu  op2,op2,%lo(op1)
3177 ;;      dsll32  op0,op0,0
3178 ;;      daddu   op0,op0,op2
3179 ;;
3180 ;; which takes 4 cycles on most superscalar targets.
3181 (define_insn_and_split "*lea64"
3182   [(set (match_operand:DI 0 "register_operand" "=d")
3183         (match_operand:DI 1 "general_symbolic_operand" ""))
3184    (clobber (match_scratch:DI 2 "=&d"))]
3185   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
3186   "#"
3187   "&& reload_completed"
3188   [(set (match_dup 0) (high:DI (match_dup 3)))
3189    (set (match_dup 2) (high:DI (match_dup 4)))
3190    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3191    (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
3192    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
3193    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
3194 {
3195   operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3196   operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
3197 }
3198   [(set_attr "length" "24")])
3199
3200 ;; Insns to fetch a symbol from a big GOT.
3201
3202 (define_insn_and_split "*xgot_hi<mode>"
3203   [(set (match_operand:P 0 "register_operand" "=d")
3204         (high:P (match_operand:P 1 "got_disp_operand" "")))]
3205   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3206   "#"
3207   "&& reload_completed"
3208   [(set (match_dup 0) (high:P (match_dup 2)))
3209    (set (match_dup 0) (plus:P (match_dup 0) (match_dup 3)))]
3210 {
3211   operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_DISP);
3212   operands[3] = pic_offset_table_rtx;
3213 }
3214   [(set_attr "got" "xgot_high")
3215    (set_attr "mode" "<MODE>")])
3216
3217 (define_insn_and_split "*xgot_lo<mode>"
3218   [(set (match_operand:P 0 "register_operand" "=d")
3219         (lo_sum:P (match_operand:P 1 "register_operand" "d")
3220                   (match_operand:P 2 "got_disp_operand" "")))]
3221   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3222   "#"
3223   "&& reload_completed"
3224   [(set (match_dup 0)
3225         (unspec:P [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3226   { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_DISP); }
3227   [(set_attr "got" "load")
3228    (set_attr "mode" "<MODE>")])
3229
3230 ;; Insns to fetch a symbol from a normal GOT.
3231
3232 (define_insn_and_split "*got_disp<mode>"
3233   [(set (match_operand:P 0 "register_operand" "=d")
3234         (match_operand:P 1 "got_disp_operand" ""))]
3235   "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3236   "#"
3237   "&& reload_completed"
3238   [(set (match_dup 0)
3239         (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3240 {
3241   operands[2] = pic_offset_table_rtx;
3242   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_DISP);
3243 }
3244   [(set_attr "got" "load")
3245    (set_attr "mode" "<MODE>")])
3246
3247 ;; Insns for loading the "page" part of a page/ofst address from the GOT.
3248
3249 (define_insn_and_split "*got_page<mode>"
3250   [(set (match_operand:P 0 "register_operand" "=d")
3251         (high:P (match_operand:P 1 "got_page_ofst_operand" "")))]
3252   "TARGET_EXPLICIT_RELOCS"
3253   "#"
3254   "&& reload_completed"
3255   [(set (match_dup 0)
3256         (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3257 {
3258   operands[2] = pic_offset_table_rtx;
3259   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3260 }
3261   [(set_attr "got" "load")
3262    (set_attr "mode" "<MODE>")])
3263
3264 ;; Lower-level instructions for loading an address from the GOT.
3265 ;; We could use MEMs, but an unspec gives more optimization
3266 ;; opportunities.
3267
3268 (define_insn "load_got<mode>"
3269   [(set (match_operand:P 0 "register_operand" "=d")
3270         (unspec:P [(match_operand:P 1 "register_operand" "d")
3271                    (match_operand:P 2 "immediate_operand" "")]
3272                   UNSPEC_LOAD_GOT))]
3273   ""
3274   "<load>\t%0,%R2(%1)"
3275   [(set_attr "type" "load")
3276    (set_attr "mode" "<MODE>")
3277    (set_attr "length" "4")])
3278
3279 ;; Instructions for adding the low 16 bits of an address to a register.
3280 ;; Operand 2 is the address: print_operand works out which relocation
3281 ;; should be applied.
3282
3283 (define_insn "*low<mode>"
3284   [(set (match_operand:P 0 "register_operand" "=d")
3285         (lo_sum:P (match_operand:P 1 "register_operand" "d")
3286                   (match_operand:P 2 "immediate_operand" "")))]
3287   "!TARGET_MIPS16"
3288   "<d>addiu\t%0,%1,%R2"
3289   [(set_attr "type" "arith")
3290    (set_attr "mode" "<MODE>")])
3291
3292 (define_insn "*low<mode>_mips16"
3293   [(set (match_operand:P 0 "register_operand" "=d")
3294         (lo_sum:P (match_operand:P 1 "register_operand" "0")
3295                   (match_operand:P 2 "immediate_operand" "")))]
3296   "TARGET_MIPS16"
3297   "<d>addiu\t%0,%R2"
3298   [(set_attr "type" "arith")
3299    (set_attr "mode" "<MODE>")
3300    (set_attr "length" "8")])
3301
3302 ;; Allow combine to split complex const_int load sequences, using operand 2
3303 ;; to store the intermediate results.  See move_operand for details.
3304 (define_split
3305   [(set (match_operand:GPR 0 "register_operand")
3306         (match_operand:GPR 1 "splittable_const_int_operand"))
3307    (clobber (match_operand:GPR 2 "register_operand"))]
3308   ""
3309   [(const_int 0)]
3310 {
3311   mips_move_integer (operands[0], operands[2], INTVAL (operands[1]));
3312   DONE;
3313 })
3314
3315 ;; Likewise, for symbolic operands.
3316 (define_split
3317   [(set (match_operand:P 0 "register_operand")
3318         (match_operand:P 1 "splittable_symbolic_operand"))
3319    (clobber (match_operand:P 2 "register_operand"))]
3320   ""
3321   [(set (match_dup 0) (match_dup 1))]
3322   { operands[1] = mips_split_symbol (operands[2], operands[1]); })
3323
3324 ;; 64-bit integer moves
3325
3326 ;; Unlike most other insns, the move insns can't be split with
3327 ;; different predicates, because register spilling and other parts of
3328 ;; the compiler, have memoized the insn number already.
3329
3330 (define_expand "movdi"
3331   [(set (match_operand:DI 0 "")
3332         (match_operand:DI 1 ""))]
3333   ""
3334 {
3335   if (mips_legitimize_move (DImode, operands[0], operands[1]))
3336     DONE;
3337 })
3338
3339 ;; For mips16, we need a special case to handle storing $31 into
3340 ;; memory, since we don't have a constraint to match $31.  This
3341 ;; instruction can be generated by save_restore_insns.
3342
3343 (define_insn "*mov<mode>_ra"
3344   [(set (match_operand:GPR 0 "stack_operand" "=m")
3345         (reg:GPR 31))]
3346   "TARGET_MIPS16"
3347   "<store>\t$31,%0"
3348   [(set_attr "type" "store")
3349    (set_attr "mode" "<MODE>")])
3350
3351 (define_insn "*movdi_32bit"
3352   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*a,*d,*B*C*D,*B*C*D,*d,*m")
3353         (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*a,*d,*m,*B*C*D,*B*C*D"))]
3354   "!TARGET_64BIT && !TARGET_FLOAT64 && !TARGET_MIPS16
3355    && (register_operand (operands[0], DImode)
3356        || reg_or_0_operand (operands[1], DImode))"
3357   { return mips_output_move (operands[0], operands[1]); }
3358   [(set_attr "type"     "multi,multi,load,store,mthilo,mfhilo,mtc,load,mfc,store")
3359    (set_attr "mode"     "DI")
3360    (set_attr "length"   "8,16,*,*,8,8,8,*,8,*")])
3361
3362 (define_insn "*movdi_gp32_fp64"
3363   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*a,*d,*f,*f,*f,*d,*m")
3364         (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*a,*f,*J*d,*m,*f,*f"))]
3365   "!TARGET_64BIT && TARGET_FLOAT64 && !TARGET_MIPS16
3366    && (register_operand (operands[0], DImode)
3367        || reg_or_0_operand (operands[1], DImode))"
3368   { return mips_output_move (operands[0], operands[1]); }
3369   [(set_attr "type"     "multi,multi,load,store,mthilo,mfhilo,fmove,mtc,fpload,mfc,fpstore")
3370    (set_attr "mode"     "DI")
3371    (set_attr "length"   "8,16,*,*,8,8,4,8,*,8,*")])
3372
3373 (define_insn "*movdi_32bit_mips16"
3374   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
3375         (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
3376   "!TARGET_64BIT && TARGET_MIPS16
3377    && (register_operand (operands[0], DImode)
3378        || register_operand (operands[1], DImode))"
3379   { return mips_output_move (operands[0], operands[1]); }
3380   [(set_attr "type"     "multi,multi,multi,multi,multi,load,store,mfhilo")
3381    (set_attr "mode"     "DI")
3382    (set_attr "length"   "8,8,8,8,12,*,*,8")])
3383
3384 (define_insn "*movdi_64bit"
3385   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*x,*B*C*D,*B*C*D,*d,*m")
3386         (match_operand:DI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*J*d,*d,*m,*B*C*D,*B*C*D"))]
3387   "TARGET_64BIT && !TARGET_MIPS16
3388    && (register_operand (operands[0], DImode)
3389        || reg_or_0_operand (operands[1], DImode))"
3390   { return mips_output_move (operands[0], operands[1]); }
3391   [(set_attr "type"     "move,const,const,load,store,fmove,mtc,fpload,mfc,fpstore,mthilo,mtc,load,mfc,store")
3392    (set_attr "mode"     "DI")
3393    (set_attr "length"   "4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")])
3394
3395 (define_insn "*movdi_64bit_mips16"
3396   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3397         (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3398   "TARGET_64BIT && TARGET_MIPS16
3399    && (register_operand (operands[0], DImode)
3400        || register_operand (operands[1], DImode))"
3401   { return mips_output_move (operands[0], operands[1]); }
3402   [(set_attr "type"     "move,move,move,arith,arith,const,load,store")
3403    (set_attr "mode"     "DI")
3404    (set_attr_alternative "length"
3405                 [(const_int 4)
3406                  (const_int 4)
3407                  (const_int 4)
3408                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3409                                (const_int 4)
3410                                (const_int 8))
3411                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3412                                (const_int 8)
3413                                (const_int 12))
3414                  (const_string "*")
3415                  (const_string "*")
3416                  (const_string "*")])])
3417
3418
3419 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
3420 ;; when the original load is a 4 byte instruction but the add and the
3421 ;; load are 2 2 byte instructions.
3422
3423 (define_split
3424   [(set (match_operand:DI 0 "register_operand")
3425         (mem:DI (plus:DI (match_dup 0)
3426                          (match_operand:DI 1 "const_int_operand"))))]
3427   "TARGET_64BIT && TARGET_MIPS16 && reload_completed
3428    && !TARGET_DEBUG_D_MODE
3429    && REG_P (operands[0])
3430    && M16_REG_P (REGNO (operands[0]))
3431    && GET_CODE (operands[1]) == CONST_INT
3432    && ((INTVAL (operands[1]) < 0
3433         && INTVAL (operands[1]) >= -0x10)
3434        || (INTVAL (operands[1]) >= 32 * 8
3435            && INTVAL (operands[1]) <= 31 * 8 + 0x8)
3436        || (INTVAL (operands[1]) >= 0
3437            && INTVAL (operands[1]) < 32 * 8
3438            && (INTVAL (operands[1]) & 7) != 0))"
3439   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
3440    (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
3441 {
3442   HOST_WIDE_INT val = INTVAL (operands[1]);
3443
3444   if (val < 0)
3445     operands[2] = const0_rtx;
3446   else if (val >= 32 * 8)
3447     {
3448       int off = val & 7;
3449
3450       operands[1] = GEN_INT (0x8 + off);
3451       operands[2] = GEN_INT (val - off - 0x8);
3452     }
3453   else
3454     {
3455       int off = val & 7;
3456
3457       operands[1] = GEN_INT (off);
3458       operands[2] = GEN_INT (val - off);
3459     }
3460 })
3461
3462 ;; 32-bit Integer moves
3463
3464 ;; Unlike most other insns, the move insns can't be split with
3465 ;; different predicates, because register spilling and other parts of
3466 ;; the compiler, have memoized the insn number already.
3467
3468 (define_expand "movsi"
3469   [(set (match_operand:SI 0 "")
3470         (match_operand:SI 1 ""))]
3471   ""
3472 {
3473   if (mips_legitimize_move (SImode, operands[0], operands[1]))
3474     DONE;
3475 })
3476
3477 ;; The difference between these two is whether or not ints are allowed
3478 ;; in FP registers (off by default, use -mdebugh to enable).
3479
3480 (define_insn "*movsi_internal"
3481   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*d,*z,*a,*d,*B*C*D,*B*C*D,*d,*m")
3482         (match_operand:SI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*z,*d,*J*d,*A,*d,*m,*B*C*D,*B*C*D"))]
3483   "!TARGET_MIPS16
3484    && (register_operand (operands[0], SImode)
3485        || reg_or_0_operand (operands[1], SImode))"
3486   { return mips_output_move (operands[0], operands[1]); }
3487   [(set_attr "type"     "move,const,const,load,store,fmove,mtc,fpload,mfc,fpstore,mfc,mtc,mthilo,mfhilo,mtc,load,mfc,store")
3488    (set_attr "mode"     "SI")
3489    (set_attr "length"   "4,*,*,*,*,4,4,*,4,*,4,4,4,4,4,*,4,*")])
3490
3491 (define_insn "*movsi_mips16"
3492   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3493         (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3494   "TARGET_MIPS16
3495    && (register_operand (operands[0], SImode)
3496        || register_operand (operands[1], SImode))"
3497   { return mips_output_move (operands[0], operands[1]); }
3498   [(set_attr "type"     "move,move,move,arith,arith,const,load,store")
3499    (set_attr "mode"     "SI")
3500    (set_attr_alternative "length"
3501                 [(const_int 4)
3502                  (const_int 4)
3503                  (const_int 4)
3504                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3505                                (const_int 4)
3506                                (const_int 8))
3507                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3508                                (const_int 8)
3509                                (const_int 12))
3510                  (const_string "*")
3511                  (const_string "*")
3512                  (const_string "*")])])
3513
3514 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
3515 ;; when the original load is a 4 byte instruction but the add and the
3516 ;; load are 2 2 byte instructions.
3517
3518 (define_split
3519   [(set (match_operand:SI 0 "register_operand")
3520         (mem:SI (plus:SI (match_dup 0)
3521                          (match_operand:SI 1 "const_int_operand"))))]
3522   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3523    && REG_P (operands[0])
3524    && M16_REG_P (REGNO (operands[0]))
3525    && GET_CODE (operands[1]) == CONST_INT
3526    && ((INTVAL (operands[1]) < 0
3527         && INTVAL (operands[1]) >= -0x80)
3528        || (INTVAL (operands[1]) >= 32 * 4
3529            && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
3530        || (INTVAL (operands[1]) >= 0
3531            && INTVAL (operands[1]) < 32 * 4
3532            && (INTVAL (operands[1]) & 3) != 0))"
3533   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3534    (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
3535 {
3536   HOST_WIDE_INT val = INTVAL (operands[1]);
3537
3538   if (val < 0)
3539     operands[2] = const0_rtx;
3540   else if (val >= 32 * 4)
3541     {
3542       int off = val & 3;
3543
3544       operands[1] = GEN_INT (0x7c + off);
3545       operands[2] = GEN_INT (val - off - 0x7c);
3546     }
3547   else
3548     {
3549       int off = val & 3;
3550
3551       operands[1] = GEN_INT (off);
3552       operands[2] = GEN_INT (val - off);
3553     }
3554 })
3555
3556 ;; On the mips16, we can split a load of certain constants into a load
3557 ;; and an add.  This turns a 4 byte instruction into 2 2 byte
3558 ;; instructions.
3559
3560 (define_split
3561   [(set (match_operand:SI 0 "register_operand")
3562         (match_operand:SI 1 "const_int_operand"))]
3563   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3564    && REG_P (operands[0])
3565    && M16_REG_P (REGNO (operands[0]))
3566    && GET_CODE (operands[1]) == CONST_INT
3567    && INTVAL (operands[1]) >= 0x100
3568    && INTVAL (operands[1]) <= 0xff + 0x7f"
3569   [(set (match_dup 0) (match_dup 1))
3570    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
3571 {
3572   int val = INTVAL (operands[1]);
3573
3574   operands[1] = GEN_INT (0xff);
3575   operands[2] = GEN_INT (val - 0xff);
3576 })
3577
3578 ;; This insn handles moving CCmode values.  It's really just a
3579 ;; slightly simplified copy of movsi_internal2, with additional cases
3580 ;; to move a condition register to a general register and to move
3581 ;; between the general registers and the floating point registers.
3582
3583 (define_insn "movcc"
3584   [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m")
3585         (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))]
3586   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3587   { return mips_output_move (operands[0], operands[1]); }
3588   [(set_attr "type"     "multi,move,load,store,mfc,mtc,fmove,fpload,fpstore")
3589    (set_attr "mode"     "SI")
3590    (set_attr "length"   "8,4,*,*,4,4,4,*,*")])
3591
3592 ;; Reload condition code registers.  reload_incc and reload_outcc
3593 ;; both handle moves from arbitrary operands into condition code
3594 ;; registers.  reload_incc handles the more common case in which
3595 ;; a source operand is constrained to be in a condition-code
3596 ;; register, but has not been allocated to one.
3597 ;;
3598 ;; Sometimes, such as in movcc, we have a CCmode destination whose
3599 ;; constraints do not include 'z'.  reload_outcc handles the case
3600 ;; when such an operand is allocated to a condition-code register.
3601 ;;
3602 ;; Note that reloads from a condition code register to some
3603 ;; other location can be done using ordinary moves.  Moving
3604 ;; into a GPR takes a single movcc, moving elsewhere takes
3605 ;; two.  We can leave these cases to the generic reload code.
3606 (define_expand "reload_incc"
3607   [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
3608         (match_operand:CC 1 "general_operand" ""))
3609    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3610   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3611 {
3612   mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
3613   DONE;
3614 })
3615
3616 (define_expand "reload_outcc"
3617   [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
3618         (match_operand:CC 1 "register_operand" ""))
3619    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3620   "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3621 {
3622   mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
3623   DONE;
3624 })
3625
3626 ;; MIPS4 supports loading and storing a floating point register from
3627 ;; the sum of two general registers.  We use two versions for each of
3628 ;; these four instructions: one where the two general registers are
3629 ;; SImode, and one where they are DImode.  This is because general
3630 ;; registers will be in SImode when they hold 32-bit values, but,
3631 ;; since the 32-bit values are always sign extended, the [ls][wd]xc1
3632 ;; instructions will still work correctly.
3633
3634 ;; ??? Perhaps it would be better to support these instructions by
3635 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends.  However, since
3636 ;; these instructions can only be used to load and store floating
3637 ;; point registers, that would probably cause trouble in reload.
3638
3639 (define_insn "*<ANYF:loadx>_<P:mode>"
3640   [(set (match_operand:ANYF 0 "register_operand" "=f")
3641         (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d")
3642                           (match_operand:P 2 "register_operand" "d"))))]
3643   "ISA_HAS_FP4"
3644   "<ANYF:loadx>\t%0,%1(%2)"
3645   [(set_attr "type" "fpidxload")
3646    (set_attr "mode" "<ANYF:UNITMODE>")])
3647
3648 (define_insn "*<ANYF:storex>_<P:mode>"
3649   [(set (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d")
3650                           (match_operand:P 2 "register_operand" "d")))
3651         (match_operand:ANYF 0 "register_operand" "f"))]
3652   "ISA_HAS_FP4"
3653   "<ANYF:storex>\t%0,%1(%2)"
3654   [(set_attr "type" "fpidxstore")
3655    (set_attr "mode" "<ANYF:UNITMODE>")])
3656
3657 ;; 16-bit Integer moves
3658
3659 ;; Unlike most other insns, the move insns can't be split with
3660 ;; different predicates, because register spilling and other parts of
3661 ;; the compiler, have memoized the insn number already.
3662 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
3663
3664 (define_expand "movhi"
3665   [(set (match_operand:HI 0 "")
3666         (match_operand:HI 1 ""))]
3667   ""
3668 {
3669   if (mips_legitimize_move (HImode, operands[0], operands[1]))
3670     DONE;
3671 })
3672
3673 (define_insn "*movhi_internal"
3674   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
3675         (match_operand:HI 1 "move_operand"         "d,I,m,dJ,*f,*d,*f,*d"))]
3676   "!TARGET_MIPS16
3677    && (register_operand (operands[0], HImode)
3678        || reg_or_0_operand (operands[1], HImode))"
3679   "@
3680     move\t%0,%1
3681     li\t%0,%1
3682     lhu\t%0,%1
3683     sh\t%z1,%0
3684     mfc1\t%0,%1
3685     mtc1\t%1,%0
3686     mov.s\t%0,%1
3687     mt%0\t%1"
3688   [(set_attr "type"     "move,arith,load,store,mfc,mtc,fmove,mthilo")
3689    (set_attr "mode"     "HI")
3690    (set_attr "length"   "4,4,*,*,4,4,4,4")])
3691
3692 (define_insn "*movhi_mips16"
3693   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
3694         (match_operand:HI 1 "move_operand"         "d,d,y,K,N,m,d"))]
3695   "TARGET_MIPS16
3696    && (register_operand (operands[0], HImode)
3697        || register_operand (operands[1], HImode))"
3698   "@
3699     move\t%0,%1
3700     move\t%0,%1
3701     move\t%0,%1
3702     li\t%0,%1
3703     #
3704     lhu\t%0,%1
3705     sh\t%1,%0"
3706   [(set_attr "type"     "move,move,move,arith,arith,load,store")
3707    (set_attr "mode"     "HI")
3708    (set_attr_alternative "length"
3709                 [(const_int 4)
3710                  (const_int 4)
3711                  (const_int 4)
3712                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3713                                (const_int 4)
3714                                (const_int 8))
3715                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3716                                (const_int 8)
3717                                (const_int 12))
3718                  (const_string "*")
3719                  (const_string "*")])])
3720
3721
3722 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
3723 ;; when the original load is a 4 byte instruction but the add and the
3724 ;; load are 2 2 byte instructions.
3725
3726 (define_split
3727   [(set (match_operand:HI 0 "register_operand")
3728         (mem:HI (plus:SI (match_dup 0)
3729                          (match_operand:SI 1 "const_int_operand"))))]
3730   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3731    && REG_P (operands[0])
3732    && M16_REG_P (REGNO (operands[0]))
3733    && GET_CODE (operands[1]) == CONST_INT
3734    && ((INTVAL (operands[1]) < 0
3735         && INTVAL (operands[1]) >= -0x80)
3736        || (INTVAL (operands[1]) >= 32 * 2
3737            && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
3738        || (INTVAL (operands[1]) >= 0
3739            && INTVAL (operands[1]) < 32 * 2
3740            && (INTVAL (operands[1]) & 1) != 0))"
3741   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3742    (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
3743 {
3744   HOST_WIDE_INT val = INTVAL (operands[1]);
3745
3746   if (val < 0)
3747     operands[2] = const0_rtx;
3748   else if (val >= 32 * 2)
3749     {
3750       int off = val & 1;
3751
3752       operands[1] = GEN_INT (0x7e + off);
3753       operands[2] = GEN_INT (val - off - 0x7e);
3754     }
3755   else
3756     {
3757       int off = val & 1;
3758
3759       operands[1] = GEN_INT (off);
3760       operands[2] = GEN_INT (val - off);
3761     }
3762 })
3763
3764 ;; 8-bit Integer moves
3765
3766 ;; Unlike most other insns, the move insns can't be split with
3767 ;; different predicates, because register spilling and other parts of
3768 ;; the compiler, have memoized the insn number already.
3769 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
3770
3771 (define_expand "movqi"
3772   [(set (match_operand:QI 0 "")
3773         (match_operand:QI 1 ""))]
3774   ""
3775 {
3776   if (mips_legitimize_move (QImode, operands[0], operands[1]))
3777     DONE;
3778 })
3779
3780 (define_insn "*movqi_internal"
3781   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
3782         (match_operand:QI 1 "move_operand"         "d,I,m,dJ,*f,*d,*f,*d"))]
3783   "!TARGET_MIPS16
3784    && (register_operand (operands[0], QImode)
3785        || reg_or_0_operand (operands[1], QImode))"
3786   "@
3787     move\t%0,%1
3788     li\t%0,%1
3789     lbu\t%0,%1
3790     sb\t%z1,%0
3791     mfc1\t%0,%1
3792     mtc1\t%1,%0
3793     mov.s\t%0,%1
3794     mt%0\t%1"
3795   [(set_attr "type"     "move,arith,load,store,mfc,mtc,fmove,mthilo")
3796    (set_attr "mode"     "QI")
3797    (set_attr "length"   "4,4,*,*,4,4,4,4")])
3798
3799 (define_insn "*movqi_mips16"
3800   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
3801         (match_operand:QI 1 "move_operand"         "d,d,y,K,N,m,d"))]
3802   "TARGET_MIPS16
3803    && (register_operand (operands[0], QImode)
3804        || register_operand (operands[1], QImode))"
3805   "@
3806     move\t%0,%1
3807     move\t%0,%1
3808     move\t%0,%1
3809     li\t%0,%1
3810     #
3811     lbu\t%0,%1
3812     sb\t%1,%0"
3813   [(set_attr "type"     "move,move,move,arith,arith,load,store")
3814    (set_attr "mode"     "QI")
3815    (set_attr "length"   "4,4,4,4,8,*,*")])
3816
3817 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
3818 ;; when the original load is a 4 byte instruction but the add and the
3819 ;; load are 2 2 byte instructions.
3820
3821 (define_split
3822   [(set (match_operand:QI 0 "register_operand")
3823         (mem:QI (plus:SI (match_dup 0)
3824                          (match_operand:SI 1 "const_int_operand"))))]
3825   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3826    && REG_P (operands[0])
3827    && M16_REG_P (REGNO (operands[0]))
3828    && GET_CODE (operands[1]) == CONST_INT
3829    && ((INTVAL (operands[1]) < 0
3830         && INTVAL (operands[1]) >= -0x80)
3831        || (INTVAL (operands[1]) >= 32
3832            && INTVAL (operands[1]) <= 31 + 0x7f))"
3833   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3834    (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
3835 {
3836   HOST_WIDE_INT val = INTVAL (operands[1]);
3837
3838   if (val < 0)
3839     operands[2] = const0_rtx;
3840   else
3841     {
3842       operands[1] = GEN_INT (0x7f);
3843       operands[2] = GEN_INT (val - 0x7f);
3844     }
3845 })
3846
3847 ;; 32-bit floating point moves
3848
3849 (define_expand "movsf"
3850   [(set (match_operand:SF 0 "")
3851         (match_operand:SF 1 ""))]
3852   ""
3853 {
3854   if (mips_legitimize_move (SFmode, operands[0], operands[1]))
3855     DONE;
3856 })
3857
3858 (define_insn "*movsf_hardfloat"
3859   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
3860         (match_operand:SF 1 "move_operand" "f,G,m,f,G,*d,*f,*G*d,*m,*d"))]
3861   "TARGET_HARD_FLOAT
3862    && (register_operand (operands[0], SFmode)
3863        || reg_or_0_operand (operands[1], SFmode))"
3864   { return mips_output_move (operands[0], operands[1]); }
3865   [(set_attr "type"     "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
3866    (set_attr "mode"     "SF")
3867    (set_attr "length"   "4,4,*,*,*,4,4,4,*,*")])
3868
3869 (define_insn "*movsf_softfloat"
3870   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
3871         (match_operand:SF 1 "move_operand" "Gd,m,d"))]
3872   "TARGET_SOFT_FLOAT && !TARGET_MIPS16
3873    && (register_operand (operands[0], SFmode)
3874        || reg_or_0_operand (operands[1], SFmode))"
3875   { return mips_output_move (operands[0], operands[1]); }
3876   [(set_attr "type"     "move,load,store")
3877    (set_attr "mode"     "SF")
3878    (set_attr "length"   "4,*,*")])
3879
3880 (define_insn "*movsf_mips16"
3881   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
3882         (match_operand:SF 1 "move_operand" "d,d,y,m,d"))]
3883   "TARGET_MIPS16
3884    && (register_operand (operands[0], SFmode)
3885        || register_operand (operands[1], SFmode))"
3886   { return mips_output_move (operands[0], operands[1]); }
3887   [(set_attr "type"     "move,move,move,load,store")
3888    (set_attr "mode"     "SF")
3889    (set_attr "length"   "4,4,4,*,*")])
3890
3891
3892 ;; 64-bit floating point moves
3893
3894 (define_expand "movdf"
3895   [(set (match_operand:DF 0 "")
3896         (match_operand:DF 1 ""))]
3897   ""
3898 {
3899   if (mips_legitimize_move (DFmode, operands[0], operands[1]))
3900     DONE;
3901 })
3902
3903 (define_insn "*movdf_hardfloat_64bit"
3904   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
3905         (match_operand:DF 1 "move_operand" "f,G,m,f,G,*d,*f,*d*G,*m,*d"))]
3906   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT
3907    && (register_operand (operands[0], DFmode)
3908        || reg_or_0_operand (operands[1], DFmode))"
3909   { return mips_output_move (operands[0], operands[1]); }
3910   [(set_attr "type"     "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
3911    (set_attr "mode"     "DF")
3912    (set_attr "length"   "4,4,*,*,*,4,4,4,*,*")])
3913
3914 ;; This pattern applies to both !TARGET_FLOAT64 and TARGET_FLOAT64.
3915 (define_insn "*movdf_hardfloat_32bit"
3916   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
3917         (match_operand:DF 1 "move_operand" "f,G,m,f,G,*d,*f,*d*G,*m,*d"))]
3918   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT
3919    && (register_operand (operands[0], DFmode)
3920        || reg_or_0_operand (operands[1], DFmode))"
3921   { return mips_output_move (operands[0], operands[1]); }
3922   [(set_attr "type"     "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
3923    (set_attr "mode"     "DF")
3924    (set_attr "length"   "4,8,*,*,*,8,8,8,*,*")])
3925
3926 (define_insn "*movdf_softfloat"
3927   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f")
3928         (match_operand:DF 1 "move_operand" "dG,m,dG,f,d,f"))]
3929   "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
3930    && (register_operand (operands[0], DFmode)
3931        || reg_or_0_operand (operands[1], DFmode))"
3932   { return mips_output_move (operands[0], operands[1]); }
3933   [(set_attr "type"     "multi,load,store,mfc,mtc,fmove")
3934    (set_attr "mode"     "DF")
3935    (set_attr "length"   "8,*,*,4,4,4")])
3936
3937 (define_insn "*movdf_mips16"
3938   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
3939         (match_operand:DF 1 "move_operand" "d,d,y,m,d"))]
3940   "TARGET_MIPS16
3941    && (register_operand (operands[0], DFmode)
3942        || register_operand (operands[1], DFmode))"
3943   { return mips_output_move (operands[0], operands[1]); }
3944   [(set_attr "type"     "multi,multi,multi,load,store")
3945    (set_attr "mode"     "DF")
3946    (set_attr "length"   "8,8,8,*,*")])
3947
3948 (define_split
3949   [(set (match_operand:DI 0 "nonimmediate_operand")
3950         (match_operand:DI 1 "move_operand"))]
3951   "reload_completed && !TARGET_64BIT
3952    && mips_split_64bit_move_p (operands[0], operands[1])"
3953   [(const_int 0)]
3954 {
3955   mips_split_64bit_move (operands[0], operands[1]);
3956   DONE;
3957 })
3958
3959 (define_split
3960   [(set (match_operand:DF 0 "nonimmediate_operand")
3961         (match_operand:DF 1 "move_operand"))]
3962   "reload_completed && !TARGET_64BIT
3963    && mips_split_64bit_move_p (operands[0], operands[1])"
3964   [(const_int 0)]
3965 {
3966   mips_split_64bit_move (operands[0], operands[1]);
3967   DONE;
3968 })
3969
3970 ;; When generating mips16 code, split moves of negative constants into
3971 ;; a positive "li" followed by a negation.
3972 (define_split
3973   [(set (match_operand 0 "register_operand")
3974         (match_operand 1 "const_int_operand"))]
3975   "TARGET_MIPS16 && reload_completed && INTVAL (operands[1]) < 0"
3976   [(set (match_dup 2)
3977         (match_dup 3))
3978    (set (match_dup 2)
3979         (neg:SI (match_dup 2)))]
3980 {
3981   operands[2] = gen_lowpart (SImode, operands[0]);
3982   operands[3] = GEN_INT (-INTVAL (operands[1]));
3983 })
3984
3985 ;; 64-bit paired-single floating point moves
3986
3987 (define_expand "movv2sf"
3988   [(set (match_operand:V2SF 0)
3989         (match_operand:V2SF 1))]
3990   "TARGET_PAIRED_SINGLE_FLOAT"
3991 {
3992   if (mips_legitimize_move (V2SFmode, operands[0], operands[1]))
3993     DONE;
3994 })
3995
3996 (define_insn "movv2sf_hardfloat_64bit"
3997   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
3998         (match_operand:V2SF 1 "move_operand" "f,YG,m,f,YG,*d,*f,*d*YG,*m,*d"))]
3999   "TARGET_PAIRED_SINGLE_FLOAT
4000    && TARGET_64BIT
4001    && (register_operand (operands[0], V2SFmode)
4002        || reg_or_0_operand (operands[1], V2SFmode))"
4003   { return mips_output_move (operands[0], operands[1]); }
4004   [(set_attr "type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
4005    (set_attr "mode" "SF")
4006    (set_attr "length" "4,4,*,*,*,4,4,4,*,*")])
4007
4008 ;; The HI and LO registers are not truly independent.  If we move an mthi
4009 ;; instruction before an mflo instruction, it will make the result of the
4010 ;; mflo unpredictable.  The same goes for mtlo and mfhi.
4011 ;;
4012 ;; We cope with this by making the mflo and mfhi patterns use both HI and LO.
4013 ;; Operand 1 is the register we want, operand 2 is the other one.
4014 ;;
4015 ;; When generating VR4120 or VR4130 code, we use macc{,hi} and
4016 ;; dmacc{,hi} instead of mfhi and mflo.  This avoids both the normal
4017 ;; MIPS III hi/lo hazards and the errata related to -mfix-vr4130.
4018
4019 (define_expand "mfhilo_<mode>"
4020   [(set (match_operand:GPR 0 "register_operand")
4021         (unspec:GPR [(match_operand:GPR 1 "register_operand")
4022                      (match_operand:GPR 2 "register_operand")]
4023                     UNSPEC_MFHILO))])
4024
4025 (define_insn "*mfhilo_<mode>"
4026   [(set (match_operand:GPR 0 "register_operand" "=d,d")
4027         (unspec:GPR [(match_operand:GPR 1 "register_operand" "h,l")
4028                      (match_operand:GPR 2 "register_operand" "l,h")]
4029                     UNSPEC_MFHILO))]
4030   "!ISA_HAS_MACCHI"
4031   "mf%1\t%0"
4032   [(set_attr "type" "mfhilo")
4033    (set_attr "mode" "<MODE>")])
4034
4035 (define_insn "*mfhilo_<mode>_macc"
4036   [(set (match_operand:GPR 0 "register_operand" "=d,d")
4037         (unspec:GPR [(match_operand:GPR 1 "register_operand" "h,l")
4038                      (match_operand:GPR 2 "register_operand" "l,h")]
4039                     UNSPEC_MFHILO))]
4040   "ISA_HAS_MACCHI"
4041 {
4042   if (REGNO (operands[1]) == HI_REGNUM)
4043     return "<d>macchi\t%0,%.,%.";
4044   else
4045     return "<d>macc\t%0,%.,%.";
4046 }
4047   [(set_attr "type" "mfhilo")
4048    (set_attr "mode" "<MODE>")])
4049
4050 ;; Patterns for loading or storing part of a paired floating point
4051 ;; register.  We need them because odd-numbered floating-point registers
4052 ;; are not fully independent: see mips_split_64bit_move.
4053
4054 ;; Load the low word of operand 0 with operand 1.
4055 (define_insn "load_df_low"
4056   [(set (match_operand:DF 0 "register_operand" "=f,f")
4057         (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")]
4058                    UNSPEC_LOAD_DF_LOW))]
4059   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4060 {
4061   operands[0] = mips_subword (operands[0], 0);
4062   return mips_output_move (operands[0], operands[1]);
4063 }
4064   [(set_attr "type"     "mtc,fpload")
4065    (set_attr "mode"     "SF")])
4066
4067 ;; Load the high word of operand 0 from operand 1, preserving the value
4068 ;; in the low word.
4069 (define_insn "load_df_high"
4070   [(set (match_operand:DF 0 "register_operand" "=f,f")
4071         (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")
4072                     (match_operand:DF 2 "register_operand" "0,0")]
4073                    UNSPEC_LOAD_DF_HIGH))]
4074   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4075 {
4076   operands[0] = mips_subword (operands[0], 1);
4077   return mips_output_move (operands[0], operands[1]);
4078 }
4079   [(set_attr "type"     "mtc,fpload")
4080    (set_attr "mode"     "SF")])
4081
4082 ;; Store the high word of operand 1 in operand 0.  The corresponding
4083 ;; low-word move is done in the normal way.
4084 (define_insn "store_df_high"
4085   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
4086         (unspec:SI [(match_operand:DF 1 "register_operand" "f,f")]
4087                    UNSPEC_STORE_DF_HIGH))]
4088   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4089 {
4090   operands[1] = mips_subword (operands[1], 1);
4091   return mips_output_move (operands[0], operands[1]);
4092 }
4093   [(set_attr "type"     "mfc,fpstore")
4094    (set_attr "mode"     "SF")])
4095
4096 ;; Move operand 1 to the high word of operand 0 using mthc1, preserving the
4097 ;; value in the low word.
4098 (define_insn "mthc1"
4099   [(set (match_operand:DF 0 "register_operand" "=f")
4100         (unspec:DF [(match_operand:SI 1 "general_operand" "dJ")
4101                     (match_operand:DF 2 "register_operand" "0")]
4102                     UNSPEC_MTHC1))]
4103   "TARGET_HARD_FLOAT && !TARGET_64BIT && ISA_HAS_MXHC1"
4104   "mthc1\t%z1,%0"
4105   [(set_attr "type"     "mtc")
4106    (set_attr "mode"     "SF")])
4107
4108 ;; Move high word of operand 1 to operand 0 using mfhc1.  The corresponding
4109 ;; low-word move is done in the normal way.
4110 (define_insn "mfhc1"
4111   [(set (match_operand:SI 0 "register_operand" "=d")
4112         (unspec:SI [(match_operand:DF 1 "register_operand" "f")]
4113                     UNSPEC_MFHC1))]
4114   "TARGET_HARD_FLOAT && !TARGET_64BIT && ISA_HAS_MXHC1"
4115   "mfhc1\t%0,%1"
4116   [(set_attr "type"     "mfc")
4117    (set_attr "mode"     "SF")])
4118
4119 ;; Move a constant that satisfies CONST_GP_P into operand 0.
4120 (define_expand "load_const_gp"
4121   [(set (match_operand 0 "register_operand" "=d")
4122         (const (unspec [(const_int 0)] UNSPEC_GP)))])
4123
4124 ;; Insn to initialize $gp for n32/n64 abicalls.  Operand 0 is the offset
4125 ;; of _gp from the start of this function.  Operand 1 is the incoming
4126 ;; function address.
4127 (define_insn_and_split "loadgp_newabi"
4128   [(unspec_volatile [(match_operand 0 "" "")
4129                      (match_operand 1 "register_operand" "")] UNSPEC_LOADGP)]
4130   "mips_current_loadgp_style () == LOADGP_NEWABI"
4131   "#"
4132   ""
4133   [(set (match_dup 2) (match_dup 3))
4134    (set (match_dup 2) (match_dup 4))
4135    (set (match_dup 2) (match_dup 5))]
4136 {
4137   operands[2] = pic_offset_table_rtx;
4138   operands[3] = gen_rtx_HIGH (Pmode, operands[0]);
4139   operands[4] = gen_rtx_PLUS (Pmode, operands[2], operands[1]);
4140   operands[5] = gen_rtx_LO_SUM (Pmode, operands[2], operands[0]);
4141 }
4142   [(set_attr "length" "12")])
4143
4144 ;; Likewise, for -mno-shared code.  Operand 0 is the __gnu_local_gp symbol.
4145 (define_insn_and_split "loadgp_absolute"
4146   [(unspec_volatile [(match_operand 0 "" "")] UNSPEC_LOADGP)]
4147   "mips_current_loadgp_style () == LOADGP_ABSOLUTE"
4148   "#"
4149   ""
4150   [(const_int 0)]
4151 {
4152   emit_move_insn (pic_offset_table_rtx, operands[0]);
4153   DONE;
4154 }
4155   [(set_attr "length" "8")])
4156
4157 ;; The use of gp is hidden when not using explicit relocations.
4158 ;; This blockage instruction prevents the gp load from being
4159 ;; scheduled after an implicit use of gp.  It also prevents
4160 ;; the load from being deleted as dead.
4161 (define_insn "loadgp_blockage"
4162   [(unspec_volatile [(reg:DI 28)] UNSPEC_BLOCKAGE)]
4163   ""
4164   ""
4165   [(set_attr "type"     "unknown")
4166    (set_attr "mode"     "none")
4167    (set_attr "length"   "0")])
4168
4169 ;; Initialize $gp for RTP PIC.  Operand 0 is the __GOTT_BASE__ symbol
4170 ;; and operand 1 is the __GOTT_INDEX__ symbol.
4171 (define_insn "loadgp_rtp"
4172   [(unspec_volatile [(match_operand 0 "symbol_ref_operand")
4173                      (match_operand 1 "symbol_ref_operand")] UNSPEC_LOADGP)]
4174   "mips_current_loadgp_style () == LOADGP_RTP"
4175   "#"
4176   [(set_attr "length" "12")])
4177
4178 (define_split
4179   [(unspec_volatile [(match_operand:P 0 "symbol_ref_operand")
4180                      (match_operand:P 1 "symbol_ref_operand")] UNSPEC_LOADGP)]
4181   "mips_current_loadgp_style () == LOADGP_RTP"
4182   [(set (match_dup 2) (high:P (match_dup 3)))
4183    (set (match_dup 2) (unspec:P [(match_dup 2)
4184                                  (match_dup 3)] UNSPEC_LOAD_GOT))
4185    (set (match_dup 2) (unspec:P [(match_dup 2)
4186                                  (match_dup 4)] UNSPEC_LOAD_GOT))]
4187 {
4188   operands[2] = pic_offset_table_rtx;
4189   operands[3] = mips_unspec_address (operands[0], SYMBOL_GENERAL);
4190   operands[4] = mips_unspec_address (operands[1], SYMBOL_HALF);
4191 })
4192
4193 ;; Emit a .cprestore directive, which normally expands to a single store
4194 ;; instruction.  Note that we continue to use .cprestore for explicit reloc
4195 ;; code so that jals inside inline asms will work correctly.
4196 (define_insn "cprestore"
4197   [(unspec_volatile [(match_operand 0 "const_int_operand" "I,i")
4198                      (use (reg:SI 28))]
4199                     UNSPEC_CPRESTORE)]
4200   ""
4201 {
4202   if (set_nomacro && which_alternative == 1)
4203     return ".set\tmacro\;.cprestore\t%0\;.set\tnomacro";
4204   else
4205     return ".cprestore\t%0";
4206 }
4207   [(set_attr "type" "store")
4208    (set_attr "length" "4,12")])
4209 \f
4210 ;; Block moves, see mips.c for more details.
4211 ;; Argument 0 is the destination
4212 ;; Argument 1 is the source
4213 ;; Argument 2 is the length
4214 ;; Argument 3 is the alignment
4215
4216 (define_expand "movmemsi"
4217   [(parallel [(set (match_operand:BLK 0 "general_operand")
4218                    (match_operand:BLK 1 "general_operand"))
4219               (use (match_operand:SI 2 ""))
4220               (use (match_operand:SI 3 "const_int_operand"))])]
4221   "!TARGET_MIPS16 && !TARGET_MEMCPY"
4222 {
4223   if (mips_expand_block_move (operands[0], operands[1], operands[2]))
4224     DONE;
4225   else
4226     FAIL;
4227 })
4228 \f
4229 ;;
4230 ;;  ....................
4231 ;;
4232 ;;      SHIFTS
4233 ;;
4234 ;;  ....................
4235
4236 (define_expand "<optab><mode>3"
4237   [(set (match_operand:GPR 0 "register_operand")
4238         (any_shift:GPR (match_operand:GPR 1 "register_operand")
4239                        (match_operand:SI 2 "arith_operand")))]
4240   ""
4241 {
4242   /* On the mips16, a shift of more than 8 is a four byte instruction,
4243      so, for a shift between 8 and 16, it is just as fast to do two
4244      shifts of 8 or less.  If there is a lot of shifting going on, we
4245      may win in CSE.  Otherwise combine will put the shifts back
4246      together again.  This can be called by function_arg, so we must
4247      be careful not to allocate a new register if we've reached the
4248      reload pass.  */
4249   if (TARGET_MIPS16
4250       && optimize
4251       && GET_CODE (operands[2]) == CONST_INT
4252       && INTVAL (operands[2]) > 8
4253       && INTVAL (operands[2]) <= 16
4254       && !reload_in_progress
4255       && !reload_completed)
4256     {
4257       rtx temp = gen_reg_rtx (<MODE>mode);
4258
4259       emit_insn (gen_<optab><mode>3 (temp, operands[1], GEN_INT (8)));
4260       emit_insn (gen_<optab><mode>3 (operands[0], temp,
4261                                      GEN_INT (INTVAL (operands[2]) - 8)));
4262       DONE;
4263     }
4264 })
4265
4266 (define_insn "*<optab><mode>3"
4267   [(set (match_operand:GPR 0 "register_operand" "=d")
4268         (any_shift:GPR (match_operand:GPR 1 "register_operand" "d")
4269                        (match_operand:SI 2 "arith_operand" "dI")))]
4270   "!TARGET_MIPS16"
4271 {
4272   if (GET_CODE (operands[2]) == CONST_INT)
4273     operands[2] = GEN_INT (INTVAL (operands[2])
4274                            & (GET_MODE_BITSIZE (<MODE>mode) - 1));
4275
4276   return "<d><insn>\t%0,%1,%2";
4277 }
4278   [(set_attr "type" "shift")
4279    (set_attr "mode" "<MODE>")])
4280
4281 (define_insn "*<optab>si3_extend"
4282   [(set (match_operand:DI 0 "register_operand" "=d")
4283         (sign_extend:DI
4284            (any_shift:SI (match_operand:SI 1 "register_operand" "d")
4285                          (match_operand:SI 2 "arith_operand" "dI"))))]
4286   "TARGET_64BIT && !TARGET_MIPS16"
4287 {
4288   if (GET_CODE (operands[2]) == CONST_INT)
4289     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4290
4291   return "<insn>\t%0,%1,%2";
4292 }
4293   [(set_attr "type" "shift")
4294    (set_attr "mode" "SI")])
4295
4296 (define_insn "*<optab>si3_mips16"
4297   [(set (match_operand:SI 0 "register_operand" "=d,d")
4298         (any_shift:SI (match_operand:SI 1 "register_operand" "0,d")
4299                       (match_operand:SI 2 "arith_operand" "d,I")))]
4300   "TARGET_MIPS16"
4301 {
4302   if (which_alternative == 0)
4303     return "<insn>\t%0,%2";
4304
4305   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4306   return "<insn>\t%0,%1,%2";
4307 }
4308   [(set_attr "type" "shift")
4309    (set_attr "mode" "SI")
4310    (set_attr_alternative "length"
4311                 [(const_int 4)
4312                  (if_then_else (match_operand 2 "m16_uimm3_b")
4313                                (const_int 4)
4314                                (const_int 8))])])
4315
4316 ;; We need separate DImode MIPS16 patterns because of the irregularity
4317 ;; of right shifts.
4318 (define_insn "*ashldi3_mips16"
4319   [(set (match_operand:DI 0 "register_operand" "=d,d")
4320         (ashift:DI (match_operand:DI 1 "register_operand" "0,d")
4321                    (match_operand:SI 2 "arith_operand" "d,I")))]
4322   "TARGET_64BIT && TARGET_MIPS16"
4323 {
4324   if (which_alternative == 0)
4325     return "dsll\t%0,%2";
4326
4327   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4328   return "dsll\t%0,%1,%2";
4329 }
4330   [(set_attr "type" "shift")
4331    (set_attr "mode" "DI")
4332    (set_attr_alternative "length"
4333                 [(const_int 4)
4334                  (if_then_else (match_operand 2 "m16_uimm3_b")
4335                                (const_int 4)
4336                                (const_int 8))])])
4337
4338 (define_insn "*ashrdi3_mips16"
4339   [(set (match_operand:DI 0 "register_operand" "=d,d")
4340         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
4341                      (match_operand:SI 2 "arith_operand" "d,I")))]
4342   "TARGET_64BIT && TARGET_MIPS16"
4343 {
4344   if (GET_CODE (operands[2]) == CONST_INT)
4345     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4346
4347   return "dsra\t%0,%2";
4348 }
4349   [(set_attr "type" "shift")
4350    (set_attr "mode" "DI")
4351    (set_attr_alternative "length"
4352                 [(const_int 4)
4353                  (if_then_else (match_operand 2 "m16_uimm3_b")
4354                                (const_int 4)
4355                                (const_int 8))])])
4356
4357 (define_insn "*lshrdi3_mips16"
4358   [(set (match_operand:DI 0 "register_operand" "=d,d")
4359         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
4360                      (match_operand:SI 2 "arith_operand" "d,I")))]
4361   "TARGET_64BIT && TARGET_MIPS16"
4362 {
4363   if (GET_CODE (operands[2]) == CONST_INT)
4364     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4365
4366   return "dsrl\t%0,%2";
4367 }
4368   [(set_attr "type" "shift")
4369    (set_attr "mode" "DI")
4370    (set_attr_alternative "length"
4371                 [(const_int 4)
4372                  (if_then_else (match_operand 2 "m16_uimm3_b")
4373                                (const_int 4)
4374                                (const_int 8))])])
4375
4376 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4377
4378 (define_split
4379   [(set (match_operand:GPR 0 "register_operand")
4380         (any_shift:GPR (match_operand:GPR 1 "register_operand")
4381                        (match_operand:GPR 2 "const_int_operand")))]
4382   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4383    && GET_CODE (operands[2]) == CONST_INT
4384    && INTVAL (operands[2]) > 8
4385    && INTVAL (operands[2]) <= 16"
4386   [(set (match_dup 0) (any_shift:GPR (match_dup 1) (const_int 8)))
4387    (set (match_dup 0) (any_shift:GPR (match_dup 0) (match_dup 2)))]
4388   { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4389
4390 ;; If we load a byte on the mips16 as a bitfield, the resulting
4391 ;; sequence of instructions is too complicated for combine, because it
4392 ;; involves four instructions: a load, a shift, a constant load into a
4393 ;; register, and an and (the key problem here is that the mips16 does
4394 ;; not have and immediate).  We recognize a shift of a load in order
4395 ;; to make it simple enough for combine to understand.
4396 ;;
4397 ;; The length here is the worst case: the length of the split version
4398 ;; will be more accurate.
4399 (define_insn_and_split ""
4400   [(set (match_operand:SI 0 "register_operand" "=d")
4401         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
4402                      (match_operand:SI 2 "immediate_operand" "I")))]
4403   "TARGET_MIPS16"
4404   "#"
4405   ""
4406   [(set (match_dup 0) (match_dup 1))
4407    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
4408   ""
4409   [(set_attr "type"     "load")
4410    (set_attr "mode"     "SI")
4411    (set_attr "length"   "16")])
4412
4413 (define_insn "rotr<mode>3"
4414   [(set (match_operand:GPR 0 "register_operand" "=d")
4415         (rotatert:GPR (match_operand:GPR 1 "register_operand" "d")
4416                       (match_operand:SI 2 "arith_operand" "dI")))]
4417   "ISA_HAS_ROR"
4418 {
4419   if (GET_CODE (operands[2]) == CONST_INT)
4420     gcc_assert (INTVAL (operands[2]) >= 0
4421                 && INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode));
4422
4423   return "<d>ror\t%0,%1,%2";
4424 }
4425   [(set_attr "type" "shift")
4426    (set_attr "mode" "<MODE>")])
4427 \f
4428 ;;
4429 ;;  ....................
4430 ;;
4431 ;;      COMPARISONS
4432 ;;
4433 ;;  ....................
4434
4435 ;; Flow here is rather complex:
4436 ;;
4437 ;;  1)  The cmp{si,di,sf,df} routine is called.  It deposits the arguments
4438 ;;      into cmp_operands[] but generates no RTL.
4439 ;;
4440 ;;  2)  The appropriate branch define_expand is called, which then
4441 ;;      creates the appropriate RTL for the comparison and branch.
4442 ;;      Different CC modes are used, based on what type of branch is
4443 ;;      done, so that we can constrain things appropriately.  There
4444 ;;      are assumptions in the rest of GCC that break if we fold the
4445 ;;      operands into the branches for integer operations, and use cc0
4446 ;;      for floating point, so we use the fp status register instead.
4447 ;;      If needed, an appropriate temporary is created to hold the
4448 ;;      of the integer compare.
4449
4450 (define_expand "cmp<mode>"
4451   [(set (cc0)
4452         (compare:CC (match_operand:GPR 0 "register_operand")
4453                     (match_operand:GPR 1 "nonmemory_operand")))]
4454   ""
4455 {
4456   cmp_operands[0] = operands[0];
4457   cmp_operands[1] = operands[1];
4458   DONE;
4459 })
4460
4461 (define_expand "cmp<mode>"
4462   [(set (cc0)
4463         (compare:CC (match_operand:SCALARF 0 "register_operand")
4464                     (match_operand:SCALARF 1 "register_operand")))]
4465   ""
4466 {
4467   cmp_operands[0] = operands[0];
4468   cmp_operands[1] = operands[1];
4469   DONE;
4470 })
4471 \f
4472 ;;
4473 ;;  ....................
4474 ;;
4475 ;;      CONDITIONAL BRANCHES
4476 ;;
4477 ;;  ....................
4478
4479 ;; Conditional branches on floating-point equality tests.
4480
4481 (define_insn "*branch_fp"
4482   [(set (pc)
4483         (if_then_else
4484          (match_operator 0 "equality_operator"
4485                          [(match_operand:CC 2 "register_operand" "z")
4486                           (const_int 0)])
4487          (label_ref (match_operand 1 "" ""))
4488          (pc)))]
4489   "TARGET_HARD_FLOAT"
4490 {
4491   return mips_output_conditional_branch (insn, operands,
4492                                          MIPS_BRANCH ("b%F0", "%Z2%1"),
4493                                          MIPS_BRANCH ("b%W0", "%Z2%1"));
4494 }
4495   [(set_attr "type" "branch")
4496    (set_attr "mode" "none")])
4497
4498 (define_insn "*branch_fp_inverted"
4499   [(set (pc)
4500         (if_then_else
4501          (match_operator 0 "equality_operator"
4502                          [(match_operand:CC 2 "register_operand" "z")
4503                           (const_int 0)])
4504          (pc)
4505          (label_ref (match_operand 1 "" ""))))]
4506   "TARGET_HARD_FLOAT"
4507 {
4508   return mips_output_conditional_branch (insn, operands,
4509                                          MIPS_BRANCH ("b%W0", "%Z2%1"),
4510                                          MIPS_BRANCH ("b%F0", "%Z2%1"));
4511 }
4512   [(set_attr "type" "branch")
4513    (set_attr "mode" "none")])
4514
4515 ;; Conditional branches on ordered comparisons with zero.
4516
4517 (define_insn "*branch_order<mode>"
4518   [(set (pc)
4519         (if_then_else
4520          (match_operator 0 "order_operator"
4521                          [(match_operand:GPR 2 "register_operand" "d")
4522                           (const_int 0)])
4523          (label_ref (match_operand 1 "" ""))
4524          (pc)))]
4525   "!TARGET_MIPS16"
4526   { return mips_output_order_conditional_branch (insn, operands, false); }
4527   [(set_attr "type" "branch")
4528    (set_attr "mode" "none")])
4529
4530 (define_insn "*branch_order<mode>_inverted"
4531   [(set (pc)
4532         (if_then_else
4533          (match_operator 0 "order_operator"
4534                          [(match_operand:GPR 2 "register_operand" "d")
4535                           (const_int 0)])
4536          (pc)
4537          (label_ref (match_operand 1 "" ""))))]
4538   "!TARGET_MIPS16"
4539   { return mips_output_order_conditional_branch (insn, operands, true); }
4540   [(set_attr "type" "branch")
4541    (set_attr "mode" "none")])
4542
4543 ;; Conditional branch on equality comparison.
4544
4545 (define_insn "*branch_equality<mode>"
4546   [(set (pc)
4547         (if_then_else
4548          (match_operator 0 "equality_operator"
4549                          [(match_operand:GPR 2 "register_operand" "d")
4550                           (match_operand:GPR 3 "reg_or_0_operand" "dJ")])
4551          (label_ref (match_operand 1 "" ""))
4552          (pc)))]
4553   "!TARGET_MIPS16"
4554 {
4555   return mips_output_conditional_branch (insn, operands,
4556                                          MIPS_BRANCH ("b%C0", "%2,%z3,%1"),
4557                                          MIPS_BRANCH ("b%N0", "%2,%z3,%1"));
4558 }
4559   [(set_attr "type" "branch")
4560    (set_attr "mode" "none")])
4561
4562 (define_insn "*branch_equality<mode>_inverted"
4563   [(set (pc)
4564         (if_then_else
4565          (match_operator 0 "equality_operator"
4566                          [(match_operand:GPR 2 "register_operand" "d")
4567                           (match_operand:GPR 3 "reg_or_0_operand" "dJ")])
4568          (pc)
4569          (label_ref (match_operand 1 "" ""))))]
4570   "!TARGET_MIPS16"
4571 {
4572   return mips_output_conditional_branch (insn, operands,
4573                                          MIPS_BRANCH ("b%N0", "%2,%z3,%1"),
4574                                          MIPS_BRANCH ("b%C0", "%2,%z3,%1"));
4575 }
4576   [(set_attr "type" "branch")
4577    (set_attr "mode" "none")])
4578
4579 ;; MIPS16 branches
4580
4581 (define_insn "*branch_equality<mode>_mips16"
4582   [(set (pc)
4583         (if_then_else
4584          (match_operator 0 "equality_operator"
4585                          [(match_operand:GPR 1 "register_operand" "d,t")
4586                           (const_int 0)])
4587          (match_operand 2 "pc_or_label_operand" "")
4588          (match_operand 3 "pc_or_label_operand" "")))]
4589   "TARGET_MIPS16"
4590 {
4591   if (operands[2] != pc_rtx)
4592     {
4593       if (which_alternative == 0)
4594         return "b%C0z\t%1,%2";
4595       else
4596         return "bt%C0z\t%2";
4597     }
4598   else
4599     {
4600       if (which_alternative == 0)
4601         return "b%N0z\t%1,%3";
4602       else
4603         return "bt%N0z\t%3";
4604     }
4605 }
4606   [(set_attr "type" "branch")
4607    (set_attr "mode" "none")
4608    (set_attr "length" "8")])
4609
4610 (define_expand "b<code>"
4611   [(set (pc)
4612         (if_then_else (any_cond:CC (cc0)
4613                                    (const_int 0))
4614                       (label_ref (match_operand 0 ""))
4615                       (pc)))]
4616   ""
4617 {
4618   gen_conditional_branch (operands, <CODE>);
4619   DONE;
4620 })
4621
4622 ;; Used to implement built-in functions.
4623 (define_expand "condjump"
4624   [(set (pc)
4625         (if_then_else (match_operand 0)
4626                       (label_ref (match_operand 1))
4627                       (pc)))])
4628 \f
4629 ;;
4630 ;;  ....................
4631 ;;
4632 ;;      SETTING A REGISTER FROM A COMPARISON
4633 ;;
4634 ;;  ....................
4635
4636 (define_expand "seq"
4637   [(set (match_operand:SI 0 "register_operand")
4638         (eq:SI (match_dup 1)
4639                (match_dup 2)))]
4640   ""
4641   { if (mips_emit_scc (EQ, operands[0])) DONE; else FAIL; })
4642
4643 (define_insn "*seq_<mode>"
4644   [(set (match_operand:GPR 0 "register_operand" "=d")
4645         (eq:GPR (match_operand:GPR 1 "register_operand" "d")
4646                 (const_int 0)))]
4647   "!TARGET_MIPS16"
4648   "sltu\t%0,%1,1"
4649   [(set_attr "type" "slt")
4650    (set_attr "mode" "<MODE>")])
4651
4652 (define_insn "*seq_<mode>_mips16"
4653   [(set (match_operand:GPR 0 "register_operand" "=t")
4654         (eq:GPR (match_operand:GPR 1 "register_operand" "d")
4655                 (const_int 0)))]
4656   "TARGET_MIPS16"
4657   "sltu\t%1,1"
4658   [(set_attr "type" "slt")
4659    (set_attr "mode" "<MODE>")])
4660
4661 ;; "sne" uses sltu instructions in which the first operand is $0.
4662 ;; This isn't possible in mips16 code.
4663
4664 (define_expand "sne"
4665   [(set (match_operand:SI 0 "register_operand")
4666         (ne:SI (match_dup 1)
4667                (match_dup 2)))]
4668   "!TARGET_MIPS16"
4669   { if (mips_emit_scc (NE, operands[0])) DONE; else FAIL; })
4670
4671 (define_insn "*sne_<mode>"
4672   [(set (match_operand:GPR 0 "register_operand" "=d")
4673         (ne:GPR (match_operand:GPR 1 "register_operand" "d")
4674                 (const_int 0)))]
4675   "!TARGET_MIPS16"
4676   "sltu\t%0,%.,%1"
4677   [(set_attr "type" "slt")
4678    (set_attr "mode" "<MODE>")])
4679
4680 (define_expand "sgt"
4681   [(set (match_operand:SI 0 "register_operand")
4682         (gt:SI (match_dup 1)
4683                (match_dup 2)))]
4684   ""
4685   { if (mips_emit_scc (GT, operands[0])) DONE; else FAIL; })
4686
4687 (define_insn "*sgt_<mode>"
4688   [(set (match_operand:GPR 0 "register_operand" "=d")
4689         (gt:GPR (match_operand:GPR 1 "register_operand" "d")
4690                 (match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
4691   "!TARGET_MIPS16"
4692   "slt\t%0,%z2,%1"
4693   [(set_attr "type" "slt")
4694    (set_attr "mode" "<MODE>")])
4695
4696 (define_insn "*sgt_<mode>_mips16"
4697   [(set (match_operand:GPR 0 "register_operand" "=t")
4698         (gt:GPR (match_operand:GPR 1 "register_operand" "d")
4699                 (match_operand:GPR 2 "register_operand" "d")))]
4700   "TARGET_MIPS16"
4701   "slt\t%2,%1"
4702   [(set_attr "type" "slt")
4703    (set_attr "mode" "<MODE>")])
4704
4705 (define_expand "sge"
4706   [(set (match_operand:SI 0 "register_operand")
4707         (ge:SI (match_dup 1)
4708                (match_dup 2)))]
4709   ""
4710   { if (mips_emit_scc (GE, operands[0])) DONE; else FAIL; })
4711
4712 (define_insn "*sge_<mode>"
4713   [(set (match_operand:GPR 0 "register_operand" "=d")
4714         (ge:GPR (match_operand:GPR 1 "register_operand" "d")
4715                 (const_int 1)))]
4716   "!TARGET_MIPS16"
4717   "slt\t%0,%.,%1"
4718   [(set_attr "type" "slt")
4719    (set_attr "mode" "<MODE>")])
4720
4721 (define_expand "slt"
4722   [(set (match_operand:SI 0 "register_operand")
4723         (lt:SI (match_dup 1)
4724                (match_dup 2)))]
4725   ""
4726   { if (mips_emit_scc (LT, operands[0])) DONE; else FAIL; })
4727
4728 (define_insn "*slt_<mode>"
4729   [(set (match_operand:GPR 0 "register_operand" "=d")
4730         (lt:GPR (match_operand:GPR 1 "register_operand" "d")
4731                 (match_operand:GPR 2 "arith_operand" "dI")))]
4732   "!TARGET_MIPS16"
4733   "slt\t%0,%1,%2"
4734   [(set_attr "type" "slt")
4735    (set_attr "mode" "<MODE>")])
4736
4737 (define_insn "*slt_<mode>_mips16"
4738   [(set (match_operand:GPR 0 "register_operand" "=t,t")
4739         (lt:GPR (match_operand:GPR 1 "register_operand" "d,d")
4740                 (match_operand:GPR 2 "arith_operand" "d,I")))]
4741   "TARGET_MIPS16"
4742   "slt\t%1,%2"
4743   [(set_attr "type" "slt")
4744    (set_attr "mode" "<MODE>")
4745    (set_attr_alternative "length"
4746                 [(const_int 4)
4747                  (if_then_else (match_operand 2 "m16_uimm8_1")
4748                                (const_int 4)
4749                                (const_int 8))])])
4750
4751 (define_expand "sle"
4752   [(set (match_operand:SI 0 "register_operand")
4753         (le:SI (match_dup 1)
4754                (match_dup 2)))]
4755   ""
4756   { if (mips_emit_scc (LE, operands[0])) DONE; else FAIL; })
4757
4758 (define_insn "*sle_<mode>"
4759   [(set (match_operand:GPR 0 "register_operand" "=d")
4760         (le:GPR (match_operand:GPR 1 "register_operand" "d")
4761                 (match_operand:GPR 2 "sle_operand" "")))]
4762   "!TARGET_MIPS16"
4763 {
4764   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
4765   return "slt\t%0,%1,%2";
4766 }
4767   [(set_attr "type" "slt")
4768    (set_attr "mode" "<MODE>")])
4769
4770 (define_insn "*sle_<mode>_mips16"
4771   [(set (match_operand:GPR 0 "register_operand" "=t")
4772         (le:GPR (match_operand:GPR 1 "register_operand" "d")
4773                 (match_operand:GPR 2 "sle_operand" "")))]
4774   "TARGET_MIPS16"
4775 {
4776   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
4777   return "slt\t%1,%2";
4778 }
4779   [(set_attr "type" "slt")
4780    (set_attr "mode" "<MODE>")
4781    (set (attr "length") (if_then_else (match_operand 2 "m16_uimm8_m1_1")
4782                                       (const_int 4)
4783                                       (const_int 8)))])
4784
4785 (define_expand "sgtu"
4786   [(set (match_operand:SI 0 "register_operand")
4787         (gtu:SI (match_dup 1)
4788                 (match_dup 2)))]
4789   ""
4790   { if (mips_emit_scc (GTU, operands[0])) DONE; else FAIL; })
4791
4792 (define_insn "*sgtu_<mode>"
4793   [(set (match_operand:GPR 0 "register_operand" "=d")
4794         (gtu:GPR (match_operand:GPR 1 "register_operand" "d")
4795                  (match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
4796   "!TARGET_MIPS16"
4797   "sltu\t%0,%z2,%1"
4798   [(set_attr "type" "slt")
4799    (set_attr "mode" "<MODE>")])
4800
4801 (define_insn "*sgtu_<mode>_mips16"
4802   [(set (match_operand:GPR 0 "register_operand" "=t")
4803         (gtu:GPR (match_operand:GPR 1 "register_operand" "d")
4804                  (match_operand:GPR 2 "register_operand" "d")))]
4805   "TARGET_MIPS16"
4806   "sltu\t%2,%1"
4807   [(set_attr "type" "slt")
4808    (set_attr "mode" "<MODE>")])
4809
4810 (define_expand "sgeu"
4811   [(set (match_operand:SI 0 "register_operand")
4812         (geu:SI (match_dup 1)
4813                 (match_dup 2)))]
4814   ""
4815   { if (mips_emit_scc (GEU, operands[0])) DONE; else FAIL; })
4816
4817 (define_insn "*sge_<mode>"
4818   [(set (match_operand:GPR 0 "register_operand" "=d")
4819         (geu:GPR (match_operand:GPR 1 "register_operand" "d")
4820                  (const_int 1)))]
4821   "!TARGET_MIPS16"
4822   "sltu\t%0,%.,%1"
4823   [(set_attr "type" "slt")
4824    (set_attr "mode" "<MODE>")])
4825
4826 (define_expand "sltu"
4827   [(set (match_operand:SI 0 "register_operand")
4828         (ltu:SI (match_dup 1)
4829                 (match_dup 2)))]
4830   ""
4831   { if (mips_emit_scc (LTU, operands[0])) DONE; else FAIL; })
4832
4833 (define_insn "*sltu_<mode>"
4834   [(set (match_operand:GPR 0 "register_operand" "=d")
4835         (ltu:GPR (match_operand:GPR 1 "register_operand" "d")
4836                  (match_operand:GPR 2 "arith_operand" "dI")))]
4837   "!TARGET_MIPS16"
4838   "sltu\t%0,%1,%2"
4839   [(set_attr "type" "slt")
4840    (set_attr "mode" "<MODE>")])
4841
4842 (define_insn "*sltu_<mode>_mips16"
4843   [(set (match_operand:GPR 0 "register_operand" "=t,t")
4844         (ltu:GPR (match_operand:GPR 1 "register_operand" "d,d")
4845                  (match_operand:GPR 2 "arith_operand" "d,I")))]
4846   "TARGET_MIPS16"
4847   "sltu\t%1,%2"
4848   [(set_attr "type" "slt")
4849    (set_attr "mode" "<MODE>")
4850    (set_attr_alternative "length"
4851                 [(const_int 4)
4852                  (if_then_else (match_operand 2 "m16_uimm8_1")
4853                                (const_int 4)
4854                                (const_int 8))])])
4855
4856 (define_expand "sleu"
4857   [(set (match_operand:SI 0 "register_operand")
4858         (leu:SI (match_dup 1)
4859                 (match_dup 2)))]
4860   ""
4861   { if (mips_emit_scc (LEU, operands[0])) DONE; else FAIL; })
4862
4863 (define_insn "*sleu_<mode>"
4864   [(set (match_operand:GPR 0 "register_operand" "=d")
4865         (leu:GPR (match_operand:GPR 1 "register_operand" "d")
4866                  (match_operand:GPR 2 "sleu_operand" "")))]
4867   "!TARGET_MIPS16"
4868 {
4869   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
4870   return "sltu\t%0,%1,%2";
4871 }
4872   [(set_attr "type" "slt")
4873    (set_attr "mode" "<MODE>")])
4874
4875 (define_insn "*sleu_<mode>_mips16"
4876   [(set (match_operand:GPR 0 "register_operand" "=t")
4877         (leu:GPR (match_operand:GPR 1 "register_operand" "d")
4878                  (match_operand:GPR 2 "sleu_operand" "")))]
4879   "TARGET_MIPS16"
4880 {
4881   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
4882   return "sltu\t%1,%2";
4883 }
4884   [(set_attr "type" "slt")
4885    (set_attr "mode" "<MODE>")
4886    (set (attr "length") (if_then_else (match_operand 2 "m16_uimm8_m1_1")
4887                                       (const_int 4)
4888                                       (const_int 8)))])
4889 \f
4890 ;;
4891 ;;  ....................
4892 ;;
4893 ;;      FLOATING POINT COMPARISONS
4894 ;;
4895 ;;  ....................
4896
4897 (define_insn "s<code>_<mode>"
4898   [(set (match_operand:CC 0 "register_operand" "=z")
4899         (fcond:CC (match_operand:SCALARF 1 "register_operand" "f")
4900                   (match_operand:SCALARF 2 "register_operand" "f")))]
4901   ""
4902   "c.<fcond>.<fmt>\t%Z0%1,%2"
4903   [(set_attr "type" "fcmp")
4904    (set_attr "mode" "FPSW")])
4905
4906 (define_insn "s<code>_<mode>"
4907   [(set (match_operand:CC 0 "register_operand" "=z")
4908         (swapped_fcond:CC (match_operand:SCALARF 1 "register_operand" "f")
4909                           (match_operand:SCALARF 2 "register_operand" "f")))]
4910   ""
4911   "c.<swapped_fcond>.<fmt>\t%Z0%2,%1"
4912   [(set_attr "type" "fcmp")
4913    (set_attr "mode" "FPSW")])
4914 \f
4915 ;;
4916 ;;  ....................
4917 ;;
4918 ;;      UNCONDITIONAL BRANCHES
4919 ;;
4920 ;;  ....................
4921
4922 ;; Unconditional branches.
4923
4924 (define_insn "jump"
4925   [(set (pc)
4926         (label_ref (match_operand 0 "" "")))]
4927   "!TARGET_MIPS16"
4928 {
4929   if (flag_pic)
4930     {
4931       if (get_attr_length (insn) <= 8)
4932         return "%*b\t%l0%/";
4933       else
4934         {
4935           output_asm_insn (mips_output_load_label (), operands);
4936           return "%*jr\t%@%/%]";
4937         }
4938     }
4939   else
4940     return "%*j\t%l0%/";
4941 }
4942   [(set_attr "type"     "jump")
4943    (set_attr "mode"     "none")
4944    (set (attr "length")
4945         ;; We can't use `j' when emitting PIC.  Emit a branch if it's
4946         ;; in range, otherwise load the address of the branch target into
4947         ;; $at and then jump to it.
4948         (if_then_else
4949          (ior (eq (symbol_ref "flag_pic") (const_int 0))
4950               (lt (abs (minus (match_dup 0)
4951                               (plus (pc) (const_int 4))))
4952                   (const_int 131072)))
4953          (const_int 4) (const_int 16)))])
4954
4955 ;; We need a different insn for the mips16, because a mips16 branch
4956 ;; does not have a delay slot.
4957
4958 (define_insn ""
4959   [(set (pc)
4960         (label_ref (match_operand 0 "" "")))]
4961   "TARGET_MIPS16"
4962   "b\t%l0"
4963   [(set_attr "type"     "branch")
4964    (set_attr "mode"     "none")
4965    (set_attr "length"   "8")])
4966
4967 (define_expand "indirect_jump"
4968   [(set (pc) (match_operand 0 "register_operand"))]
4969   ""
4970 {
4971   operands[0] = force_reg (Pmode, operands[0]);
4972   if (Pmode == SImode)
4973     emit_jump_insn (gen_indirect_jumpsi (operands[0]));
4974   else
4975     emit_jump_insn (gen_indirect_jumpdi (operands[0]));
4976   DONE;
4977 })
4978
4979 (define_insn "indirect_jump<mode>"
4980   [(set (pc) (match_operand:P 0 "register_operand" "d"))]
4981   ""
4982   "%*j\t%0%/"
4983   [(set_attr "type" "jump")
4984    (set_attr "mode" "none")])
4985
4986 (define_expand "tablejump"
4987   [(set (pc)
4988         (match_operand 0 "register_operand"))
4989    (use (label_ref (match_operand 1 "")))]
4990   ""
4991 {
4992   if (TARGET_MIPS16)
4993     operands[0] = expand_binop (Pmode, add_optab,
4994                                 convert_to_mode (Pmode, operands[0], false),
4995                                 gen_rtx_LABEL_REF (Pmode, operands[1]),
4996                                 0, 0, OPTAB_WIDEN);
4997   else if (TARGET_GPWORD)
4998     operands[0] = expand_binop (Pmode, add_optab, operands[0],
4999                                 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
5000   else if (TARGET_RTP_PIC)
5001     {
5002       /* When generating RTP PIC, we use case table entries that are relative
5003          to the start of the function.  Add the function's address to the
5004          value we loaded.  */
5005       rtx start = get_hard_reg_initial_val (Pmode, PIC_FUNCTION_ADDR_REGNUM);
5006       operands[0] = expand_binop (ptr_mode, add_optab, operands[0],
5007                                   start, 0, 0, OPTAB_WIDEN);
5008     }
5009
5010   if (Pmode == SImode)
5011     emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
5012   else
5013     emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
5014   DONE;
5015 })
5016
5017 (define_insn "tablejump<mode>"
5018   [(set (pc)
5019         (match_operand:P 0 "register_operand" "d"))
5020    (use (label_ref (match_operand 1 "" "")))]
5021   ""
5022   "%*j\t%0%/"
5023   [(set_attr "type" "jump")
5024    (set_attr "mode" "none")])
5025
5026 ;; For TARGET_USE_GOT, we save the gp in the jmp_buf as well.
5027 ;; While it is possible to either pull it off the stack (in the
5028 ;; o32 case) or recalculate it given t9 and our target label,
5029 ;; it takes 3 or 4 insns to do so.
5030
5031 (define_expand "builtin_setjmp_setup"
5032   [(use (match_operand 0 "register_operand"))]
5033   "TARGET_USE_GOT"
5034 {
5035   rtx addr;
5036
5037   addr = plus_constant (operands[0], GET_MODE_SIZE (Pmode) * 3);
5038   emit_move_insn (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
5039   DONE;
5040 })
5041
5042 ;; Restore the gp that we saved above.  Despite the earlier comment, it seems
5043 ;; that older code did recalculate the gp from $25.  Continue to jump through
5044 ;; $25 for compatibility (we lose nothing by doing so).
5045
5046 (define_expand "builtin_longjmp"
5047   [(use (match_operand 0 "register_operand"))]
5048   "TARGET_USE_GOT"
5049 {
5050   /* The elements of the buffer are, in order:  */
5051   int W = GET_MODE_SIZE (Pmode);
5052   rtx fp = gen_rtx_MEM (Pmode, operands[0]);
5053   rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
5054   rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
5055   rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
5056   rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
5057   /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
5058      The target is bound to be using $28 as the global pointer
5059      but the current function might not be.  */
5060   rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
5061
5062   /* This bit is similar to expand_builtin_longjmp except that it
5063      restores $gp as well.  */
5064   emit_move_insn (hard_frame_pointer_rtx, fp);
5065   emit_move_insn (pv, lab);
5066   emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
5067   emit_move_insn (gp, gpv);
5068   emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
5069   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
5070   emit_insn (gen_rtx_USE (VOIDmode, gp));
5071   emit_indirect_jump (pv);
5072   DONE;
5073 })
5074 \f
5075 ;;
5076 ;;  ....................
5077 ;;
5078 ;;      Function prologue/epilogue
5079 ;;
5080 ;;  ....................
5081 ;;
5082
5083 (define_expand "prologue"
5084   [(const_int 1)]
5085   ""
5086 {
5087   mips_expand_prologue ();
5088   DONE;
5089 })
5090
5091 ;; Block any insns from being moved before this point, since the
5092 ;; profiling call to mcount can use various registers that aren't
5093 ;; saved or used to pass arguments.
5094
5095 (define_insn "blockage"
5096   [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
5097   ""
5098   ""
5099   [(set_attr "type"     "unknown")
5100    (set_attr "mode"     "none")
5101    (set_attr "length"   "0")])
5102
5103 (define_expand "epilogue"
5104   [(const_int 2)]
5105   ""
5106 {
5107   mips_expand_epilogue (false);
5108   DONE;
5109 })
5110
5111 (define_expand "sibcall_epilogue"
5112   [(const_int 2)]
5113   ""
5114 {
5115   mips_expand_epilogue (true);
5116   DONE;
5117 })
5118
5119 ;; Trivial return.  Make it look like a normal return insn as that
5120 ;; allows jump optimizations to work better.
5121
5122 (define_insn "return"
5123   [(return)]
5124   "mips_can_use_return_insn ()"
5125   "%*j\t$31%/"
5126   [(set_attr "type"     "jump")
5127    (set_attr "mode"     "none")])
5128
5129 ;; Normal return.
5130
5131 (define_insn "return_internal"
5132   [(return)
5133    (use (match_operand 0 "pmode_register_operand" ""))]
5134   ""
5135   "%*j\t%0%/"
5136   [(set_attr "type"     "jump")
5137    (set_attr "mode"     "none")])
5138
5139 ;; This is used in compiling the unwind routines.
5140 (define_expand "eh_return"
5141   [(use (match_operand 0 "general_operand"))]
5142   ""
5143 {
5144   enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
5145
5146   if (GET_MODE (operands[0]) != gpr_mode)
5147     operands[0] = convert_to_mode (gpr_mode, operands[0], 0);
5148   if (TARGET_64BIT)
5149     emit_insn (gen_eh_set_lr_di (operands[0]));
5150   else
5151     emit_insn (gen_eh_set_lr_si (operands[0]));
5152
5153   DONE;
5154 })
5155
5156 ;; Clobber the return address on the stack.  We can't expand this
5157 ;; until we know where it will be put in the stack frame.
5158
5159 (define_insn "eh_set_lr_si"
5160   [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
5161    (clobber (match_scratch:SI 1 "=&d"))]
5162   "! TARGET_64BIT"
5163   "#")
5164
5165 (define_insn "eh_set_lr_di"
5166   [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
5167    (clobber (match_scratch:DI 1 "=&d"))]
5168   "TARGET_64BIT"
5169   "#")
5170
5171 (define_split
5172   [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
5173    (clobber (match_scratch 1))]
5174   "reload_completed && !TARGET_DEBUG_D_MODE"
5175   [(const_int 0)]
5176 {
5177   mips_set_return_address (operands[0], operands[1]);
5178   DONE;
5179 })
5180
5181 (define_insn_and_split "nonlocal_goto_receiver"
5182   [(set (reg:SI 28)
5183         (unspec_volatile:SI [(const_int 0)] UNSPEC_NONLOCAL_GOTO_RECEIVER))]
5184   "TARGET_CALL_CLOBBERED_GP"
5185   "#"
5186   "&& reload_completed"
5187   [(const_int 0)]
5188 {
5189   mips_restore_gp ();
5190   DONE;
5191 }
5192   [(set_attr "type"   "load")
5193    (set_attr "length" "12")])
5194 \f
5195 ;;
5196 ;;  ....................
5197 ;;
5198 ;;      FUNCTION CALLS
5199 ;;
5200 ;;  ....................
5201
5202 ;; Instructions to load a call address from the GOT.  The address might
5203 ;; point to a function or to a lazy binding stub.  In the latter case,
5204 ;; the stub will use the dynamic linker to resolve the function, which
5205 ;; in turn will change the GOT entry to point to the function's real
5206 ;; address.
5207 ;;
5208 ;; This means that every call, even pure and constant ones, can
5209 ;; potentially modify the GOT entry.  And once a stub has been called,
5210 ;; we must not call it again.
5211 ;;
5212 ;; We represent this restriction using an imaginary fixed register that
5213 ;; acts like a GOT version number.  By making the register call-clobbered,
5214 ;; we tell the target-independent code that the address could be changed
5215 ;; by any call insn.
5216 (define_insn "load_call<mode>"
5217   [(set (match_operand:P 0 "register_operand" "=d")
5218         (unspec:P [(match_operand:P 1 "register_operand" "r")
5219                    (match_operand:P 2 "immediate_operand" "")
5220                    (reg:P FAKE_CALL_REGNO)]
5221                   UNSPEC_LOAD_CALL))]
5222   "TARGET_USE_GOT"
5223   "<load>\t%0,%R2(%1)"
5224   [(set_attr "type" "load")
5225    (set_attr "mode" "<MODE>")
5226    (set_attr "length" "4")])
5227
5228 ;; Sibling calls.  All these patterns use jump instructions.
5229
5230 ;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
5231 ;; addresses if a direct jump is acceptable.  Since the 'S' constraint
5232 ;; is defined in terms of call_insn_operand, the same is true of the
5233 ;; constraints.
5234
5235 ;; When we use an indirect jump, we need a register that will be
5236 ;; preserved by the epilogue.  Since TARGET_USE_PIC_FN_ADDR_REG forces
5237 ;; us to use $25 for this purpose -- and $25 is never clobbered by the
5238 ;; epilogue -- we might as well use it for !TARGET_USE_PIC_FN_ADDR_REG
5239 ;; as well.
5240
5241 (define_expand "sibcall"
5242   [(parallel [(call (match_operand 0 "")
5243                     (match_operand 1 ""))
5244               (use (match_operand 2 ""))        ;; next_arg_reg
5245               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
5246   "TARGET_SIBCALLS"
5247 {
5248   mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true);
5249   DONE;
5250 })
5251
5252 (define_insn "sibcall_internal"
5253   [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
5254          (match_operand 1 "" ""))]
5255   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5256   { return MIPS_CALL ("j", operands, 0); }
5257   [(set_attr "type" "call")])
5258
5259 (define_expand "sibcall_value"
5260   [(parallel [(set (match_operand 0 "")
5261                    (call (match_operand 1 "")
5262                          (match_operand 2 "")))
5263               (use (match_operand 3 ""))])]             ;; next_arg_reg
5264   "TARGET_SIBCALLS"
5265 {
5266   mips_expand_call (operands[0], XEXP (operands[1], 0),
5267                     operands[2], operands[3], true);
5268   DONE;
5269 })
5270
5271 (define_insn "sibcall_value_internal"
5272   [(set (match_operand 0 "register_operand" "")
5273         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
5274               (match_operand 2 "" "")))]
5275   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5276   { return MIPS_CALL ("j", operands, 1); }
5277   [(set_attr "type" "call")])
5278
5279 (define_insn "sibcall_value_multiple_internal"
5280   [(set (match_operand 0 "register_operand" "")
5281         (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
5282               (match_operand 2 "" "")))
5283    (set (match_operand 3 "register_operand" "")
5284         (call (mem:SI (match_dup 1))
5285               (match_dup 2)))]
5286   "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5287   { return MIPS_CALL ("j", operands, 1); }
5288   [(set_attr "type" "call")])
5289
5290 (define_expand "call"
5291   [(parallel [(call (match_operand 0 "")
5292                     (match_operand 1 ""))
5293               (use (match_operand 2 ""))        ;; next_arg_reg
5294               (use (match_operand 3 ""))])]     ;; struct_value_size_rtx
5295   ""
5296 {
5297   mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false);
5298   DONE;
5299 })
5300
5301 ;; This instruction directly corresponds to an assembly-language "jal".
5302 ;; There are four cases:
5303 ;;
5304 ;;    - -mno-abicalls:
5305 ;;        Both symbolic and register destinations are OK.  The pattern
5306 ;;        always expands to a single mips instruction.
5307 ;;
5308 ;;    - -mabicalls/-mno-explicit-relocs:
5309 ;;        Again, both symbolic and register destinations are OK.
5310 ;;        The call is treated as a multi-instruction black box.
5311 ;;
5312 ;;    - -mabicalls/-mexplicit-relocs with n32 or n64:
5313 ;;        Only "jal $25" is allowed.  This expands to a single "jalr $25"
5314 ;;        instruction.
5315 ;;
5316 ;;    - -mabicalls/-mexplicit-relocs with o32 or o64:
5317 ;;        Only "jal $25" is allowed.  The call is actually two instructions:
5318 ;;        "jalr $25" followed by an insn to reload $gp.
5319 ;;
5320 ;; In the last case, we can generate the individual instructions with
5321 ;; a define_split.  There are several things to be wary of:
5322 ;;
5323 ;;   - We can't expose the load of $gp before reload.  If we did,
5324 ;;     it might get removed as dead, but reload can introduce new
5325 ;;     uses of $gp by rematerializing constants.
5326 ;;
5327 ;;   - We shouldn't restore $gp after calls that never return.
5328 ;;     It isn't valid to insert instructions between a noreturn
5329 ;;     call and the following barrier.
5330 ;;
5331 ;;   - The splitter deliberately changes the liveness of $gp.  The unsplit
5332 ;;     instruction preserves $gp and so have no effect on its liveness.
5333 ;;     But once we generate the separate insns, it becomes obvious that
5334 ;;     $gp is not live on entry to the call.
5335 ;;
5336 ;; ??? The operands[2] = insn check is a hack to make the original insn
5337 ;; available to the splitter.
5338 (define_insn_and_split "call_internal"
5339   [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
5340          (match_operand 1 "" ""))
5341    (clobber (reg:SI 31))]
5342   ""
5343   { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 0); }
5344   "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)"
5345   [(const_int 0)]
5346 {
5347   emit_call_insn (gen_call_split (operands[0], operands[1]));
5348   if (!find_reg_note (operands[2], REG_NORETURN, 0))
5349     mips_restore_gp ();
5350   DONE;
5351 }
5352   [(set_attr "jal" "indirect,direct")
5353    (set_attr "extended_mips16" "no,yes")])
5354
5355 (define_insn "call_split"
5356   [(call (mem:SI (match_operand 0 "call_insn_operand" "cS"))
5357          (match_operand 1 "" ""))
5358    (clobber (reg:SI 31))
5359    (clobber (reg:SI 28))]
5360   "TARGET_SPLIT_CALLS"
5361   { return MIPS_CALL ("jal", operands, 0); }
5362   [(set_attr "type" "call")])
5363
5364 (define_expand "call_value"
5365   [(parallel [(set (match_operand 0 "")
5366                    (call (match_operand 1 "")
5367                          (match_operand 2 "")))
5368               (use (match_operand 3 ""))])]             ;; next_arg_reg
5369   ""
5370 {
5371   mips_expand_call (operands[0], XEXP (operands[1], 0),
5372                     operands[2], operands[3], false);
5373   DONE;
5374 })
5375
5376 ;; See comment for call_internal.
5377 (define_insn_and_split "call_value_internal"
5378   [(set (match_operand 0 "register_operand" "")
5379         (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
5380               (match_operand 2 "" "")))
5381    (clobber (reg:SI 31))]
5382   ""
5383   { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1); }
5384   "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)"
5385   [(const_int 0)]
5386 {
5387   emit_call_insn (gen_call_value_split (operands[0], operands[1],
5388                                         operands[2]));
5389   if (!find_reg_note (operands[3], REG_NORETURN, 0))
5390     mips_restore_gp ();
5391   DONE;
5392 }
5393   [(set_attr "jal" "indirect,direct")
5394    (set_attr "extended_mips16" "no,yes")])
5395
5396 (define_insn "call_value_split"
5397   [(set (match_operand 0 "register_operand" "")
5398         (call (mem:SI (match_operand 1 "call_insn_operand" "cS"))
5399               (match_operand 2 "" "")))
5400    (clobber (reg:SI 31))
5401    (clobber (reg:SI 28))]
5402   "TARGET_SPLIT_CALLS"
5403   { return MIPS_CALL ("jal", operands, 1); }
5404   [(set_attr "type" "call")])
5405
5406 ;; See comment for call_internal.
5407 (define_insn_and_split "call_value_multiple_internal"
5408   [(set (match_operand 0 "register_operand" "")
5409         (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
5410               (match_operand 2 "" "")))
5411    (set (match_operand 3 "register_operand" "")
5412         (call (mem:SI (match_dup 1))
5413               (match_dup 2)))
5414    (clobber (reg:SI 31))]
5415   ""
5416   { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1); }
5417   "reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)"
5418   [(const_int 0)]
5419 {
5420   emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1],
5421                                                  operands[2], operands[3]));
5422   if (!find_reg_note (operands[4], REG_NORETURN, 0))
5423     mips_restore_gp ();
5424   DONE;
5425 }
5426   [(set_attr "jal" "indirect,direct")
5427    (set_attr "extended_mips16" "no,yes")])
5428
5429 (define_insn "call_value_multiple_split"
5430   [(set (match_operand 0 "register_operand" "")
5431         (call (mem:SI (match_operand 1 "call_insn_operand" "cS"))
5432               (match_operand 2 "" "")))
5433    (set (match_operand 3 "register_operand" "")
5434         (call (mem:SI (match_dup 1))
5435               (match_dup 2)))
5436    (clobber (reg:SI 31))
5437    (clobber (reg:SI 28))]
5438   "TARGET_SPLIT_CALLS"
5439   { return MIPS_CALL ("jal", operands, 1); }
5440   [(set_attr "type" "call")])
5441
5442 ;; Call subroutine returning any type.
5443
5444 (define_expand "untyped_call"
5445   [(parallel [(call (match_operand 0 "")
5446                     (const_int 0))
5447               (match_operand 1 "")
5448               (match_operand 2 "")])]
5449   ""
5450 {
5451   int i;
5452
5453   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
5454
5455   for (i = 0; i < XVECLEN (operands[2], 0); i++)
5456     {
5457       rtx set = XVECEXP (operands[2], 0, i);
5458       emit_move_insn (SET_DEST (set), SET_SRC (set));
5459     }
5460
5461   emit_insn (gen_blockage ());
5462   DONE;
5463 })
5464 \f
5465 ;;
5466 ;;  ....................
5467 ;;
5468 ;;      MISC.
5469 ;;
5470 ;;  ....................
5471 ;;
5472
5473
5474 (define_insn "prefetch"
5475   [(prefetch (match_operand:QI 0 "address_operand" "p")
5476              (match_operand 1 "const_int_operand" "n")
5477              (match_operand 2 "const_int_operand" "n"))]
5478   "ISA_HAS_PREFETCH && TARGET_EXPLICIT_RELOCS"
5479 {
5480   operands[1] = mips_prefetch_cookie (operands[1], operands[2]);
5481   return "pref\t%1,%a0";
5482 }
5483   [(set_attr "type" "prefetch")])
5484
5485 (define_insn "*prefetch_indexed_<mode>"
5486   [(prefetch (plus:P (match_operand:P 0 "register_operand" "d")
5487                      (match_operand:P 1 "register_operand" "d"))
5488              (match_operand 2 "const_int_operand" "n")
5489              (match_operand 3 "const_int_operand" "n"))]
5490   "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5491 {
5492   operands[2] = mips_prefetch_cookie (operands[2], operands[3]);
5493   return "prefx\t%2,%1(%0)";
5494 }
5495   [(set_attr "type" "prefetchx")])
5496
5497 (define_insn "nop"
5498   [(const_int 0)]
5499   ""
5500   "%(nop%)"
5501   [(set_attr "type"     "nop")
5502    (set_attr "mode"     "none")])
5503
5504 ;; Like nop, but commented out when outside a .set noreorder block.
5505 (define_insn "hazard_nop"
5506   [(const_int 1)]
5507   ""
5508   {
5509     if (set_noreorder)
5510       return "nop";
5511     else
5512       return "#nop";
5513   }
5514   [(set_attr "type"     "nop")])
5515 \f
5516 ;; MIPS4 Conditional move instructions.
5517
5518 (define_insn "*mov<GPR:mode>_on_<MOVECC:mode>"
5519   [(set (match_operand:GPR 0 "register_operand" "=d,d")
5520         (if_then_else:GPR
5521          (match_operator:MOVECC 4 "equality_operator"
5522                 [(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>")
5523                  (const_int 0)])
5524          (match_operand:GPR 2 "reg_or_0_operand" "dJ,0")
5525          (match_operand:GPR 3 "reg_or_0_operand" "0,dJ")))]
5526   "ISA_HAS_CONDMOVE"
5527   "@
5528     mov%T4\t%0,%z2,%1
5529     mov%t4\t%0,%z3,%1"
5530   [(set_attr "type" "condmove")
5531    (set_attr "mode" "<GPR:MODE>")])
5532
5533 (define_insn "*mov<SCALARF:mode>_on_<MOVECC:mode>"
5534   [(set (match_operand:SCALARF 0 "register_operand" "=f,f")
5535         (if_then_else:SCALARF
5536          (match_operator:MOVECC 4 "equality_operator"
5537                 [(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>")
5538                  (const_int 0)])
5539          (match_operand:SCALARF 2 "register_operand" "f,0")
5540          (match_operand:SCALARF 3 "register_operand" "0,f")))]
5541   "ISA_HAS_CONDMOVE"
5542   "@
5543     mov%T4.<fmt>\t%0,%2,%1
5544     mov%t4.<fmt>\t%0,%3,%1"
5545   [(set_attr "type" "condmove")
5546    (set_attr "mode" "<SCALARF:MODE>")])
5547
5548 ;; These are the main define_expand's used to make conditional moves.
5549
5550 (define_expand "mov<mode>cc"
5551   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
5552    (set (match_operand:GPR 0 "register_operand")
5553         (if_then_else:GPR (match_dup 5)
5554                           (match_operand:GPR 2 "reg_or_0_operand")
5555                           (match_operand:GPR 3 "reg_or_0_operand")))]
5556   "ISA_HAS_CONDMOVE"
5557 {
5558   gen_conditional_move (operands);
5559   DONE;
5560 })
5561
5562 (define_expand "mov<mode>cc"
5563   [(set (match_dup 4) (match_operand 1 "comparison_operator"))
5564    (set (match_operand:SCALARF 0 "register_operand")
5565         (if_then_else:SCALARF (match_dup 5)
5566                               (match_operand:SCALARF 2 "register_operand")
5567                               (match_operand:SCALARF 3 "register_operand")))]
5568   "ISA_HAS_CONDMOVE"
5569 {
5570   gen_conditional_move (operands);
5571   DONE;
5572 })
5573 \f
5574 ;;
5575 ;;  ....................
5576 ;;
5577 ;;      mips16 inline constant tables
5578 ;;
5579 ;;  ....................
5580 ;;
5581
5582 (define_insn "consttable_int"
5583   [(unspec_volatile [(match_operand 0 "consttable_operand" "")
5584                      (match_operand 1 "const_int_operand" "")]
5585                     UNSPEC_CONSTTABLE_INT)]
5586   "TARGET_MIPS16"
5587 {
5588   assemble_integer (operands[0], INTVAL (operands[1]),
5589                     BITS_PER_UNIT * INTVAL (operands[1]), 1);
5590   return "";
5591 }
5592   [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
5593
5594 (define_insn "consttable_float"
5595   [(unspec_volatile [(match_operand 0 "consttable_operand" "")]
5596                     UNSPEC_CONSTTABLE_FLOAT)]
5597   "TARGET_MIPS16"
5598 {
5599   REAL_VALUE_TYPE d;
5600
5601   gcc_assert (GET_CODE (operands[0]) == CONST_DOUBLE);
5602   REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
5603   assemble_real (d, GET_MODE (operands[0]),
5604                  GET_MODE_BITSIZE (GET_MODE (operands[0])));
5605   return "";
5606 }
5607   [(set (attr "length")
5608         (symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))])
5609
5610 (define_insn "align"
5611   [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)]
5612   ""
5613   ".align\t%0"
5614   [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))])
5615 \f
5616 (define_split
5617   [(match_operand 0 "small_data_pattern")]
5618   "reload_completed"
5619   [(match_dup 0)]
5620   { operands[0] = mips_rewrite_small_data (operands[0]); })
5621
5622 ;;
5623 ;;  ....................
5624 ;;
5625 ;;      MIPS16e Save/Restore
5626 ;;
5627 ;;  ....................
5628 ;;
5629
5630 (define_insn "*mips16e_save_restore"
5631   [(match_parallel 0 ""
5632        [(set (match_operand:SI 1 "register_operand")
5633              (plus:SI (match_dup 1)
5634                       (match_operand:SI 2 "const_int_operand")))])]
5635   "operands[1] == stack_pointer_rtx
5636    && mips16e_save_restore_pattern_p (operands[0], INTVAL (operands[2]), NULL)"
5637   { return mips16e_output_save_restore (operands[0], INTVAL (operands[2])); }
5638   [(set_attr "type" "arith")
5639    (set_attr "extended_mips16" "yes")])
5640
5641 ; Thread-Local Storage
5642
5643 ; The TLS base pointer is accessed via "rdhwr $v1, $29".  No current
5644 ; MIPS architecture defines this register, and no current
5645 ; implementation provides it; instead, any OS which supports TLS is
5646 ; expected to trap and emulate this instruction.  rdhwr is part of the
5647 ; MIPS 32r2 specification, but we use it on any architecture because
5648 ; we expect it to be emulated.  Use .set to force the assembler to
5649 ; accept it.
5650
5651 (define_insn "tls_get_tp_<mode>"
5652   [(set (match_operand:P 0 "register_operand" "=v")
5653         (unspec:P [(const_int 0)]
5654                   UNSPEC_TLS_GET_TP))]
5655   "HAVE_AS_TLS && !TARGET_MIPS16"
5656   ".set\tpush\;.set\tmips32r2\t\;rdhwr\t%0,$29\;.set\tpop"
5657   [(set_attr "type" "unknown")
5658    ; Since rdhwr always generates a trap for now, putting it in a delay
5659    ; slot would make the kernel's emulation of it much slower.
5660    (set_attr "can_delay" "no")
5661    (set_attr "mode" "<MODE>")])
5662 \f
5663 ; The MIPS Paired-Single Floating Point and MIPS-3D Instructions.
5664
5665 (include "mips-ps-3d.md")
5666
5667 ; The MIPS DSP Instructions.
5668
5669 (include "mips-dsp.md")
5670
5671 ; The MIPS DSP REV 2 Instructions.
5672
5673 (include "mips-dspr2.md")