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