mips.md revision 169689
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    return "mul\t%0,%1,%2";
1046  return "mult\t%0,%1,%2";
1047}
1048  [(set_attr "type" "imul3,imul")
1049   (set_attr "mode" "SI")])
1050
1051(define_insn "muldi3_mult3"
1052  [(set (match_operand:DI 0 "register_operand" "=d")
1053	(mult:DI (match_operand:DI 1 "register_operand" "d")
1054		 (match_operand:DI 2 "register_operand" "d")))
1055   (clobber (match_scratch:DI 3 "=h"))
1056   (clobber (match_scratch:DI 4 "=l"))]
1057  "TARGET_64BIT && GENERATE_MULT3_DI"
1058  "dmult\t%0,%1,%2"
1059  [(set_attr "type" "imul3")
1060   (set_attr "mode" "DI")])
1061
1062;; If a register gets allocated to LO, and we spill to memory, the reload
1063;; will include a move from LO to a GPR.  Merge it into the multiplication
1064;; if it can set the GPR directly.
1065;;
1066;; Operand 0: LO
1067;; Operand 1: GPR (1st multiplication operand)
1068;; Operand 2: GPR (2nd multiplication operand)
1069;; Operand 3: HI
1070;; Operand 4: GPR (destination)
1071(define_peephole2
1072  [(parallel
1073       [(set (match_operand:SI 0 "register_operand")
1074	     (mult:SI (match_operand:SI 1 "register_operand")
1075		      (match_operand:SI 2 "register_operand")))
1076        (clobber (match_operand:SI 3 "register_operand"))
1077        (clobber (scratch:SI))])
1078   (set (match_operand:SI 4 "register_operand")
1079	(unspec [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
1080  "GENERATE_MULT3_SI && peep2_reg_dead_p (2, operands[0])"
1081  [(parallel
1082       [(set (match_dup 4)
1083	     (mult:SI (match_dup 1)
1084		      (match_dup 2)))
1085        (clobber (match_dup 3))
1086        (clobber (match_dup 0))])])
1087
1088(define_insn "mul<mode>3_internal"
1089  [(set (match_operand:GPR 0 "register_operand" "=l")
1090	(mult:GPR (match_operand:GPR 1 "register_operand" "d")
1091		  (match_operand:GPR 2 "register_operand" "d")))
1092   (clobber (match_scratch:GPR 3 "=h"))]
1093  "!TARGET_FIX_R4000"
1094  "<d>mult\t%1,%2"
1095  [(set_attr "type" "imul")
1096   (set_attr "mode" "<MODE>")])
1097
1098(define_insn "mul<mode>3_r4000"
1099  [(set (match_operand:GPR 0 "register_operand" "=d")
1100	(mult:GPR (match_operand:GPR 1 "register_operand" "d")
1101		  (match_operand:GPR 2 "register_operand" "d")))
1102   (clobber (match_scratch:GPR 3 "=h"))
1103   (clobber (match_scratch:GPR 4 "=l"))]
1104  "TARGET_FIX_R4000"
1105  "<d>mult\t%1,%2\;mflo\t%0"
1106  [(set_attr "type" "imul")
1107   (set_attr "mode" "<MODE>")
1108   (set_attr "length" "8")])
1109
1110;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
1111;; of "mult; mflo".  They have the same latency, but the first form gives
1112;; us an extra cycle to compute the operands.
1113
1114;; Operand 0: LO
1115;; Operand 1: GPR (1st multiplication operand)
1116;; Operand 2: GPR (2nd multiplication operand)
1117;; Operand 3: HI
1118;; Operand 4: GPR (destination)
1119(define_peephole2
1120  [(parallel
1121       [(set (match_operand:SI 0 "register_operand")
1122	     (mult:SI (match_operand:SI 1 "register_operand")
1123		      (match_operand:SI 2 "register_operand")))
1124        (clobber (match_operand:SI 3 "register_operand"))])
1125   (set (match_operand:SI 4 "register_operand")
1126	(unspec:SI [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
1127  "ISA_HAS_MACC && !GENERATE_MULT3_SI"
1128  [(set (match_dup 0)
1129	(const_int 0))
1130   (parallel
1131       [(set (match_dup 0)
1132	     (plus:SI (mult:SI (match_dup 1)
1133			       (match_dup 2))
1134		      (match_dup 0)))
1135	(set (match_dup 4)
1136	     (plus:SI (mult:SI (match_dup 1)
1137			       (match_dup 2))
1138		      (match_dup 0)))
1139        (clobber (match_dup 3))])])
1140
1141;; Multiply-accumulate patterns
1142
1143;; For processors that can copy the output to a general register:
1144;;
1145;; The all-d alternative is needed because the combiner will find this
1146;; pattern and then register alloc/reload will move registers around to
1147;; make them fit, and we don't want to trigger unnecessary loads to LO.
1148;;
1149;; The last alternative should be made slightly less desirable, but adding
1150;; "?" to the constraint is too strong, and causes values to be loaded into
1151;; LO even when that's more costly.  For now, using "*d" mostly does the
1152;; trick.
1153(define_insn "*mul_acc_si"
1154  [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1155	(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1156			  (match_operand:SI 2 "register_operand" "d,d,d"))
1157		 (match_operand:SI 3 "register_operand" "0,l,*d")))
1158   (clobber (match_scratch:SI 4 "=h,h,h"))
1159   (clobber (match_scratch:SI 5 "=X,3,l"))
1160   (clobber (match_scratch:SI 6 "=X,X,&d"))]
1161  "(TARGET_MIPS3900
1162   || ISA_HAS_MADD_MSUB)
1163   && !TARGET_MIPS16"
1164{
1165  static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" };
1166  if (which_alternative == 2)
1167    return "#";
1168  if (ISA_HAS_MADD_MSUB && which_alternative != 0)
1169    return "#";
1170  return madd[which_alternative];
1171}
1172  [(set_attr "type"	"imadd,imadd,multi")
1173   (set_attr "mode"	"SI")
1174   (set_attr "length"	"4,4,8")])
1175
1176;; Split the above insn if we failed to get LO allocated.
1177(define_split
1178  [(set (match_operand:SI 0 "register_operand")
1179	(plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1180			  (match_operand:SI 2 "register_operand"))
1181		 (match_operand:SI 3 "register_operand")))
1182   (clobber (match_scratch:SI 4))
1183   (clobber (match_scratch:SI 5))
1184   (clobber (match_scratch:SI 6))]
1185  "reload_completed && !TARGET_DEBUG_D_MODE
1186   && GP_REG_P (true_regnum (operands[0]))
1187   && GP_REG_P (true_regnum (operands[3]))"
1188  [(parallel [(set (match_dup 6)
1189		   (mult:SI (match_dup 1) (match_dup 2)))
1190	      (clobber (match_dup 4))
1191	      (clobber (match_dup 5))])
1192   (set (match_dup 0) (plus:SI (match_dup 6) (match_dup 3)))]
1193  "")
1194
1195;; Splitter to copy result of MADD to a general register
1196(define_split
1197  [(set (match_operand:SI                   0 "register_operand")
1198        (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1199                          (match_operand:SI 2 "register_operand"))
1200                 (match_operand:SI          3 "register_operand")))
1201   (clobber (match_scratch:SI               4))
1202   (clobber (match_scratch:SI               5))
1203   (clobber (match_scratch:SI               6))]
1204  "reload_completed && !TARGET_DEBUG_D_MODE
1205   && GP_REG_P (true_regnum (operands[0]))
1206   && true_regnum (operands[3]) == LO_REGNUM"
1207  [(parallel [(set (match_dup 3)
1208                   (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1209                            (match_dup 3)))
1210              (clobber (match_dup 4))
1211              (clobber (match_dup 5))
1212              (clobber (match_dup 6))])
1213   (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1214  "")
1215
1216(define_insn "*macc"
1217  [(set (match_operand:SI 0 "register_operand" "=l,d")
1218	(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1219			  (match_operand:SI 2 "register_operand" "d,d"))
1220		 (match_operand:SI 3 "register_operand" "0,l")))
1221   (clobber (match_scratch:SI 4 "=h,h"))
1222   (clobber (match_scratch:SI 5 "=X,3"))]
1223  "ISA_HAS_MACC"
1224{
1225  if (which_alternative == 1)
1226    return "macc\t%0,%1,%2";
1227  else if (TARGET_MIPS5500)
1228    return "madd\t%1,%2";
1229  else
1230    /* The VR4130 assumes that there is a two-cycle latency between a macc
1231       that "writes" to $0 and an instruction that reads from it.  We avoid
1232       this by assigning to $1 instead.  */
1233    return "%[macc\t%@,%1,%2%]";
1234}
1235  [(set_attr "type" "imadd")
1236   (set_attr "mode" "SI")])
1237
1238(define_insn "*msac"
1239  [(set (match_operand:SI 0 "register_operand" "=l,d")
1240        (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1241                  (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1242                           (match_operand:SI 3 "register_operand" "d,d"))))
1243   (clobber (match_scratch:SI 4 "=h,h"))
1244   (clobber (match_scratch:SI 5 "=X,1"))]
1245  "ISA_HAS_MSAC"
1246{
1247  if (which_alternative == 1)
1248    return "msac\t%0,%2,%3";
1249  else if (TARGET_MIPS5500)
1250    return "msub\t%2,%3";
1251  else
1252    return "msac\t$0,%2,%3";
1253}
1254  [(set_attr "type"     "imadd")
1255   (set_attr "mode"     "SI")])
1256
1257;; An msac-like instruction implemented using negation and a macc.
1258(define_insn_and_split "*msac_using_macc"
1259  [(set (match_operand:SI 0 "register_operand" "=l,d")
1260        (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1261                  (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1262                           (match_operand:SI 3 "register_operand" "d,d"))))
1263   (clobber (match_scratch:SI 4 "=h,h"))
1264   (clobber (match_scratch:SI 5 "=X,1"))
1265   (clobber (match_scratch:SI 6 "=d,d"))]
1266  "ISA_HAS_MACC && !ISA_HAS_MSAC"
1267  "#"
1268  "&& reload_completed"
1269  [(set (match_dup 6)
1270	(neg:SI (match_dup 3)))
1271   (parallel
1272       [(set (match_dup 0)
1273	     (plus:SI (mult:SI (match_dup 2)
1274			       (match_dup 6))
1275		      (match_dup 1)))
1276	(clobber (match_dup 4))
1277	(clobber (match_dup 5))])]
1278  ""
1279  [(set_attr "type"     "imadd")
1280   (set_attr "length"	"8")])
1281
1282;; Patterns generated by the define_peephole2 below.
1283
1284(define_insn "*macc2"
1285  [(set (match_operand:SI 0 "register_operand" "=l")
1286	(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1287			  (match_operand:SI 2 "register_operand" "d"))
1288		 (match_dup 0)))
1289   (set (match_operand:SI 3 "register_operand" "=d")
1290	(plus:SI (mult:SI (match_dup 1)
1291			  (match_dup 2))
1292		 (match_dup 0)))
1293   (clobber (match_scratch:SI 4 "=h"))]
1294  "ISA_HAS_MACC && reload_completed"
1295  "macc\t%3,%1,%2"
1296  [(set_attr "type"	"imadd")
1297   (set_attr "mode"	"SI")])
1298
1299(define_insn "*msac2"
1300  [(set (match_operand:SI 0 "register_operand" "=l")
1301	(minus:SI (match_dup 0)
1302		  (mult:SI (match_operand:SI 1 "register_operand" "d")
1303			   (match_operand:SI 2 "register_operand" "d"))))
1304   (set (match_operand:SI 3 "register_operand" "=d")
1305	(minus:SI (match_dup 0)
1306		  (mult:SI (match_dup 1)
1307			   (match_dup 2))))
1308   (clobber (match_scratch:SI 4 "=h"))]
1309  "ISA_HAS_MSAC && reload_completed"
1310  "msac\t%3,%1,%2"
1311  [(set_attr "type"	"imadd")
1312   (set_attr "mode"	"SI")])
1313
1314;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1315;; Similarly msac.
1316;;
1317;; Operand 0: LO
1318;; Operand 1: macc/msac
1319;; Operand 2: HI
1320;; Operand 3: GPR (destination)
1321(define_peephole2
1322  [(parallel
1323       [(set (match_operand:SI 0 "register_operand")
1324	     (match_operand:SI 1 "macc_msac_operand"))
1325	(clobber (match_operand:SI 2 "register_operand"))
1326	(clobber (scratch:SI))])
1327   (set (match_operand:SI 3 "register_operand")
1328	(unspec:SI [(match_dup 0) (match_dup 2)] UNSPEC_MFHILO))]
1329  ""
1330  [(parallel [(set (match_dup 0)
1331		   (match_dup 1))
1332	      (set (match_dup 3)
1333		   (match_dup 1))
1334	      (clobber (match_dup 2))])]
1335  "")
1336
1337;; When we have a three-address multiplication instruction, it should
1338;; be faster to do a separate multiply and add, rather than moving
1339;; something into LO in order to use a macc instruction.
1340;;
1341;; This peephole needs a scratch register to cater for the case when one
1342;; of the multiplication operands is the same as the destination.
1343;;
1344;; Operand 0: GPR (scratch)
1345;; Operand 1: LO
1346;; Operand 2: GPR (addend)
1347;; Operand 3: GPR (destination)
1348;; Operand 4: macc/msac
1349;; Operand 5: HI
1350;; Operand 6: new multiplication
1351;; Operand 7: new addition/subtraction
1352(define_peephole2
1353  [(match_scratch:SI 0 "d")
1354   (set (match_operand:SI 1 "register_operand")
1355	(match_operand:SI 2 "register_operand"))
1356   (match_dup 0)
1357   (parallel
1358       [(set (match_operand:SI 3 "register_operand")
1359	     (match_operand:SI 4 "macc_msac_operand"))
1360	(clobber (match_operand:SI 5 "register_operand"))
1361	(clobber (match_dup 1))])]
1362  "GENERATE_MULT3_SI
1363   && true_regnum (operands[1]) == LO_REGNUM
1364   && peep2_reg_dead_p (2, operands[1])
1365   && GP_REG_P (true_regnum (operands[3]))"
1366  [(parallel [(set (match_dup 0)
1367		   (match_dup 6))
1368	      (clobber (match_dup 5))
1369	      (clobber (match_dup 1))])
1370   (set (match_dup 3)
1371	(match_dup 7))]
1372{
1373  operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1374  operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1375				operands[2], operands[0]);
1376})
1377
1378;; Same as above, except LO is the initial target of the macc.
1379;;
1380;; Operand 0: GPR (scratch)
1381;; Operand 1: LO
1382;; Operand 2: GPR (addend)
1383;; Operand 3: macc/msac
1384;; Operand 4: HI
1385;; Operand 5: GPR (destination)
1386;; Operand 6: new multiplication
1387;; Operand 7: new addition/subtraction
1388(define_peephole2
1389  [(match_scratch:SI 0 "d")
1390   (set (match_operand:SI 1 "register_operand")
1391	(match_operand:SI 2 "register_operand"))
1392   (match_dup 0)
1393   (parallel
1394       [(set (match_dup 1)
1395	     (match_operand:SI 3 "macc_msac_operand"))
1396	(clobber (match_operand:SI 4 "register_operand"))
1397	(clobber (scratch:SI))])
1398   (match_dup 0)
1399   (set (match_operand:SI 5 "register_operand")
1400	(unspec:SI [(match_dup 1) (match_dup 4)] UNSPEC_MFHILO))]
1401  "GENERATE_MULT3_SI && peep2_reg_dead_p (3, operands[1])"
1402  [(parallel [(set (match_dup 0)
1403		   (match_dup 6))
1404	      (clobber (match_dup 4))
1405	      (clobber (match_dup 1))])
1406   (set (match_dup 5)
1407	(match_dup 7))]
1408{
1409  operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1410  operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1411				operands[2], operands[0]);
1412})
1413
1414(define_insn "*mul_sub_si"
1415  [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1416        (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1417                  (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1418                           (match_operand:SI 3 "register_operand" "d,d,d"))))
1419   (clobber (match_scratch:SI 4 "=h,h,h"))
1420   (clobber (match_scratch:SI 5 "=X,1,l"))
1421   (clobber (match_scratch:SI 6 "=X,X,&d"))]
1422  "ISA_HAS_MADD_MSUB"
1423  "@
1424   msub\t%2,%3
1425   #
1426   #"
1427  [(set_attr "type"     "imadd,multi,multi")
1428   (set_attr "mode"     "SI")
1429   (set_attr "length"   "4,8,8")])
1430
1431;; Split the above insn if we failed to get LO allocated.
1432(define_split
1433  [(set (match_operand:SI 0 "register_operand")
1434        (minus:SI (match_operand:SI 1 "register_operand")
1435                  (mult:SI (match_operand:SI 2 "register_operand")
1436                           (match_operand:SI 3 "register_operand"))))
1437   (clobber (match_scratch:SI 4))
1438   (clobber (match_scratch:SI 5))
1439   (clobber (match_scratch:SI 6))]
1440  "reload_completed && !TARGET_DEBUG_D_MODE
1441   && GP_REG_P (true_regnum (operands[0]))
1442   && GP_REG_P (true_regnum (operands[1]))"
1443  [(parallel [(set (match_dup 6)
1444                   (mult:SI (match_dup 2) (match_dup 3)))
1445              (clobber (match_dup 4))
1446              (clobber (match_dup 5))])
1447   (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 6)))]
1448  "")
1449
1450;; Splitter to copy result of MSUB to a general register
1451(define_split
1452  [(set (match_operand:SI 0 "register_operand")
1453        (minus:SI (match_operand:SI 1 "register_operand")
1454                  (mult:SI (match_operand:SI 2 "register_operand")
1455                           (match_operand:SI 3 "register_operand"))))
1456   (clobber (match_scratch:SI 4))
1457   (clobber (match_scratch:SI 5))
1458   (clobber (match_scratch:SI 6))]
1459  "reload_completed && !TARGET_DEBUG_D_MODE
1460   && GP_REG_P (true_regnum (operands[0]))
1461   && true_regnum (operands[1]) == LO_REGNUM"
1462  [(parallel [(set (match_dup 1)
1463                   (minus:SI (match_dup 1)
1464                             (mult:SI (match_dup 2) (match_dup 3))))
1465              (clobber (match_dup 4))
1466              (clobber (match_dup 5))
1467              (clobber (match_dup 6))])
1468   (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1469  "")
1470
1471(define_insn "*muls"
1472  [(set (match_operand:SI                  0 "register_operand" "=l,d")
1473        (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1474                         (match_operand:SI 2 "register_operand" "d,d"))))
1475   (clobber (match_scratch:SI              3                    "=h,h"))
1476   (clobber (match_scratch:SI              4                    "=X,l"))]
1477  "ISA_HAS_MULS"
1478  "@
1479   muls\t$0,%1,%2
1480   muls\t%0,%1,%2"
1481  [(set_attr "type"     "imul,imul3")
1482   (set_attr "mode"     "SI")])
1483
1484;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1485
1486(define_expand "<u>mulsidi3"
1487  [(parallel
1488      [(set (match_operand:DI 0 "register_operand")
1489	    (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1490		     (any_extend:DI (match_operand:SI 2 "register_operand"))))
1491       (clobber (scratch:DI))
1492       (clobber (scratch:DI))
1493       (clobber (scratch:DI))])]
1494  "!TARGET_64BIT || !TARGET_FIX_R4000"
1495{
1496  if (!TARGET_64BIT)
1497    {
1498      if (!TARGET_FIX_R4000)
1499	emit_insn (gen_<u>mulsidi3_32bit_internal (operands[0], operands[1],
1500						   operands[2]));
1501      else
1502	emit_insn (gen_<u>mulsidi3_32bit_r4000 (operands[0], operands[1],
1503					        operands[2]));
1504      DONE;
1505    }
1506})
1507
1508(define_insn "<u>mulsidi3_32bit_internal"
1509  [(set (match_operand:DI 0 "register_operand" "=x")
1510	(mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1511		 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1512  "!TARGET_64BIT && !TARGET_FIX_R4000"
1513  "mult<u>\t%1,%2"
1514  [(set_attr "type" "imul")
1515   (set_attr "mode" "SI")])
1516
1517(define_insn "<u>mulsidi3_32bit_r4000"
1518  [(set (match_operand:DI 0 "register_operand" "=d")
1519	(mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1520		 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1521   (clobber (match_scratch:DI 3 "=x"))]
1522  "!TARGET_64BIT && TARGET_FIX_R4000"
1523  "mult<u>\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1524  [(set_attr "type" "imul")
1525   (set_attr "mode" "SI")
1526   (set_attr "length" "12")])
1527
1528(define_insn_and_split "*<u>mulsidi3_64bit"
1529  [(set (match_operand:DI 0 "register_operand" "=d")
1530	(mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1531		 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1532   (clobber (match_scratch:DI 3 "=l"))
1533   (clobber (match_scratch:DI 4 "=h"))
1534   (clobber (match_scratch:DI 5 "=d"))]
1535  "TARGET_64BIT && !TARGET_FIX_R4000"
1536  "#"
1537  "&& reload_completed"
1538  [(parallel
1539       [(set (match_dup 3)
1540	     (sign_extend:DI
1541		(mult:SI (match_dup 1)
1542			 (match_dup 2))))
1543	(set (match_dup 4)
1544	     (ashiftrt:DI
1545		(mult:DI (any_extend:DI (match_dup 1))
1546			 (any_extend:DI (match_dup 2)))
1547		(const_int 32)))])
1548
1549   ;; OP5 <- LO, OP0 <- HI
1550   (set (match_dup 5) (unspec:DI [(match_dup 3) (match_dup 4)] UNSPEC_MFHILO))
1551   (set (match_dup 0) (unspec:DI [(match_dup 4) (match_dup 3)] UNSPEC_MFHILO))
1552
1553   ;; Zero-extend OP5.
1554   (set (match_dup 5)
1555	(ashift:DI (match_dup 5)
1556		   (const_int 32)))
1557   (set (match_dup 5)
1558	(lshiftrt:DI (match_dup 5)
1559		     (const_int 32)))
1560
1561   ;; Shift OP0 into place.
1562   (set (match_dup 0)
1563	(ashift:DI (match_dup 0)
1564		   (const_int 32)))
1565
1566   ;; OR the two halves together
1567   (set (match_dup 0)
1568	(ior:DI (match_dup 0)
1569		(match_dup 5)))]
1570  ""
1571  [(set_attr "type" "imul")
1572   (set_attr "mode" "SI")
1573   (set_attr "length" "24")])
1574
1575(define_insn "*<u>mulsidi3_64bit_parts"
1576  [(set (match_operand:DI 0 "register_operand" "=l")
1577	(sign_extend:DI
1578	   (mult:SI (match_operand:SI 2 "register_operand" "d")
1579		    (match_operand:SI 3 "register_operand" "d"))))
1580   (set (match_operand:DI 1 "register_operand" "=h")
1581	(ashiftrt:DI
1582	   (mult:DI (any_extend:DI (match_dup 2))
1583		    (any_extend:DI (match_dup 3)))
1584	   (const_int 32)))]
1585  "TARGET_64BIT && !TARGET_FIX_R4000"
1586  "mult<u>\t%2,%3"
1587  [(set_attr "type" "imul")
1588   (set_attr "mode" "SI")])
1589
1590;; Widening multiply with negation.
1591(define_insn "*muls<u>_di"
1592  [(set (match_operand:DI 0 "register_operand" "=x")
1593        (neg:DI
1594	 (mult:DI
1595	  (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1596	  (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1597  "!TARGET_64BIT && ISA_HAS_MULS"
1598  "muls<u>\t$0,%1,%2"
1599  [(set_attr "type" "imul")
1600   (set_attr "mode" "SI")])
1601
1602(define_insn "*msac<u>_di"
1603  [(set (match_operand:DI 0 "register_operand" "=x")
1604        (minus:DI
1605	   (match_operand:DI 3 "register_operand" "0")
1606	   (mult:DI
1607	      (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1608	      (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1609  "!TARGET_64BIT && ISA_HAS_MSAC"
1610{
1611  if (TARGET_MIPS5500)
1612    return "msub<u>\t%1,%2";
1613  else
1614    return "msac<u>\t$0,%1,%2";
1615}
1616  [(set_attr "type" "imadd")
1617   (set_attr "mode" "SI")])
1618
1619;; _highpart patterns
1620
1621(define_expand "<su>mulsi3_highpart"
1622  [(set (match_operand:SI 0 "register_operand")
1623	(truncate:SI
1624	 (lshiftrt:DI
1625	  (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1626		   (any_extend:DI (match_operand:SI 2 "register_operand")))
1627	  (const_int 32))))]
1628  "ISA_HAS_MULHI || !TARGET_FIX_R4000"
1629{
1630  if (ISA_HAS_MULHI)
1631    emit_insn (gen_<su>mulsi3_highpart_mulhi_internal (operands[0],
1632						       operands[1],
1633						       operands[2]));
1634  else
1635    emit_insn (gen_<su>mulsi3_highpart_internal (operands[0], operands[1],
1636					         operands[2]));
1637  DONE;
1638})
1639
1640(define_insn "<su>mulsi3_highpart_internal"
1641  [(set (match_operand:SI 0 "register_operand" "=h")
1642	(truncate:SI
1643	 (lshiftrt:DI
1644	  (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1645		   (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1646	  (const_int 32))))
1647   (clobber (match_scratch:SI 3 "=l"))]
1648  "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
1649  "mult<u>\t%1,%2"
1650  [(set_attr "type" "imul")
1651   (set_attr "mode" "SI")])
1652
1653(define_insn "<su>mulsi3_highpart_mulhi_internal"
1654  [(set (match_operand:SI 0 "register_operand" "=h,d")
1655        (truncate:SI
1656	 (lshiftrt:DI
1657	  (mult:DI
1658	   (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1659	   (any_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
1660	  (const_int 32))))
1661   (clobber (match_scratch:SI 3 "=l,l"))
1662   (clobber (match_scratch:SI 4 "=X,h"))]
1663  "ISA_HAS_MULHI"
1664  "@
1665   mult<u>\t%1,%2
1666   mulhi<u>\t%0,%1,%2"
1667  [(set_attr "type" "imul,imul3")
1668   (set_attr "mode" "SI")])
1669
1670(define_insn "*<su>mulsi3_highpart_neg_mulhi_internal"
1671  [(set (match_operand:SI 0 "register_operand" "=h,d")
1672        (truncate:SI
1673	 (lshiftrt:DI
1674	  (neg:DI
1675	   (mult:DI
1676	    (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1677	    (any_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
1678	  (const_int 32))))
1679   (clobber (match_scratch:SI 3 "=l,l"))
1680   (clobber (match_scratch:SI 4 "=X,h"))]
1681  "ISA_HAS_MULHI"
1682  "@
1683   mulshi<u>\t%.,%1,%2
1684   mulshi<u>\t%0,%1,%2"
1685  [(set_attr "type" "imul,imul3")
1686   (set_attr "mode" "SI")])
1687
1688;; Disable unsigned multiplication for -mfix-vr4120.  This is for VR4120
1689;; errata MD(0), which says that dmultu does not always produce the
1690;; correct result.
1691(define_insn "<su>muldi3_highpart"
1692  [(set (match_operand:DI 0 "register_operand" "=h")
1693	(truncate:DI
1694	 (lshiftrt:TI
1695	  (mult:TI
1696	   (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
1697	   (any_extend:TI (match_operand:DI 2 "register_operand" "d")))
1698	  (const_int 64))))
1699   (clobber (match_scratch:DI 3 "=l"))]
1700  "TARGET_64BIT && !TARGET_FIX_R4000
1701   && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
1702  "dmult<u>\t%1,%2"
1703  [(set_attr "type" "imul")
1704   (set_attr "mode" "DI")])
1705
1706;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
1707;; instruction.  The HI/LO registers are used as a 64 bit accumulator.
1708
1709(define_insn "madsi"
1710  [(set (match_operand:SI 0 "register_operand" "+l")
1711	(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1712			  (match_operand:SI 2 "register_operand" "d"))
1713		 (match_dup 0)))
1714   (clobber (match_scratch:SI 3 "=h"))]
1715  "TARGET_MAD"
1716  "mad\t%1,%2"
1717  [(set_attr "type"	"imadd")
1718   (set_attr "mode"	"SI")])
1719
1720(define_insn "*<su>mul_acc_di"
1721  [(set (match_operand:DI 0 "register_operand" "=x")
1722	(plus:DI
1723	 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1724		  (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1725	 (match_operand:DI 3 "register_operand" "0")))]
1726  "(TARGET_MAD || ISA_HAS_MACC)
1727   && !TARGET_64BIT"
1728{
1729  if (TARGET_MAD)
1730    return "mad<u>\t%1,%2";
1731  else if (TARGET_MIPS5500)
1732    return "madd<u>\t%1,%2";
1733  else
1734    /* See comment in *macc.  */
1735    return "%[macc<u>\t%@,%1,%2%]";
1736}
1737  [(set_attr "type" "imadd")
1738   (set_attr "mode" "SI")])
1739
1740;; Floating point multiply accumulate instructions.
1741
1742(define_insn "*madd<mode>"
1743  [(set (match_operand:ANYF 0 "register_operand" "=f")
1744	(plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1745			      (match_operand:ANYF 2 "register_operand" "f"))
1746		   (match_operand:ANYF 3 "register_operand" "f")))]
1747  "ISA_HAS_FP4 && TARGET_FUSED_MADD"
1748  "madd.<fmt>\t%0,%3,%1,%2"
1749  [(set_attr "type" "fmadd")
1750   (set_attr "mode" "<UNITMODE>")])
1751
1752(define_insn "*msub<mode>"
1753  [(set (match_operand:ANYF 0 "register_operand" "=f")
1754	(minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1755			       (match_operand:ANYF 2 "register_operand" "f"))
1756		    (match_operand:ANYF 3 "register_operand" "f")))]
1757  "ISA_HAS_FP4 && TARGET_FUSED_MADD"
1758  "msub.<fmt>\t%0,%3,%1,%2"
1759  [(set_attr "type" "fmadd")
1760   (set_attr "mode" "<UNITMODE>")])
1761
1762(define_insn "*nmadd<mode>"
1763  [(set (match_operand:ANYF 0 "register_operand" "=f")
1764	(neg:ANYF (plus:ANYF
1765		   (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1766			      (match_operand:ANYF 2 "register_operand" "f"))
1767		   (match_operand:ANYF 3 "register_operand" "f"))))]
1768  "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1769   && HONOR_SIGNED_ZEROS (<MODE>mode)
1770   && !HONOR_NANS (<MODE>mode)"
1771  "nmadd.<fmt>\t%0,%3,%1,%2"
1772  [(set_attr "type" "fmadd")
1773   (set_attr "mode" "<UNITMODE>")])
1774
1775(define_insn "*nmadd<mode>_fastmath"
1776  [(set (match_operand:ANYF 0 "register_operand" "=f")
1777	(minus:ANYF
1778	 (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
1779		    (match_operand:ANYF 2 "register_operand" "f"))
1780	 (match_operand:ANYF 3 "register_operand" "f")))]
1781  "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1782   && !HONOR_SIGNED_ZEROS (<MODE>mode)
1783   && !HONOR_NANS (<MODE>mode)"
1784  "nmadd.<fmt>\t%0,%3,%1,%2"
1785  [(set_attr "type" "fmadd")
1786   (set_attr "mode" "<UNITMODE>")])
1787
1788(define_insn "*nmsub<mode>"
1789  [(set (match_operand:ANYF 0 "register_operand" "=f")
1790	(neg:ANYF (minus:ANYF
1791		   (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
1792			      (match_operand:ANYF 3 "register_operand" "f"))
1793		   (match_operand:ANYF 1 "register_operand" "f"))))]
1794  "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1795   && HONOR_SIGNED_ZEROS (<MODE>mode)
1796   && !HONOR_NANS (<MODE>mode)"
1797  "nmsub.<fmt>\t%0,%1,%2,%3"
1798  [(set_attr "type" "fmadd")
1799   (set_attr "mode" "<UNITMODE>")])
1800
1801(define_insn "*nmsub<mode>_fastmath"
1802  [(set (match_operand:ANYF 0 "register_operand" "=f")
1803	(minus:ANYF
1804	 (match_operand:ANYF 1 "register_operand" "f")
1805	 (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
1806		    (match_operand:ANYF 3 "register_operand" "f"))))]
1807  "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1808   && !HONOR_SIGNED_ZEROS (<MODE>mode)
1809   && !HONOR_NANS (<MODE>mode)"
1810  "nmsub.<fmt>\t%0,%1,%2,%3"
1811  [(set_attr "type" "fmadd")
1812   (set_attr "mode" "<UNITMODE>")])
1813
1814;;
1815;;  ....................
1816;;
1817;;	DIVISION and REMAINDER
1818;;
1819;;  ....................
1820;;
1821
1822(define_expand "div<mode>3"
1823  [(set (match_operand:ANYF 0 "register_operand")
1824	(div:ANYF (match_operand:ANYF 1 "reg_or_1_operand")
1825		  (match_operand:ANYF 2 "register_operand")))]
1826  "<divide_condition>"
1827{
1828  if (const_1_operand (operands[1], <MODE>mode))
1829    if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
1830      operands[1] = force_reg (<MODE>mode, operands[1]);
1831})
1832
1833;; These patterns work around the early SB-1 rev2 core "F1" erratum:
1834;;
1835;; If an mfc1 or dmfc1 happens to access the floating point register
1836;; file at the same time a long latency operation (div, sqrt, recip,
1837;; sqrt) iterates an intermediate result back through the floating
1838;; point register file bypass, then instead returning the correct
1839;; register value the mfc1 or dmfc1 operation returns the intermediate
1840;; result of the long latency operation.
1841;;
1842;; The workaround is to insert an unconditional 'mov' from/to the
1843;; long latency op destination register.
1844
1845(define_insn "*div<mode>3"
1846  [(set (match_operand:ANYF 0 "register_operand" "=f")
1847	(div:ANYF (match_operand:ANYF 1 "register_operand" "f")
1848		  (match_operand:ANYF 2 "register_operand" "f")))]
1849  "<divide_condition>"
1850{
1851  if (TARGET_FIX_SB1)
1852    return "div.<fmt>\t%0,%1,%2\;mov.<fmt>\t%0,%0";
1853  else
1854    return "div.<fmt>\t%0,%1,%2";
1855}
1856  [(set_attr "type" "fdiv")
1857   (set_attr "mode" "<UNITMODE>")
1858   (set (attr "length")
1859        (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1860                      (const_int 8)
1861                      (const_int 4)))])
1862
1863(define_insn "*recip<mode>3"
1864  [(set (match_operand:ANYF 0 "register_operand" "=f")
1865	(div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
1866		  (match_operand:ANYF 2 "register_operand" "f")))]
1867  "<recip_condition> && flag_unsafe_math_optimizations"
1868{
1869  if (TARGET_FIX_SB1)
1870    return "recip.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
1871  else
1872    return "recip.<fmt>\t%0,%2";
1873}
1874  [(set_attr "type" "frdiv")
1875   (set_attr "mode" "<UNITMODE>")
1876   (set (attr "length")
1877        (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1878                      (const_int 8)
1879                      (const_int 4)))])
1880
1881;; VR4120 errata MD(A1): signed division instructions do not work correctly
1882;; with negative operands.  We use special libgcc functions instead.
1883(define_insn "divmod<mode>4"
1884  [(set (match_operand:GPR 0 "register_operand" "=l")
1885	(div:GPR (match_operand:GPR 1 "register_operand" "d")
1886		 (match_operand:GPR 2 "register_operand" "d")))
1887   (set (match_operand:GPR 3 "register_operand" "=h")
1888	(mod:GPR (match_dup 1)
1889		 (match_dup 2)))]
1890  "!TARGET_FIX_VR4120"
1891  { return mips_output_division ("<d>div\t$0,%1,%2", operands); }
1892  [(set_attr "type" "idiv")
1893   (set_attr "mode" "<MODE>")])
1894
1895(define_insn "udivmod<mode>4"
1896  [(set (match_operand:GPR 0 "register_operand" "=l")
1897	(udiv:GPR (match_operand:GPR 1 "register_operand" "d")
1898		  (match_operand:GPR 2 "register_operand" "d")))
1899   (set (match_operand:GPR 3 "register_operand" "=h")
1900	(umod:GPR (match_dup 1)
1901		  (match_dup 2)))]
1902  ""
1903  { return mips_output_division ("<d>divu\t$0,%1,%2", operands); }
1904  [(set_attr "type" "idiv")
1905   (set_attr "mode" "<MODE>")])
1906
1907;;
1908;;  ....................
1909;;
1910;;	SQUARE ROOT
1911;;
1912;;  ....................
1913
1914;; These patterns work around the early SB-1 rev2 core "F1" erratum (see
1915;; "*div[sd]f3" comment for details).
1916
1917(define_insn "sqrt<mode>2"
1918  [(set (match_operand:ANYF 0 "register_operand" "=f")
1919	(sqrt:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
1920  "<sqrt_condition>"
1921{
1922  if (TARGET_FIX_SB1)
1923    return "sqrt.<fmt>\t%0,%1\;mov.<fmt>\t%0,%0";
1924  else
1925    return "sqrt.<fmt>\t%0,%1";
1926}
1927  [(set_attr "type" "fsqrt")
1928   (set_attr "mode" "<UNITMODE>")
1929   (set (attr "length")
1930        (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1931                      (const_int 8)
1932                      (const_int 4)))])
1933
1934(define_insn "*rsqrt<mode>a"
1935  [(set (match_operand:ANYF 0 "register_operand" "=f")
1936	(div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
1937		  (sqrt:ANYF (match_operand:ANYF 2 "register_operand" "f"))))]
1938  "<recip_condition> && flag_unsafe_math_optimizations"
1939{
1940  if (TARGET_FIX_SB1)
1941    return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
1942  else
1943    return "rsqrt.<fmt>\t%0,%2";
1944}
1945  [(set_attr "type" "frsqrt")
1946   (set_attr "mode" "<UNITMODE>")
1947   (set (attr "length")
1948        (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1949                      (const_int 8)
1950                      (const_int 4)))])
1951
1952(define_insn "*rsqrt<mode>b"
1953  [(set (match_operand:ANYF 0 "register_operand" "=f")
1954	(sqrt:ANYF (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
1955			     (match_operand:ANYF 2 "register_operand" "f"))))]
1956  "<recip_condition> && flag_unsafe_math_optimizations"
1957{
1958  if (TARGET_FIX_SB1)
1959    return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
1960  else
1961    return "rsqrt.<fmt>\t%0,%2";
1962}
1963  [(set_attr "type" "frsqrt")
1964   (set_attr "mode" "<UNITMODE>")
1965   (set (attr "length")
1966        (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1967                      (const_int 8)
1968                      (const_int 4)))])
1969
1970;;
1971;;  ....................
1972;;
1973;;	ABSOLUTE VALUE
1974;;
1975;;  ....................
1976
1977;; Do not use the integer abs macro instruction, since that signals an
1978;; exception on -2147483648 (sigh).
1979
1980;; abs.fmt is an arithmetic instruction and treats all NaN inputs as
1981;; invalid; it does not clear their sign bits.  We therefore can't use
1982;; abs.fmt if the signs of NaNs matter.
1983
1984(define_insn "abs<mode>2"
1985  [(set (match_operand:ANYF 0 "register_operand" "=f")
1986	(abs:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
1987  "!HONOR_NANS (<MODE>mode)"
1988  "abs.<fmt>\t%0,%1"
1989  [(set_attr "type" "fabs")
1990   (set_attr "mode" "<UNITMODE>")])
1991
1992;;
1993;;  ...................
1994;;
1995;;  Count leading zeroes.
1996;;
1997;;  ...................
1998;;
1999
2000(define_insn "clz<mode>2"
2001  [(set (match_operand:GPR 0 "register_operand" "=d")
2002	(clz:GPR (match_operand:GPR 1 "register_operand" "d")))]
2003  "ISA_HAS_CLZ_CLO"
2004  "<d>clz\t%0,%1"
2005  [(set_attr "type" "clz")
2006   (set_attr "mode" "<MODE>")])
2007
2008;;
2009;;  ....................
2010;;
2011;;	NEGATION and ONE'S COMPLEMENT
2012;;
2013;;  ....................
2014
2015(define_insn "negsi2"
2016  [(set (match_operand:SI 0 "register_operand" "=d")
2017	(neg:SI (match_operand:SI 1 "register_operand" "d")))]
2018  ""
2019{
2020  if (TARGET_MIPS16)
2021    return "neg\t%0,%1";
2022  else
2023    return "subu\t%0,%.,%1";
2024}
2025  [(set_attr "type"	"arith")
2026   (set_attr "mode"	"SI")])
2027
2028(define_insn "negdi2"
2029  [(set (match_operand:DI 0 "register_operand" "=d")
2030	(neg:DI (match_operand:DI 1 "register_operand" "d")))]
2031  "TARGET_64BIT && !TARGET_MIPS16"
2032  "dsubu\t%0,%.,%1"
2033  [(set_attr "type"	"arith")
2034   (set_attr "mode"	"DI")])
2035
2036;; neg.fmt is an arithmetic instruction and treats all NaN inputs as
2037;; invalid; it does not flip their sign bit.  We therefore can't use
2038;; neg.fmt if the signs of NaNs matter.
2039
2040(define_insn "neg<mode>2"
2041  [(set (match_operand:ANYF 0 "register_operand" "=f")
2042	(neg:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2043  "!HONOR_NANS (<MODE>mode)"
2044  "neg.<fmt>\t%0,%1"
2045  [(set_attr "type" "fneg")
2046   (set_attr "mode" "<UNITMODE>")])
2047
2048(define_insn "one_cmpl<mode>2"
2049  [(set (match_operand:GPR 0 "register_operand" "=d")
2050	(not:GPR (match_operand:GPR 1 "register_operand" "d")))]
2051  ""
2052{
2053  if (TARGET_MIPS16)
2054    return "not\t%0,%1";
2055  else
2056    return "nor\t%0,%.,%1";
2057}
2058  [(set_attr "type" "arith")
2059   (set_attr "mode" "<MODE>")])
2060
2061;;
2062;;  ....................
2063;;
2064;;	LOGICAL
2065;;
2066;;  ....................
2067;;
2068
2069;; Many of these instructions use trivial define_expands, because we
2070;; want to use a different set of constraints when TARGET_MIPS16.
2071
2072(define_expand "and<mode>3"
2073  [(set (match_operand:GPR 0 "register_operand")
2074	(and:GPR (match_operand:GPR 1 "register_operand")
2075		 (match_operand:GPR 2 "uns_arith_operand")))]
2076  ""
2077{
2078  if (TARGET_MIPS16)
2079    operands[2] = force_reg (<MODE>mode, operands[2]);
2080})
2081
2082(define_insn "*and<mode>3"
2083  [(set (match_operand:GPR 0 "register_operand" "=d,d")
2084	(and:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2085		 (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2086  "!TARGET_MIPS16"
2087  "@
2088   and\t%0,%1,%2
2089   andi\t%0,%1,%x2"
2090  [(set_attr "type" "arith")
2091   (set_attr "mode" "<MODE>")])
2092
2093(define_insn "*and<mode>3_mips16"
2094  [(set (match_operand:GPR 0 "register_operand" "=d")
2095	(and:GPR (match_operand:GPR 1 "register_operand" "%0")
2096		 (match_operand:GPR 2 "register_operand" "d")))]
2097  "TARGET_MIPS16"
2098  "and\t%0,%2"
2099  [(set_attr "type" "arith")
2100   (set_attr "mode" "<MODE>")])
2101
2102(define_expand "ior<mode>3"
2103  [(set (match_operand:GPR 0 "register_operand")
2104	(ior:GPR (match_operand:GPR 1 "register_operand")
2105		 (match_operand:GPR 2 "uns_arith_operand")))]
2106  ""
2107{
2108  if (TARGET_MIPS16)
2109    operands[2] = force_reg (<MODE>mode, operands[2]);
2110})
2111
2112(define_insn "*ior<mode>3"
2113  [(set (match_operand:GPR 0 "register_operand" "=d,d")
2114	(ior:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2115		 (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2116  "!TARGET_MIPS16"
2117  "@
2118   or\t%0,%1,%2
2119   ori\t%0,%1,%x2"
2120  [(set_attr "type" "arith")
2121   (set_attr "mode" "<MODE>")])
2122
2123(define_insn "*ior<mode>3_mips16"
2124  [(set (match_operand:GPR 0 "register_operand" "=d")
2125	(ior:GPR (match_operand:GPR 1 "register_operand" "%0")
2126		 (match_operand:GPR 2 "register_operand" "d")))]
2127  "TARGET_MIPS16"
2128  "or\t%0,%2"
2129  [(set_attr "type" "arith")
2130   (set_attr "mode" "<MODE>")])
2131
2132(define_expand "xor<mode>3"
2133  [(set (match_operand:GPR 0 "register_operand")
2134	(xor:GPR (match_operand:GPR 1 "register_operand")
2135		 (match_operand:GPR 2 "uns_arith_operand")))]
2136  ""
2137  "")
2138
2139(define_insn ""
2140  [(set (match_operand:GPR 0 "register_operand" "=d,d")
2141	(xor:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2142		 (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2143  "!TARGET_MIPS16"
2144  "@
2145   xor\t%0,%1,%2
2146   xori\t%0,%1,%x2"
2147  [(set_attr "type" "arith")
2148   (set_attr "mode" "<MODE>")])
2149
2150(define_insn ""
2151  [(set (match_operand:GPR 0 "register_operand" "=d,t,t")
2152	(xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d")
2153		 (match_operand:GPR 2 "uns_arith_operand" "d,K,d")))]
2154  "TARGET_MIPS16"
2155  "@
2156   xor\t%0,%2
2157   cmpi\t%1,%2
2158   cmp\t%1,%2"
2159  [(set_attr "type" "arith")
2160   (set_attr "mode" "<MODE>")
2161   (set_attr_alternative "length"
2162		[(const_int 4)
2163		 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2164			       (const_int 4)
2165			       (const_int 8))
2166		 (const_int 4)])])
2167
2168(define_insn "*nor<mode>3"
2169  [(set (match_operand:GPR 0 "register_operand" "=d")
2170	(and:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
2171		 (not:GPR (match_operand:GPR 2 "register_operand" "d"))))]
2172  "!TARGET_MIPS16"
2173  "nor\t%0,%1,%2"
2174  [(set_attr "type" "arith")
2175   (set_attr "mode" "<MODE>")])
2176
2177;;
2178;;  ....................
2179;;
2180;;	TRUNCATION
2181;;
2182;;  ....................
2183
2184
2185
2186(define_insn "truncdfsf2"
2187  [(set (match_operand:SF 0 "register_operand" "=f")
2188	(float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2189  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2190  "cvt.s.d\t%0,%1"
2191  [(set_attr "type"	"fcvt")
2192   (set_attr "cnv_mode"	"D2S")   
2193   (set_attr "mode"	"SF")])
2194
2195;; Integer truncation patterns.  Truncating SImode values to smaller
2196;; modes is a no-op, as it is for most other GCC ports.  Truncating
2197;; DImode values to SImode is not a no-op for TARGET_64BIT since we
2198;; need to make sure that the lower 32 bits are properly sign-extended
2199;; (see TRULY_NOOP_TRUNCATION).  Truncating DImode values into modes
2200;; smaller than SImode is equivalent to two separate truncations:
2201;;
2202;;                        A       B
2203;;    DI ---> HI  ==  DI ---> SI ---> HI
2204;;    DI ---> QI  ==  DI ---> SI ---> QI
2205;;
2206;; Step A needs a real instruction but step B does not.
2207
2208(define_insn "truncdisi2"
2209  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
2210        (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
2211  "TARGET_64BIT"
2212  "@
2213    sll\t%0,%1,0
2214    sw\t%1,%0"
2215  [(set_attr "type" "shift,store")
2216   (set_attr "mode" "SI")
2217   (set_attr "extended_mips16" "yes,*")])
2218
2219(define_insn "truncdihi2"
2220  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
2221        (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
2222  "TARGET_64BIT"
2223  "@
2224    sll\t%0,%1,0
2225    sh\t%1,%0"
2226  [(set_attr "type" "shift,store")
2227   (set_attr "mode" "SI")
2228   (set_attr "extended_mips16" "yes,*")])
2229
2230(define_insn "truncdiqi2"
2231  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
2232        (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
2233  "TARGET_64BIT"
2234  "@
2235    sll\t%0,%1,0
2236    sb\t%1,%0"
2237  [(set_attr "type" "shift,store")
2238   (set_attr "mode" "SI")
2239   (set_attr "extended_mips16" "yes,*")])
2240
2241;; Combiner patterns to optimize shift/truncate combinations.
2242
2243(define_insn ""
2244  [(set (match_operand:SI 0 "register_operand" "=d")
2245        (truncate:SI
2246	  (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2247                       (match_operand:DI 2 "const_arith_operand" ""))))]
2248  "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
2249  "dsra\t%0,%1,%2"
2250  [(set_attr "type" "shift")
2251   (set_attr "mode" "SI")])
2252
2253(define_insn ""
2254  [(set (match_operand:SI 0 "register_operand" "=d")
2255        (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2256                                  (const_int 32))))]
2257  "TARGET_64BIT && !TARGET_MIPS16"
2258  "dsra\t%0,%1,32"
2259  [(set_attr "type" "shift")
2260   (set_attr "mode" "SI")])
2261
2262
2263;; Combiner patterns for truncate/sign_extend combinations.  They use
2264;; the shift/truncate patterns above.
2265
2266(define_insn_and_split ""
2267  [(set (match_operand:SI 0 "register_operand" "=d")
2268	(sign_extend:SI
2269	    (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
2270  "TARGET_64BIT && !TARGET_MIPS16"
2271  "#"
2272  "&& reload_completed"
2273  [(set (match_dup 2)
2274	(ashift:DI (match_dup 1)
2275		   (const_int 48)))
2276   (set (match_dup 0)
2277	(truncate:SI (ashiftrt:DI (match_dup 2)
2278				  (const_int 48))))]
2279  { operands[2] = gen_lowpart (DImode, operands[0]); })
2280
2281(define_insn_and_split ""
2282  [(set (match_operand:SI 0 "register_operand" "=d")
2283	(sign_extend:SI
2284	    (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
2285  "TARGET_64BIT && !TARGET_MIPS16"
2286  "#"
2287  "&& reload_completed"
2288  [(set (match_dup 2)
2289	(ashift:DI (match_dup 1)
2290		   (const_int 56)))
2291   (set (match_dup 0)
2292	(truncate:SI (ashiftrt:DI (match_dup 2)
2293				  (const_int 56))))]
2294  { operands[2] = gen_lowpart (DImode, operands[0]); })
2295
2296
2297;; Combiner patterns to optimize truncate/zero_extend combinations.
2298
2299(define_insn ""
2300  [(set (match_operand:SI 0 "register_operand" "=d")
2301        (zero_extend:SI (truncate:HI
2302                         (match_operand:DI 1 "register_operand" "d"))))]
2303  "TARGET_64BIT && !TARGET_MIPS16"
2304  "andi\t%0,%1,0xffff"
2305  [(set_attr "type"     "arith")
2306   (set_attr "mode"     "SI")])
2307
2308(define_insn ""
2309  [(set (match_operand:SI 0 "register_operand" "=d")
2310        (zero_extend:SI (truncate:QI
2311                         (match_operand:DI 1 "register_operand" "d"))))]
2312  "TARGET_64BIT && !TARGET_MIPS16"
2313  "andi\t%0,%1,0xff"
2314  [(set_attr "type"     "arith")
2315   (set_attr "mode"     "SI")])
2316
2317(define_insn ""
2318  [(set (match_operand:HI 0 "register_operand" "=d")
2319        (zero_extend:HI (truncate:QI
2320                         (match_operand:DI 1 "register_operand" "d"))))]
2321  "TARGET_64BIT && !TARGET_MIPS16"
2322  "andi\t%0,%1,0xff"
2323  [(set_attr "type"     "arith")
2324   (set_attr "mode"     "HI")])
2325
2326;;
2327;;  ....................
2328;;
2329;;	ZERO EXTENSION
2330;;
2331;;  ....................
2332
2333;; Extension insns.
2334
2335(define_insn_and_split "zero_extendsidi2"
2336  [(set (match_operand:DI 0 "register_operand" "=d,d")
2337        (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,W")))]
2338  "TARGET_64BIT"
2339  "@
2340   #
2341   lwu\t%0,%1"
2342  "&& reload_completed && REG_P (operands[1])"
2343  [(set (match_dup 0)
2344        (ashift:DI (match_dup 1) (const_int 32)))
2345   (set (match_dup 0)
2346        (lshiftrt:DI (match_dup 0) (const_int 32)))]
2347  { operands[1] = gen_lowpart (DImode, operands[1]); }
2348  [(set_attr "type" "multi,load")
2349   (set_attr "mode" "DI")
2350   (set_attr "length" "8,*")])
2351
2352;; Combine is not allowed to convert this insn into a zero_extendsidi2
2353;; because of TRULY_NOOP_TRUNCATION.
2354
2355(define_insn_and_split "*clear_upper32"
2356  [(set (match_operand:DI 0 "register_operand" "=d,d")
2357        (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o")
2358		(const_int 4294967295)))]
2359  "TARGET_64BIT"
2360{
2361  if (which_alternative == 0)
2362    return "#";
2363
2364  operands[1] = gen_lowpart (SImode, operands[1]);
2365  return "lwu\t%0,%1";
2366}
2367  "&& reload_completed && REG_P (operands[1])"
2368  [(set (match_dup 0)
2369        (ashift:DI (match_dup 1) (const_int 32)))
2370   (set (match_dup 0)
2371        (lshiftrt:DI (match_dup 0) (const_int 32)))]
2372  ""
2373  [(set_attr "type" "multi,load")
2374   (set_attr "mode" "DI")
2375   (set_attr "length" "8,*")])
2376
2377(define_expand "zero_extend<SHORT:mode><GPR:mode>2"
2378  [(set (match_operand:GPR 0 "register_operand")
2379        (zero_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
2380  ""
2381{
2382  if (TARGET_MIPS16 && !GENERATE_MIPS16E
2383      && !memory_operand (operands[1], <SHORT:MODE>mode))
2384    {
2385      emit_insn (gen_and<GPR:mode>3 (operands[0],
2386				     gen_lowpart (<GPR:MODE>mode, operands[1]),
2387				     force_reg (<GPR:MODE>mode,
2388						GEN_INT (<SHORT:mask>))));
2389      DONE;
2390    }
2391})
2392
2393(define_insn "*zero_extend<SHORT:mode><GPR:mode>2"
2394  [(set (match_operand:GPR 0 "register_operand" "=d,d")
2395        (zero_extend:GPR
2396	     (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2397  "!TARGET_MIPS16"
2398  "@
2399   andi\t%0,%1,<SHORT:mask>
2400   l<SHORT:size>u\t%0,%1"
2401  [(set_attr "type" "arith,load")
2402   (set_attr "mode" "<GPR:MODE>")])
2403
2404(define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16e"
2405  [(set (match_operand:GPR 0 "register_operand" "=d")
2406        (zero_extend:GPR (match_operand:SHORT 1 "register_operand" "0")))]
2407  "GENERATE_MIPS16E"
2408  "ze<SHORT:size>\t%0"
2409  [(set_attr "type" "arith")
2410   (set_attr "mode" "<GPR:MODE>")])
2411
2412(define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16"
2413  [(set (match_operand:GPR 0 "register_operand" "=d")
2414        (zero_extend:GPR (match_operand:SHORT 1 "memory_operand" "m")))]
2415  "TARGET_MIPS16"
2416  "l<SHORT:size>u\t%0,%1"
2417  [(set_attr "type" "load")
2418   (set_attr "mode" "<GPR:MODE>")])
2419
2420(define_expand "zero_extendqihi2"
2421  [(set (match_operand:HI 0 "register_operand")
2422	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2423  ""
2424{
2425  if (TARGET_MIPS16 && !memory_operand (operands[1], QImode))
2426    {
2427      emit_insn (gen_zero_extendqisi2 (gen_lowpart (SImode, operands[0]),
2428				       operands[1]));
2429      DONE;
2430    }
2431})
2432
2433(define_insn "*zero_extendqihi2"
2434  [(set (match_operand:HI 0 "register_operand" "=d,d")
2435        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2436  "!TARGET_MIPS16"
2437  "@
2438   andi\t%0,%1,0x00ff
2439   lbu\t%0,%1"
2440  [(set_attr "type" "arith,load")
2441   (set_attr "mode" "HI")])
2442
2443(define_insn "*zero_extendqihi2_mips16"
2444  [(set (match_operand:HI 0 "register_operand" "=d")
2445        (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2446  "TARGET_MIPS16"
2447  "lbu\t%0,%1"
2448  [(set_attr "type" "load")
2449   (set_attr "mode" "HI")])
2450
2451;;
2452;;  ....................
2453;;
2454;;	SIGN EXTENSION
2455;;
2456;;  ....................
2457
2458;; Extension insns.
2459;; Those for integer source operand are ordered widest source type first.
2460
2461;; When TARGET_64BIT, all SImode integer registers should already be in
2462;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2).  We can
2463;; therefore get rid of register->register instructions if we constrain
2464;; the source to be in the same register as the destination.
2465;;
2466;; The register alternative has type "arith" so that the pre-reload
2467;; scheduler will treat it as a move.  This reflects what happens if
2468;; the register alternative needs a reload.
2469(define_insn_and_split "extendsidi2"
2470  [(set (match_operand:DI 0 "register_operand" "=d,d")
2471        (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,m")))]
2472  "TARGET_64BIT"
2473  "@
2474   #
2475   lw\t%0,%1"
2476  "&& reload_completed && register_operand (operands[1], VOIDmode)"
2477  [(const_int 0)]
2478{
2479  emit_note (NOTE_INSN_DELETED);
2480  DONE;
2481}
2482  [(set_attr "type" "arith,load")
2483   (set_attr "mode" "DI")])
2484
2485(define_expand "extend<SHORT:mode><GPR:mode>2"
2486  [(set (match_operand:GPR 0 "register_operand")
2487        (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
2488  "")
2489
2490(define_insn "*extend<SHORT:mode><GPR:mode>2_mips16e"
2491  [(set (match_operand:GPR 0 "register_operand" "=d,d")
2492        (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand" "0,m")))]
2493  "GENERATE_MIPS16E"
2494  "@
2495   se<SHORT:size>\t%0
2496   l<SHORT:size>\t%0,%1"
2497  [(set_attr "type" "arith,load")
2498   (set_attr "mode" "<GPR:MODE>")])
2499
2500(define_insn_and_split "*extend<SHORT:mode><GPR:mode>2"
2501  [(set (match_operand:GPR 0 "register_operand" "=d,d")
2502        (sign_extend:GPR
2503	     (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2504  "!ISA_HAS_SEB_SEH && !GENERATE_MIPS16E"
2505  "@
2506   #
2507   l<SHORT:size>\t%0,%1"
2508  "&& reload_completed && REG_P (operands[1])"
2509  [(set (match_dup 0) (ashift:GPR (match_dup 1) (match_dup 2)))
2510   (set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))]
2511{
2512  operands[1] = gen_lowpart (<GPR:MODE>mode, operands[1]);
2513  operands[2] = GEN_INT (GET_MODE_BITSIZE (<GPR:MODE>mode)
2514			 - GET_MODE_BITSIZE (<SHORT:MODE>mode));
2515}
2516  [(set_attr "type" "arith,load")
2517   (set_attr "mode" "<GPR:MODE>")
2518   (set_attr "length" "8,*")])
2519
2520(define_insn "*extend<SHORT:mode><GPR:mode>2_se<SHORT:size>"
2521  [(set (match_operand:GPR 0 "register_operand" "=d,d")
2522        (sign_extend:GPR
2523	     (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2524  "ISA_HAS_SEB_SEH"
2525  "@
2526   se<SHORT:size>\t%0,%1
2527   l<SHORT:size>\t%0,%1"
2528  [(set_attr "type" "arith,load")
2529   (set_attr "mode" "<GPR:MODE>")])
2530
2531;; This pattern generates the same code as extendqisi2; split it into
2532;; that form after reload.
2533(define_insn_and_split "extendqihi2"
2534  [(set (match_operand:HI 0 "register_operand" "=d,d")
2535        (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2536  ""
2537  "#"
2538  "reload_completed"
2539  [(set (match_dup 0) (sign_extend:SI (match_dup 1)))]
2540  { operands[0] = gen_lowpart (SImode, operands[0]); }
2541  [(set_attr "type" "arith,load")
2542   (set_attr "mode" "SI")
2543   (set_attr "length" "8,*")])
2544
2545(define_insn "extendsfdf2"
2546  [(set (match_operand:DF 0 "register_operand" "=f")
2547	(float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2548  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2549  "cvt.d.s\t%0,%1"
2550  [(set_attr "type"	"fcvt")
2551   (set_attr "cnv_mode"	"S2D")   
2552   (set_attr "mode"	"DF")])
2553
2554;;
2555;;  ....................
2556;;
2557;;	CONVERSIONS
2558;;
2559;;  ....................
2560
2561(define_expand "fix_truncdfsi2"
2562  [(set (match_operand:SI 0 "register_operand")
2563	(fix:SI (match_operand:DF 1 "register_operand")))]
2564  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2565{
2566  if (!ISA_HAS_TRUNC_W)
2567    {
2568      emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
2569      DONE;
2570    }
2571})
2572
2573(define_insn "fix_truncdfsi2_insn"
2574  [(set (match_operand:SI 0 "register_operand" "=f")
2575	(fix:SI (match_operand:DF 1 "register_operand" "f")))]
2576  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
2577  "trunc.w.d %0,%1"
2578  [(set_attr "type"	"fcvt")
2579   (set_attr "mode"	"DF")
2580   (set_attr "cnv_mode"	"D2I")
2581   (set_attr "length"	"4")])
2582
2583(define_insn "fix_truncdfsi2_macro"
2584  [(set (match_operand:SI 0 "register_operand" "=f")
2585	(fix:SI (match_operand:DF 1 "register_operand" "f")))
2586   (clobber (match_scratch:DF 2 "=d"))]
2587  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
2588{
2589  if (set_nomacro)
2590    return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
2591  else
2592    return "trunc.w.d %0,%1,%2";
2593}
2594  [(set_attr "type"	"fcvt")
2595   (set_attr "mode"	"DF")
2596   (set_attr "cnv_mode"	"D2I")
2597   (set_attr "length"	"36")])
2598
2599(define_expand "fix_truncsfsi2"
2600  [(set (match_operand:SI 0 "register_operand")
2601	(fix:SI (match_operand:SF 1 "register_operand")))]
2602  "TARGET_HARD_FLOAT"
2603{
2604  if (!ISA_HAS_TRUNC_W)
2605    {
2606      emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
2607      DONE;
2608    }
2609})
2610
2611(define_insn "fix_truncsfsi2_insn"
2612  [(set (match_operand:SI 0 "register_operand" "=f")
2613	(fix:SI (match_operand:SF 1 "register_operand" "f")))]
2614  "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
2615  "trunc.w.s %0,%1"
2616  [(set_attr "type"	"fcvt")
2617   (set_attr "mode"	"SF")
2618   (set_attr "cnv_mode"	"S2I")
2619   (set_attr "length"	"4")])
2620
2621(define_insn "fix_truncsfsi2_macro"
2622  [(set (match_operand:SI 0 "register_operand" "=f")
2623	(fix:SI (match_operand:SF 1 "register_operand" "f")))
2624   (clobber (match_scratch:SF 2 "=d"))]
2625  "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
2626{
2627  if (set_nomacro)
2628    return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
2629  else
2630    return "trunc.w.s %0,%1,%2";
2631}
2632  [(set_attr "type"	"fcvt")
2633   (set_attr "mode"	"SF")
2634   (set_attr "cnv_mode"	"S2I")
2635   (set_attr "length"	"36")])
2636
2637
2638(define_insn "fix_truncdfdi2"
2639  [(set (match_operand:DI 0 "register_operand" "=f")
2640	(fix:DI (match_operand:DF 1 "register_operand" "f")))]
2641  "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2642  "trunc.l.d %0,%1"
2643  [(set_attr "type"	"fcvt")
2644   (set_attr "mode"	"DF")
2645   (set_attr "cnv_mode"	"D2I")
2646   (set_attr "length"	"4")])
2647
2648
2649(define_insn "fix_truncsfdi2"
2650  [(set (match_operand:DI 0 "register_operand" "=f")
2651	(fix:DI (match_operand:SF 1 "register_operand" "f")))]
2652  "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2653  "trunc.l.s %0,%1"
2654  [(set_attr "type"	"fcvt")
2655   (set_attr "mode"	"SF")
2656   (set_attr "cnv_mode"	"S2I")
2657   (set_attr "length"	"4")])
2658
2659
2660(define_insn "floatsidf2"
2661  [(set (match_operand:DF 0 "register_operand" "=f")
2662	(float:DF (match_operand:SI 1 "register_operand" "f")))]
2663  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2664  "cvt.d.w\t%0,%1"
2665  [(set_attr "type"	"fcvt")
2666   (set_attr "mode"	"DF")
2667   (set_attr "cnv_mode"	"I2D")   
2668   (set_attr "length"	"4")])
2669
2670
2671(define_insn "floatdidf2"
2672  [(set (match_operand:DF 0 "register_operand" "=f")
2673	(float:DF (match_operand:DI 1 "register_operand" "f")))]
2674  "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2675  "cvt.d.l\t%0,%1"
2676  [(set_attr "type"	"fcvt")
2677   (set_attr "mode"	"DF")
2678   (set_attr "cnv_mode"	"I2D")   
2679   (set_attr "length"	"4")])
2680
2681
2682(define_insn "floatsisf2"
2683  [(set (match_operand:SF 0 "register_operand" "=f")
2684	(float:SF (match_operand:SI 1 "register_operand" "f")))]
2685  "TARGET_HARD_FLOAT"
2686  "cvt.s.w\t%0,%1"
2687  [(set_attr "type"	"fcvt")
2688   (set_attr "mode"	"SF")
2689   (set_attr "cnv_mode"	"I2S")   
2690   (set_attr "length"	"4")])
2691
2692
2693(define_insn "floatdisf2"
2694  [(set (match_operand:SF 0 "register_operand" "=f")
2695	(float:SF (match_operand:DI 1 "register_operand" "f")))]
2696  "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2697  "cvt.s.l\t%0,%1"
2698  [(set_attr "type"	"fcvt")
2699   (set_attr "mode"	"SF")
2700   (set_attr "cnv_mode"	"I2S")   
2701   (set_attr "length"	"4")])
2702
2703
2704(define_expand "fixuns_truncdfsi2"
2705  [(set (match_operand:SI 0 "register_operand")
2706	(unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
2707  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2708{
2709  rtx reg1 = gen_reg_rtx (DFmode);
2710  rtx reg2 = gen_reg_rtx (DFmode);
2711  rtx reg3 = gen_reg_rtx (SImode);
2712  rtx label1 = gen_label_rtx ();
2713  rtx label2 = gen_label_rtx ();
2714  REAL_VALUE_TYPE offset;
2715
2716  real_2expN (&offset, 31);
2717
2718  if (reg1)			/* Turn off complaints about unreached code.  */
2719    {
2720      emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2721      do_pending_stack_adjust ();
2722
2723      emit_insn (gen_cmpdf (operands[1], reg1));
2724      emit_jump_insn (gen_bge (label1));
2725
2726      emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
2727      emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2728				   gen_rtx_LABEL_REF (VOIDmode, label2)));
2729      emit_barrier ();
2730
2731      emit_label (label1);
2732      emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
2733      emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
2734				     (BITMASK_HIGH, SImode)));
2735
2736      emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
2737      emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2738
2739      emit_label (label2);
2740
2741      /* Allow REG_NOTES to be set on last insn (labels don't have enough
2742	 fields, and can't be used for REG_NOTES anyway).  */
2743      emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2744      DONE;
2745    }
2746})
2747
2748
2749(define_expand "fixuns_truncdfdi2"
2750  [(set (match_operand:DI 0 "register_operand")
2751	(unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
2752  "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2753{
2754  rtx reg1 = gen_reg_rtx (DFmode);
2755  rtx reg2 = gen_reg_rtx (DFmode);
2756  rtx reg3 = gen_reg_rtx (DImode);
2757  rtx label1 = gen_label_rtx ();
2758  rtx label2 = gen_label_rtx ();
2759  REAL_VALUE_TYPE offset;
2760
2761  real_2expN (&offset, 63);
2762
2763  emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2764  do_pending_stack_adjust ();
2765
2766  emit_insn (gen_cmpdf (operands[1], reg1));
2767  emit_jump_insn (gen_bge (label1));
2768
2769  emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
2770  emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2771			       gen_rtx_LABEL_REF (VOIDmode, label2)));
2772  emit_barrier ();
2773
2774  emit_label (label1);
2775  emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
2776  emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
2777  emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
2778
2779  emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
2780  emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
2781
2782  emit_label (label2);
2783
2784  /* Allow REG_NOTES to be set on last insn (labels don't have enough
2785     fields, and can't be used for REG_NOTES anyway).  */
2786  emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2787  DONE;
2788})
2789
2790
2791(define_expand "fixuns_truncsfsi2"
2792  [(set (match_operand:SI 0 "register_operand")
2793	(unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
2794  "TARGET_HARD_FLOAT"
2795{
2796  rtx reg1 = gen_reg_rtx (SFmode);
2797  rtx reg2 = gen_reg_rtx (SFmode);
2798  rtx reg3 = gen_reg_rtx (SImode);
2799  rtx label1 = gen_label_rtx ();
2800  rtx label2 = gen_label_rtx ();
2801  REAL_VALUE_TYPE offset;
2802
2803  real_2expN (&offset, 31);
2804
2805  emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
2806  do_pending_stack_adjust ();
2807
2808  emit_insn (gen_cmpsf (operands[1], reg1));
2809  emit_jump_insn (gen_bge (label1));
2810
2811  emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
2812  emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2813			       gen_rtx_LABEL_REF (VOIDmode, label2)));
2814  emit_barrier ();
2815
2816  emit_label (label1);
2817  emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
2818  emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
2819				 (BITMASK_HIGH, SImode)));
2820
2821  emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
2822  emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2823
2824  emit_label (label2);
2825
2826  /* Allow REG_NOTES to be set on last insn (labels don't have enough
2827     fields, and can't be used for REG_NOTES anyway).  */
2828  emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2829  DONE;
2830})
2831
2832
2833(define_expand "fixuns_truncsfdi2"
2834  [(set (match_operand:DI 0 "register_operand")
2835	(unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
2836  "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2837{
2838  rtx reg1 = gen_reg_rtx (SFmode);
2839  rtx reg2 = gen_reg_rtx (SFmode);
2840  rtx reg3 = gen_reg_rtx (DImode);
2841  rtx label1 = gen_label_rtx ();
2842  rtx label2 = gen_label_rtx ();
2843  REAL_VALUE_TYPE offset;
2844
2845  real_2expN (&offset, 63);
2846
2847  emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
2848  do_pending_stack_adjust ();
2849
2850  emit_insn (gen_cmpsf (operands[1], reg1));
2851  emit_jump_insn (gen_bge (label1));
2852
2853  emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
2854  emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2855			       gen_rtx_LABEL_REF (VOIDmode, label2)));
2856  emit_barrier ();
2857
2858  emit_label (label1);
2859  emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
2860  emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
2861  emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
2862
2863  emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
2864  emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
2865
2866  emit_label (label2);
2867
2868  /* Allow REG_NOTES to be set on last insn (labels don't have enough
2869     fields, and can't be used for REG_NOTES anyway).  */
2870  emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2871  DONE;
2872})
2873
2874;;
2875;;  ....................
2876;;
2877;;	DATA MOVEMENT
2878;;
2879;;  ....................
2880
2881;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
2882
2883(define_expand "extv"
2884  [(set (match_operand 0 "register_operand")
2885	(sign_extract (match_operand:QI 1 "memory_operand")
2886		      (match_operand 2 "immediate_operand")
2887		      (match_operand 3 "immediate_operand")))]
2888  "!TARGET_MIPS16"
2889{
2890  if (mips_expand_unaligned_load (operands[0], operands[1],
2891				  INTVAL (operands[2]),
2892				  INTVAL (operands[3])))
2893    DONE;
2894  else
2895    FAIL;
2896})
2897
2898(define_expand "extzv"
2899  [(set (match_operand 0 "register_operand")
2900	(zero_extract (match_operand 1 "nonimmediate_operand")
2901		      (match_operand 2 "immediate_operand")
2902		      (match_operand 3 "immediate_operand")))]
2903  "!TARGET_MIPS16"
2904{
2905  if (mips_expand_unaligned_load (operands[0], operands[1],
2906				  INTVAL (operands[2]),
2907				  INTVAL (operands[3])))
2908    DONE;
2909  else if (mips_use_ins_ext_p (operands[1], operands[2], operands[3]))
2910    {
2911      if (GET_MODE (operands[0]) == DImode)
2912        emit_insn (gen_extzvdi (operands[0], operands[1], operands[2],
2913				operands[3]));
2914      else
2915        emit_insn (gen_extzvsi (operands[0], operands[1], operands[2],
2916				operands[3]));
2917      DONE;
2918    }
2919  else
2920    FAIL;
2921})
2922
2923(define_insn "extzv<mode>"
2924  [(set (match_operand:GPR 0 "register_operand" "=d")
2925	(zero_extract:GPR (match_operand:GPR 1 "register_operand" "d")
2926			  (match_operand:SI 2 "immediate_operand" "I")
2927			  (match_operand:SI 3 "immediate_operand" "I")))]
2928  "mips_use_ins_ext_p (operands[1], operands[2], operands[3])"
2929  "<d>ext\t%0,%1,%3,%2"
2930  [(set_attr "type"	"arith")
2931   (set_attr "mode"	"<MODE>")])
2932
2933
2934(define_expand "insv"
2935  [(set (zero_extract (match_operand 0 "nonimmediate_operand")
2936		      (match_operand 1 "immediate_operand")
2937		      (match_operand 2 "immediate_operand"))
2938	(match_operand 3 "reg_or_0_operand"))]
2939  "!TARGET_MIPS16"
2940{
2941  if (mips_expand_unaligned_store (operands[0], operands[3],
2942				   INTVAL (operands[1]),
2943				   INTVAL (operands[2])))
2944    DONE;
2945  else if (mips_use_ins_ext_p (operands[0], operands[1], operands[2]))
2946    {
2947      if (GET_MODE (operands[0]) == DImode)
2948        emit_insn (gen_insvdi (operands[0], operands[1], operands[2],
2949			       operands[3]));
2950      else
2951        emit_insn (gen_insvsi (operands[0], operands[1], operands[2],
2952			       operands[3]));
2953      DONE;
2954   }
2955   else
2956     FAIL;
2957})
2958
2959(define_insn "insv<mode>"
2960  [(set (zero_extract:GPR (match_operand:GPR 0 "register_operand" "+d")
2961			  (match_operand:SI 1 "immediate_operand" "I")
2962			  (match_operand:SI 2 "immediate_operand" "I"))
2963	(match_operand:GPR 3 "reg_or_0_operand" "dJ"))]
2964  "mips_use_ins_ext_p (operands[0], operands[1], operands[2])"
2965  "<d>ins\t%0,%z3,%2,%1"
2966  [(set_attr "type"	"arith")
2967   (set_attr "mode"	"<MODE>")])
2968
2969;; Unaligned word moves generated by the bit field patterns.
2970;;
2971;; As far as the rtl is concerned, both the left-part and right-part
2972;; instructions can access the whole field.  However, the real operand
2973;; refers to just the first or the last byte (depending on endianness).
2974;; We therefore use two memory operands to each instruction, one to
2975;; describe the rtl effect and one to use in the assembly output.
2976;;
2977;; Operands 0 and 1 are the rtl-level target and source respectively.
2978;; This allows us to use the standard length calculations for the "load"
2979;; and "store" type attributes.
2980
2981(define_insn "mov_<load>l"
2982  [(set (match_operand:GPR 0 "register_operand" "=d")
2983	(unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
2984		     (match_operand:QI 2 "memory_operand" "m")]
2985		    UNSPEC_LOAD_LEFT))]
2986  "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
2987  "<load>l\t%0,%2"
2988  [(set_attr "type" "load")
2989   (set_attr "mode" "<MODE>")])
2990
2991(define_insn "mov_<load>r"
2992  [(set (match_operand:GPR 0 "register_operand" "=d")
2993	(unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
2994		     (match_operand:QI 2 "memory_operand" "m")
2995		     (match_operand:GPR 3 "register_operand" "0")]
2996		    UNSPEC_LOAD_RIGHT))]
2997  "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
2998  "<load>r\t%0,%2"
2999  [(set_attr "type" "load")
3000   (set_attr "mode" "<MODE>")])
3001
3002(define_insn "mov_<store>l"
3003  [(set (match_operand:BLK 0 "memory_operand" "=m")
3004	(unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3005		     (match_operand:QI 2 "memory_operand" "m")]
3006		    UNSPEC_STORE_LEFT))]
3007  "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
3008  "<store>l\t%z1,%2"
3009  [(set_attr "type" "store")
3010   (set_attr "mode" "<MODE>")])
3011
3012(define_insn "mov_<store>r"
3013  [(set (match_operand:BLK 0 "memory_operand" "+m")
3014	(unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3015		     (match_operand:QI 2 "memory_operand" "m")
3016		     (match_dup 0)]
3017		    UNSPEC_STORE_RIGHT))]
3018  "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
3019  "<store>r\t%z1,%2"
3020  [(set_attr "type" "store")
3021   (set_attr "mode" "<MODE>")])
3022
3023;; An instruction to calculate the high part of a 64-bit SYMBOL_GENERAL.
3024;; The required value is:
3025;;
3026;;	(%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
3027;;
3028;; which translates to:
3029;;
3030;;	lui	op0,%highest(op1)
3031;;	daddiu	op0,op0,%higher(op1)
3032;;	dsll	op0,op0,16
3033;;	daddiu	op0,op0,%hi(op1)
3034;;	dsll	op0,op0,16
3035;;
3036;; The split is deferred until after flow2 to allow the peephole2 below
3037;; to take effect.
3038(define_insn_and_split "*lea_high64"
3039  [(set (match_operand:DI 0 "register_operand" "=d")
3040	(high:DI (match_operand:DI 1 "general_symbolic_operand" "")))]
3041  "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3042  "#"
3043  "&& flow2_completed"
3044  [(set (match_dup 0) (high:DI (match_dup 2)))
3045   (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
3046   (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
3047   (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3048   (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
3049{
3050  operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3051  operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
3052}
3053  [(set_attr "length" "20")])
3054
3055;; Use a scratch register to reduce the latency of the above pattern
3056;; on superscalar machines.  The optimized sequence is:
3057;;
3058;;	lui	op1,%highest(op2)
3059;;	lui	op0,%hi(op2)
3060;;	daddiu	op1,op1,%higher(op2)
3061;;	dsll32	op1,op1,0
3062;;	daddu	op1,op1,op0
3063(define_peephole2
3064  [(set (match_operand:DI 1 "register_operand")
3065	(high:DI (match_operand:DI 2 "general_symbolic_operand")))
3066   (match_scratch:DI 0 "d")]
3067  "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3068  [(set (match_dup 1) (high:DI (match_dup 3)))
3069   (set (match_dup 0) (high:DI (match_dup 4)))
3070   (set (match_dup 1) (lo_sum:DI (match_dup 1) (match_dup 3)))
3071   (set (match_dup 1) (ashift:DI (match_dup 1) (const_int 32)))
3072   (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 0)))]
3073{
3074  operands[3] = mips_unspec_address (operands[2], SYMBOL_64_HIGH);
3075  operands[4] = mips_unspec_address (operands[2], SYMBOL_64_LOW);
3076})
3077
3078;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
3079;; SYMBOL_GENERAL X will take 6 cycles.  This next pattern allows combine
3080;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
3081;; used once.  We can then use the sequence:
3082;;
3083;;	lui	op0,%highest(op1)
3084;;	lui	op2,%hi(op1)
3085;;	daddiu	op0,op0,%higher(op1)
3086;;	daddiu	op2,op2,%lo(op1)
3087;;	dsll32	op0,op0,0
3088;;	daddu	op0,op0,op2
3089;;
3090;; which takes 4 cycles on most superscalar targets.
3091(define_insn_and_split "*lea64"
3092  [(set (match_operand:DI 0 "register_operand" "=d")
3093	(match_operand:DI 1 "general_symbolic_operand" ""))
3094   (clobber (match_scratch:DI 2 "=&d"))]
3095  "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
3096  "#"
3097  "&& reload_completed"
3098  [(set (match_dup 0) (high:DI (match_dup 3)))
3099   (set (match_dup 2) (high:DI (match_dup 4)))
3100   (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3101   (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
3102   (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
3103   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
3104{
3105  operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3106  operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
3107}
3108  [(set_attr "length" "24")])
3109
3110;; Insns to fetch a global symbol from a big GOT.
3111
3112(define_insn_and_split "*xgot_hi<mode>"
3113  [(set (match_operand:P 0 "register_operand" "=d")
3114	(high:P (match_operand:P 1 "global_got_operand" "")))]
3115  "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3116  "#"
3117  "&& reload_completed"
3118  [(set (match_dup 0) (high:P (match_dup 2)))
3119   (set (match_dup 0) (plus:P (match_dup 0) (match_dup 3)))]
3120{
3121  operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3122  operands[3] = pic_offset_table_rtx;
3123}
3124  [(set_attr "got" "xgot_high")
3125   (set_attr "mode" "<MODE>")])
3126
3127(define_insn_and_split "*xgot_lo<mode>"
3128  [(set (match_operand:P 0 "register_operand" "=d")
3129	(lo_sum:P (match_operand:P 1 "register_operand" "d")
3130		  (match_operand:P 2 "global_got_operand" "")))]
3131  "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3132  "#"
3133  "&& reload_completed"
3134  [(set (match_dup 0)
3135	(unspec:P [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3136  { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
3137  [(set_attr "got" "load")
3138   (set_attr "mode" "<MODE>")])
3139
3140;; Insns to fetch a global symbol from a normal GOT.
3141
3142(define_insn_and_split "*got_disp<mode>"
3143  [(set (match_operand:P 0 "register_operand" "=d")
3144	(match_operand:P 1 "global_got_operand" ""))]
3145  "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3146  "#"
3147  "&& reload_completed"
3148  [(set (match_dup 0)
3149	(unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3150{
3151  operands[2] = pic_offset_table_rtx;
3152  operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3153}
3154  [(set_attr "got" "load")
3155   (set_attr "mode" "<MODE>")])
3156
3157;; Insns for loading the high part of a local symbol.
3158
3159(define_insn_and_split "*got_page<mode>"
3160  [(set (match_operand:P 0 "register_operand" "=d")
3161	(high:P (match_operand:P 1 "local_got_operand" "")))]
3162  "TARGET_EXPLICIT_RELOCS"
3163  "#"
3164  "&& reload_completed"
3165  [(set (match_dup 0)
3166	(unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3167{
3168  operands[2] = pic_offset_table_rtx;
3169  operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3170}
3171  [(set_attr "got" "load")
3172   (set_attr "mode" "<MODE>")])
3173
3174;; Lower-level instructions for loading an address from the GOT.
3175;; We could use MEMs, but an unspec gives more optimization
3176;; opportunities.
3177
3178(define_insn "load_got<mode>"
3179  [(set (match_operand:P 0 "register_operand" "=d")
3180	(unspec:P [(match_operand:P 1 "register_operand" "d")
3181		   (match_operand:P 2 "immediate_operand" "")]
3182		  UNSPEC_LOAD_GOT))]
3183  ""
3184  "<load>\t%0,%R2(%1)"
3185  [(set_attr "type" "load")
3186   (set_attr "mode" "<MODE>")
3187   (set_attr "length" "4")])
3188
3189;; Instructions for adding the low 16 bits of an address to a register.
3190;; Operand 2 is the address: print_operand works out which relocation
3191;; should be applied.
3192
3193(define_insn "*low<mode>"
3194  [(set (match_operand:P 0 "register_operand" "=d")
3195	(lo_sum:P (match_operand:P 1 "register_operand" "d")
3196		  (match_operand:P 2 "immediate_operand" "")))]
3197  "!TARGET_MIPS16"
3198  "<d>addiu\t%0,%1,%R2"
3199  [(set_attr "type" "arith")
3200   (set_attr "mode" "<MODE>")])
3201
3202(define_insn "*low<mode>_mips16"
3203  [(set (match_operand:P 0 "register_operand" "=d")
3204	(lo_sum:P (match_operand:P 1 "register_operand" "0")
3205		  (match_operand:P 2 "immediate_operand" "")))]
3206  "TARGET_MIPS16"
3207  "<d>addiu\t%0,%R2"
3208  [(set_attr "type" "arith")
3209   (set_attr "mode" "<MODE>")
3210   (set_attr "length" "8")])
3211
3212;; Allow combine to split complex const_int load sequences, using operand 2
3213;; to store the intermediate results.  See move_operand for details.
3214(define_split
3215  [(set (match_operand:GPR 0 "register_operand")
3216	(match_operand:GPR 1 "splittable_const_int_operand"))
3217   (clobber (match_operand:GPR 2 "register_operand"))]
3218  ""
3219  [(const_int 0)]
3220{
3221  mips_move_integer (operands[0], operands[2], INTVAL (operands[1]));
3222  DONE;
3223})
3224
3225;; Likewise, for symbolic operands.
3226(define_split
3227  [(set (match_operand:P 0 "register_operand")
3228	(match_operand:P 1 "splittable_symbolic_operand"))
3229   (clobber (match_operand:P 2 "register_operand"))]
3230  ""
3231  [(set (match_dup 0) (match_dup 1))]
3232  { operands[1] = mips_split_symbol (operands[2], operands[1]); })
3233
3234;; 64-bit integer moves
3235
3236;; Unlike most other insns, the move insns can't be split with
3237;; different predicates, because register spilling and other parts of
3238;; the compiler, have memoized the insn number already.
3239
3240(define_expand "movdi"
3241  [(set (match_operand:DI 0 "")
3242	(match_operand:DI 1 ""))]
3243  ""
3244{
3245  if (mips_legitimize_move (DImode, operands[0], operands[1]))
3246    DONE;
3247})
3248
3249;; For mips16, we need a special case to handle storing $31 into
3250;; memory, since we don't have a constraint to match $31.  This
3251;; instruction can be generated by save_restore_insns.
3252
3253(define_insn "*mov<mode>_ra"
3254  [(set (match_operand:GPR 0 "stack_operand" "=m")
3255	(reg:GPR 31))]
3256  "TARGET_MIPS16"
3257  "<store>\t$31,%0"
3258  [(set_attr "type" "store")
3259   (set_attr "mode" "<MODE>")])
3260
3261(define_insn "*movdi_32bit"
3262  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*a,*d,*B*C*D,*B*C*D,*d,*m")
3263	(match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*a,*d,*m,*B*C*D,*B*C*D"))]
3264  "!TARGET_64BIT && !TARGET_MIPS16
3265   && (register_operand (operands[0], DImode)
3266       || reg_or_0_operand (operands[1], DImode))"
3267  { return mips_output_move (operands[0], operands[1]); }
3268  [(set_attr "type"	"arith,arith,load,store,mthilo,mfhilo,xfer,load,xfer,store")
3269   (set_attr "mode"	"DI")
3270   (set_attr "length"   "8,16,*,*,8,8,8,*,8,*")])
3271
3272(define_insn "*movdi_32bit_mips16"
3273  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
3274	(match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
3275  "!TARGET_64BIT && TARGET_MIPS16
3276   && (register_operand (operands[0], DImode)
3277       || register_operand (operands[1], DImode))"
3278  { return mips_output_move (operands[0], operands[1]); }
3279  [(set_attr "type"	"arith,arith,arith,arith,arith,load,store,mfhilo")
3280   (set_attr "mode"	"DI")
3281   (set_attr "length"	"8,8,8,8,12,*,*,8")])
3282
3283(define_insn "*movdi_64bit"
3284  [(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")
3285	(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"))]
3286  "TARGET_64BIT && !TARGET_MIPS16
3287   && (register_operand (operands[0], DImode)
3288       || reg_or_0_operand (operands[1], DImode))"
3289  { return mips_output_move (operands[0], operands[1]); }
3290  [(set_attr "type"	"arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,mthilo,xfer,load,xfer,store")
3291   (set_attr "mode"	"DI")
3292   (set_attr "length"	"4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")])
3293
3294(define_insn "*movdi_64bit_mips16"
3295  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3296	(match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3297  "TARGET_64BIT && TARGET_MIPS16
3298   && (register_operand (operands[0], DImode)
3299       || register_operand (operands[1], DImode))"
3300  { return mips_output_move (operands[0], operands[1]); }
3301  [(set_attr "type"	"arith,arith,arith,arith,arith,const,load,store")
3302   (set_attr "mode"	"DI")
3303   (set_attr_alternative "length"
3304		[(const_int 4)
3305		 (const_int 4)
3306		 (const_int 4)
3307		 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3308			       (const_int 4)
3309			       (const_int 8))
3310		 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3311			       (const_int 8)
3312			       (const_int 12))
3313		 (const_string "*")
3314		 (const_string "*")
3315		 (const_string "*")])])
3316
3317
3318;; On the mips16, we can split ld $r,N($r) into an add and a load,
3319;; when the original load is a 4 byte instruction but the add and the
3320;; load are 2 2 byte instructions.
3321
3322(define_split
3323  [(set (match_operand:DI 0 "register_operand")
3324	(mem:DI (plus:DI (match_dup 0)
3325			 (match_operand:DI 1 "const_int_operand"))))]
3326  "TARGET_64BIT && TARGET_MIPS16 && reload_completed
3327   && !TARGET_DEBUG_D_MODE
3328   && REG_P (operands[0])
3329   && M16_REG_P (REGNO (operands[0]))
3330   && GET_CODE (operands[1]) == CONST_INT
3331   && ((INTVAL (operands[1]) < 0
3332	&& INTVAL (operands[1]) >= -0x10)
3333       || (INTVAL (operands[1]) >= 32 * 8
3334	   && INTVAL (operands[1]) <= 31 * 8 + 0x8)
3335       || (INTVAL (operands[1]) >= 0
3336	   && INTVAL (operands[1]) < 32 * 8
3337	   && (INTVAL (operands[1]) & 7) != 0))"
3338  [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
3339   (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
3340{
3341  HOST_WIDE_INT val = INTVAL (operands[1]);
3342
3343  if (val < 0)
3344    operands[2] = const0_rtx;
3345  else if (val >= 32 * 8)
3346    {
3347      int off = val & 7;
3348
3349      operands[1] = GEN_INT (0x8 + off);
3350      operands[2] = GEN_INT (val - off - 0x8);
3351    }
3352  else
3353    {
3354      int off = val & 7;
3355
3356      operands[1] = GEN_INT (off);
3357      operands[2] = GEN_INT (val - off);
3358    }
3359})
3360
3361;; 32-bit Integer moves
3362
3363;; Unlike most other insns, the move insns can't be split with
3364;; different predicates, because register spilling and other parts of
3365;; the compiler, have memoized the insn number already.
3366
3367(define_expand "movsi"
3368  [(set (match_operand:SI 0 "")
3369	(match_operand:SI 1 ""))]
3370  ""
3371{
3372  if (mips_legitimize_move (SImode, operands[0], operands[1]))
3373    DONE;
3374})
3375
3376;; The difference between these two is whether or not ints are allowed
3377;; in FP registers (off by default, use -mdebugh to enable).
3378
3379(define_insn "*movsi_internal"
3380  [(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")
3381	(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"))]
3382  "!TARGET_MIPS16
3383   && (register_operand (operands[0], SImode)
3384       || reg_or_0_operand (operands[1], SImode))"
3385  { return mips_output_move (operands[0], operands[1]); }
3386  [(set_attr "type"	"arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,xfer,xfer,mthilo,mfhilo,xfer,load,xfer,store")
3387   (set_attr "mode"	"SI")
3388   (set_attr "length"	"4,*,*,*,*,4,4,*,4,*,4,4,4,4,4,*,4,*")])
3389
3390(define_insn "*movsi_mips16"
3391  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3392	(match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3393  "TARGET_MIPS16
3394   && (register_operand (operands[0], SImode)
3395       || register_operand (operands[1], SImode))"
3396  { return mips_output_move (operands[0], operands[1]); }
3397  [(set_attr "type"	"arith,arith,arith,arith,arith,const,load,store")
3398   (set_attr "mode"	"SI")
3399   (set_attr_alternative "length"
3400		[(const_int 4)
3401		 (const_int 4)
3402		 (const_int 4)
3403		 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3404			       (const_int 4)
3405			       (const_int 8))
3406		 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3407			       (const_int 8)
3408			       (const_int 12))
3409		 (const_string "*")
3410		 (const_string "*")
3411		 (const_string "*")])])
3412
3413;; On the mips16, we can split lw $r,N($r) into an add and a load,
3414;; when the original load is a 4 byte instruction but the add and the
3415;; load are 2 2 byte instructions.
3416
3417(define_split
3418  [(set (match_operand:SI 0 "register_operand")
3419	(mem:SI (plus:SI (match_dup 0)
3420			 (match_operand:SI 1 "const_int_operand"))))]
3421  "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3422   && REG_P (operands[0])
3423   && M16_REG_P (REGNO (operands[0]))
3424   && GET_CODE (operands[1]) == CONST_INT
3425   && ((INTVAL (operands[1]) < 0
3426	&& INTVAL (operands[1]) >= -0x80)
3427       || (INTVAL (operands[1]) >= 32 * 4
3428	   && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
3429       || (INTVAL (operands[1]) >= 0
3430	   && INTVAL (operands[1]) < 32 * 4
3431	   && (INTVAL (operands[1]) & 3) != 0))"
3432  [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3433   (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
3434{
3435  HOST_WIDE_INT val = INTVAL (operands[1]);
3436
3437  if (val < 0)
3438    operands[2] = const0_rtx;
3439  else if (val >= 32 * 4)
3440    {
3441      int off = val & 3;
3442
3443      operands[1] = GEN_INT (0x7c + off);
3444      operands[2] = GEN_INT (val - off - 0x7c);
3445    }
3446  else
3447    {
3448      int off = val & 3;
3449
3450      operands[1] = GEN_INT (off);
3451      operands[2] = GEN_INT (val - off);
3452    }
3453})
3454
3455;; On the mips16, we can split a load of certain constants into a load
3456;; and an add.  This turns a 4 byte instruction into 2 2 byte
3457;; instructions.
3458
3459(define_split
3460  [(set (match_operand:SI 0 "register_operand")
3461	(match_operand:SI 1 "const_int_operand"))]
3462  "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3463   && REG_P (operands[0])
3464   && M16_REG_P (REGNO (operands[0]))
3465   && GET_CODE (operands[1]) == CONST_INT
3466   && INTVAL (operands[1]) >= 0x100
3467   && INTVAL (operands[1]) <= 0xff + 0x7f"
3468  [(set (match_dup 0) (match_dup 1))
3469   (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
3470{
3471  int val = INTVAL (operands[1]);
3472
3473  operands[1] = GEN_INT (0xff);
3474  operands[2] = GEN_INT (val - 0xff);
3475})
3476
3477;; This insn handles moving CCmode values.  It's really just a
3478;; slightly simplified copy of movsi_internal2, with additional cases
3479;; to move a condition register to a general register and to move
3480;; between the general registers and the floating point registers.
3481
3482(define_insn "movcc"
3483  [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m")
3484	(match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))]
3485  "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3486  { return mips_output_move (operands[0], operands[1]); }
3487  [(set_attr "type"	"xfer,arith,load,store,xfer,xfer,fmove,fpload,fpstore")
3488   (set_attr "mode"	"SI")
3489   (set_attr "length"	"8,4,*,*,4,4,4,*,*")])
3490
3491;; Reload condition code registers.  reload_incc and reload_outcc
3492;; both handle moves from arbitrary operands into condition code
3493;; registers.  reload_incc handles the more common case in which
3494;; a source operand is constrained to be in a condition-code
3495;; register, but has not been allocated to one.
3496;;
3497;; Sometimes, such as in movcc, we have a CCmode destination whose
3498;; constraints do not include 'z'.  reload_outcc handles the case
3499;; when such an operand is allocated to a condition-code register.
3500;;
3501;; Note that reloads from a condition code register to some
3502;; other location can be done using ordinary moves.  Moving
3503;; into a GPR takes a single movcc, moving elsewhere takes
3504;; two.  We can leave these cases to the generic reload code.
3505(define_expand "reload_incc"
3506  [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
3507	(match_operand:CC 1 "general_operand" ""))
3508   (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3509  "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3510{
3511  mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
3512  DONE;
3513})
3514
3515(define_expand "reload_outcc"
3516  [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
3517	(match_operand:CC 1 "register_operand" ""))
3518   (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3519  "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3520{
3521  mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
3522  DONE;
3523})
3524
3525;; MIPS4 supports loading and storing a floating point register from
3526;; the sum of two general registers.  We use two versions for each of
3527;; these four instructions: one where the two general registers are
3528;; SImode, and one where they are DImode.  This is because general
3529;; registers will be in SImode when they hold 32 bit values, but,
3530;; since the 32 bit values are always sign extended, the [ls][wd]xc1
3531;; instructions will still work correctly.
3532
3533;; ??? Perhaps it would be better to support these instructions by
3534;; modifying GO_IF_LEGITIMATE_ADDRESS and friends.  However, since
3535;; these instructions can only be used to load and store floating
3536;; point registers, that would probably cause trouble in reload.
3537
3538(define_insn "*<ANYF:loadx>_<P:mode>"
3539  [(set (match_operand:ANYF 0 "register_operand" "=f")
3540	(mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d")
3541			  (match_operand:P 2 "register_operand" "d"))))]
3542  "ISA_HAS_FP4"
3543  "<ANYF:loadx>\t%0,%1(%2)"
3544  [(set_attr "type" "fpidxload")
3545   (set_attr "mode" "<ANYF:UNITMODE>")])
3546
3547(define_insn "*<ANYF:storex>_<P:mode>"
3548  [(set (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d")
3549			  (match_operand:P 2 "register_operand" "d")))
3550	(match_operand:ANYF 0 "register_operand" "f"))]
3551  "ISA_HAS_FP4"
3552  "<ANYF:storex>\t%0,%1(%2)"
3553  [(set_attr "type" "fpidxstore")
3554   (set_attr "mode" "<ANYF:UNITMODE>")])
3555
3556;; 16-bit Integer moves
3557
3558;; Unlike most other insns, the move insns can't be split with
3559;; different predicates, because register spilling and other parts of
3560;; the compiler, have memoized the insn number already.
3561;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
3562
3563(define_expand "movhi"
3564  [(set (match_operand:HI 0 "")
3565	(match_operand:HI 1 ""))]
3566  ""
3567{
3568  if (mips_legitimize_move (HImode, operands[0], operands[1]))
3569    DONE;
3570})
3571
3572(define_insn "*movhi_internal"
3573  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
3574	(match_operand:HI 1 "move_operand"         "d,I,m,dJ,*f,*d,*f,*d"))]
3575  "!TARGET_MIPS16
3576   && (register_operand (operands[0], HImode)
3577       || reg_or_0_operand (operands[1], HImode))"
3578  "@
3579    move\t%0,%1
3580    li\t%0,%1
3581    lhu\t%0,%1
3582    sh\t%z1,%0
3583    mfc1\t%0,%1
3584    mtc1\t%1,%0
3585    mov.s\t%0,%1
3586    mt%0\t%1"
3587  [(set_attr "type"	"arith,arith,load,store,xfer,xfer,fmove,mthilo")
3588   (set_attr "mode"	"HI")
3589   (set_attr "length"	"4,4,*,*,4,4,4,4")])
3590
3591(define_insn "*movhi_mips16"
3592  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
3593	(match_operand:HI 1 "move_operand"         "d,d,y,K,N,m,d"))]
3594  "TARGET_MIPS16
3595   && (register_operand (operands[0], HImode)
3596       || register_operand (operands[1], HImode))"
3597  "@
3598    move\t%0,%1
3599    move\t%0,%1
3600    move\t%0,%1
3601    li\t%0,%1
3602    #
3603    lhu\t%0,%1
3604    sh\t%1,%0"
3605  [(set_attr "type"	"arith,arith,arith,arith,arith,load,store")
3606   (set_attr "mode"	"HI")
3607   (set_attr_alternative "length"
3608		[(const_int 4)
3609		 (const_int 4)
3610		 (const_int 4)
3611		 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3612			       (const_int 4)
3613			       (const_int 8))
3614		 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3615			       (const_int 8)
3616			       (const_int 12))
3617		 (const_string "*")
3618		 (const_string "*")])])
3619
3620
3621;; On the mips16, we can split lh $r,N($r) into an add and a load,
3622;; when the original load is a 4 byte instruction but the add and the
3623;; load are 2 2 byte instructions.
3624
3625(define_split
3626  [(set (match_operand:HI 0 "register_operand")
3627	(mem:HI (plus:SI (match_dup 0)
3628			 (match_operand:SI 1 "const_int_operand"))))]
3629  "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3630   && REG_P (operands[0])
3631   && M16_REG_P (REGNO (operands[0]))
3632   && GET_CODE (operands[1]) == CONST_INT
3633   && ((INTVAL (operands[1]) < 0
3634	&& INTVAL (operands[1]) >= -0x80)
3635       || (INTVAL (operands[1]) >= 32 * 2
3636	   && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
3637       || (INTVAL (operands[1]) >= 0
3638	   && INTVAL (operands[1]) < 32 * 2
3639	   && (INTVAL (operands[1]) & 1) != 0))"
3640  [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3641   (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
3642{
3643  HOST_WIDE_INT val = INTVAL (operands[1]);
3644
3645  if (val < 0)
3646    operands[2] = const0_rtx;
3647  else if (val >= 32 * 2)
3648    {
3649      int off = val & 1;
3650
3651      operands[1] = GEN_INT (0x7e + off);
3652      operands[2] = GEN_INT (val - off - 0x7e);
3653    }
3654  else
3655    {
3656      int off = val & 1;
3657
3658      operands[1] = GEN_INT (off);
3659      operands[2] = GEN_INT (val - off);
3660    }
3661})
3662
3663;; 8-bit Integer moves
3664
3665;; Unlike most other insns, the move insns can't be split with
3666;; different predicates, because register spilling and other parts of
3667;; the compiler, have memoized the insn number already.
3668;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
3669
3670(define_expand "movqi"
3671  [(set (match_operand:QI 0 "")
3672	(match_operand:QI 1 ""))]
3673  ""
3674{
3675  if (mips_legitimize_move (QImode, operands[0], operands[1]))
3676    DONE;
3677})
3678
3679(define_insn "*movqi_internal"
3680  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
3681	(match_operand:QI 1 "move_operand"         "d,I,m,dJ,*f,*d,*f,*d"))]
3682  "!TARGET_MIPS16
3683   && (register_operand (operands[0], QImode)
3684       || reg_or_0_operand (operands[1], QImode))"
3685  "@
3686    move\t%0,%1
3687    li\t%0,%1
3688    lbu\t%0,%1
3689    sb\t%z1,%0
3690    mfc1\t%0,%1
3691    mtc1\t%1,%0
3692    mov.s\t%0,%1
3693    mt%0\t%1"
3694  [(set_attr "type"	"arith,arith,load,store,xfer,xfer,fmove,mthilo")
3695   (set_attr "mode"	"QI")
3696   (set_attr "length"	"4,4,*,*,4,4,4,4")])
3697
3698(define_insn "*movqi_mips16"
3699  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
3700	(match_operand:QI 1 "move_operand"         "d,d,y,K,N,m,d"))]
3701  "TARGET_MIPS16
3702   && (register_operand (operands[0], QImode)
3703       || register_operand (operands[1], QImode))"
3704  "@
3705    move\t%0,%1
3706    move\t%0,%1
3707    move\t%0,%1
3708    li\t%0,%1
3709    #
3710    lbu\t%0,%1
3711    sb\t%1,%0"
3712  [(set_attr "type"	"arith,arith,arith,arith,arith,load,store")
3713   (set_attr "mode"	"QI")
3714   (set_attr "length"	"4,4,4,4,8,*,*")])
3715
3716;; On the mips16, we can split lb $r,N($r) into an add and a load,
3717;; when the original load is a 4 byte instruction but the add and the
3718;; load are 2 2 byte instructions.
3719
3720(define_split
3721  [(set (match_operand:QI 0 "register_operand")
3722	(mem:QI (plus:SI (match_dup 0)
3723			 (match_operand:SI 1 "const_int_operand"))))]
3724  "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3725   && REG_P (operands[0])
3726   && M16_REG_P (REGNO (operands[0]))
3727   && GET_CODE (operands[1]) == CONST_INT
3728   && ((INTVAL (operands[1]) < 0
3729	&& INTVAL (operands[1]) >= -0x80)
3730       || (INTVAL (operands[1]) >= 32
3731	   && INTVAL (operands[1]) <= 31 + 0x7f))"
3732  [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3733   (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
3734{
3735  HOST_WIDE_INT val = INTVAL (operands[1]);
3736
3737  if (val < 0)
3738    operands[2] = const0_rtx;
3739  else
3740    {
3741      operands[1] = GEN_INT (0x7f);
3742      operands[2] = GEN_INT (val - 0x7f);
3743    }
3744})
3745
3746;; 32-bit floating point moves
3747
3748(define_expand "movsf"
3749  [(set (match_operand:SF 0 "")
3750	(match_operand:SF 1 ""))]
3751  ""
3752{
3753  if (mips_legitimize_move (SFmode, operands[0], operands[1]))
3754    DONE;
3755})
3756
3757(define_insn "*movsf_hardfloat"
3758  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
3759	(match_operand:SF 1 "move_operand" "f,G,m,f,G,*d,*f,*G*d,*m,*d"))]
3760  "TARGET_HARD_FLOAT
3761   && (register_operand (operands[0], SFmode)
3762       || reg_or_0_operand (operands[1], SFmode))"
3763  { return mips_output_move (operands[0], operands[1]); }
3764  [(set_attr "type"	"fmove,xfer,fpload,fpstore,store,xfer,xfer,arith,load,store")
3765   (set_attr "mode"	"SF")
3766   (set_attr "length"	"4,4,*,*,*,4,4,4,*,*")])
3767
3768(define_insn "*movsf_softfloat"
3769  [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
3770	(match_operand:SF 1 "move_operand" "Gd,m,d"))]
3771  "TARGET_SOFT_FLOAT && !TARGET_MIPS16
3772   && (register_operand (operands[0], SFmode)
3773       || reg_or_0_operand (operands[1], SFmode))"
3774  { return mips_output_move (operands[0], operands[1]); }
3775  [(set_attr "type"	"arith,load,store")
3776   (set_attr "mode"	"SF")
3777   (set_attr "length"	"4,*,*")])
3778
3779(define_insn "*movsf_mips16"
3780  [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
3781	(match_operand:SF 1 "move_operand" "d,d,y,m,d"))]
3782  "TARGET_MIPS16
3783   && (register_operand (operands[0], SFmode)
3784       || register_operand (operands[1], SFmode))"
3785  { return mips_output_move (operands[0], operands[1]); }
3786  [(set_attr "type"	"arith,arith,arith,load,store")
3787   (set_attr "mode"	"SF")
3788   (set_attr "length"	"4,4,4,*,*")])
3789
3790
3791;; 64-bit floating point moves
3792
3793(define_expand "movdf"
3794  [(set (match_operand:DF 0 "")
3795	(match_operand:DF 1 ""))]
3796  ""
3797{
3798  if (mips_legitimize_move (DFmode, operands[0], operands[1]))
3799    DONE;
3800})
3801
3802(define_insn "*movdf_hardfloat_64bit"
3803  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
3804	(match_operand:DF 1 "move_operand" "f,G,m,f,G,*d,*f,*d*G,*m,*d"))]
3805  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT
3806   && (register_operand (operands[0], DFmode)
3807       || reg_or_0_operand (operands[1], DFmode))"
3808  { return mips_output_move (operands[0], operands[1]); }
3809  [(set_attr "type"	"fmove,xfer,fpload,fpstore,store,xfer,xfer,arith,load,store")
3810   (set_attr "mode"	"DF")
3811   (set_attr "length"	"4,4,*,*,*,4,4,4,*,*")])
3812
3813(define_insn "*movdf_hardfloat_32bit"
3814  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
3815	(match_operand:DF 1 "move_operand" "f,G,m,f,G,*d,*f,*d*G,*m,*d"))]
3816  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT
3817   && (register_operand (operands[0], DFmode)
3818       || reg_or_0_operand (operands[1], DFmode))"
3819  { return mips_output_move (operands[0], operands[1]); }
3820  [(set_attr "type"	"fmove,xfer,fpload,fpstore,store,xfer,xfer,arith,load,store")
3821   (set_attr "mode"	"DF")
3822   (set_attr "length"	"4,8,*,*,*,8,8,8,*,*")])
3823
3824(define_insn "*movdf_softfloat"
3825  [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f")
3826	(match_operand:DF 1 "move_operand" "dG,m,dG,f,d,f"))]
3827  "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
3828   && (register_operand (operands[0], DFmode)
3829       || reg_or_0_operand (operands[1], DFmode))"
3830  { return mips_output_move (operands[0], operands[1]); }
3831  [(set_attr "type"	"arith,load,store,xfer,xfer,fmove")
3832   (set_attr "mode"	"DF")
3833   (set_attr "length"	"8,*,*,4,4,4")])
3834
3835(define_insn "*movdf_mips16"
3836  [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
3837	(match_operand:DF 1 "move_operand" "d,d,y,m,d"))]
3838  "TARGET_MIPS16
3839   && (register_operand (operands[0], DFmode)
3840       || register_operand (operands[1], DFmode))"
3841  { return mips_output_move (operands[0], operands[1]); }
3842  [(set_attr "type"	"arith,arith,arith,load,store")
3843   (set_attr "mode"	"DF")
3844   (set_attr "length"	"8,8,8,*,*")])
3845
3846(define_split
3847  [(set (match_operand:DI 0 "nonimmediate_operand")
3848	(match_operand:DI 1 "move_operand"))]
3849  "reload_completed && !TARGET_64BIT
3850   && mips_split_64bit_move_p (operands[0], operands[1])"
3851  [(const_int 0)]
3852{
3853  mips_split_64bit_move (operands[0], operands[1]);
3854  DONE;
3855})
3856
3857(define_split
3858  [(set (match_operand:DF 0 "nonimmediate_operand")
3859	(match_operand:DF 1 "move_operand"))]
3860  "reload_completed && !TARGET_64BIT
3861   && mips_split_64bit_move_p (operands[0], operands[1])"
3862  [(const_int 0)]
3863{
3864  mips_split_64bit_move (operands[0], operands[1]);
3865  DONE;
3866})
3867
3868;; When generating mips16 code, split moves of negative constants into
3869;; a positive "li" followed by a negation.
3870(define_split
3871  [(set (match_operand 0 "register_operand")
3872	(match_operand 1 "const_int_operand"))]
3873  "TARGET_MIPS16 && reload_completed && INTVAL (operands[1]) < 0"
3874  [(set (match_dup 2)
3875	(match_dup 3))
3876   (set (match_dup 2)
3877	(neg:SI (match_dup 2)))]
3878{
3879  operands[2] = gen_lowpart (SImode, operands[0]);
3880  operands[3] = GEN_INT (-INTVAL (operands[1]));
3881})
3882
3883;; 64-bit paired-single floating point moves
3884
3885(define_expand "movv2sf"
3886  [(set (match_operand:V2SF 0)
3887	(match_operand:V2SF 1))]
3888  "TARGET_PAIRED_SINGLE_FLOAT"
3889{
3890  if (mips_legitimize_move (V2SFmode, operands[0], operands[1]))
3891    DONE;
3892})
3893
3894(define_insn "movv2sf_hardfloat_64bit"
3895  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
3896	(match_operand:V2SF 1 "move_operand" "f,YG,m,f,YG,*d,*f,*d*YG,*m,*d"))]
3897  "TARGET_PAIRED_SINGLE_FLOAT
3898   && TARGET_64BIT
3899   && (register_operand (operands[0], V2SFmode)
3900       || reg_or_0_operand (operands[1], V2SFmode))"
3901  { return mips_output_move (operands[0], operands[1]); }
3902  [(set_attr "type" "fmove,xfer,fpload,fpstore,store,xfer,xfer,arith,load,store")
3903   (set_attr "mode" "SF")
3904   (set_attr "length" "4,4,*,*,*,4,4,4,*,*")])
3905
3906;; The HI and LO registers are not truly independent.  If we move an mthi
3907;; instruction before an mflo instruction, it will make the result of the
3908;; mflo unpredictable.  The same goes for mtlo and mfhi.
3909;;
3910;; We cope with this by making the mflo and mfhi patterns use both HI and LO.
3911;; Operand 1 is the register we want, operand 2 is the other one.
3912;;
3913;; When generating VR4120 or VR4130 code, we use macc{,hi} and
3914;; dmacc{,hi} instead of mfhi and mflo.  This avoids both the normal
3915;; MIPS III hi/lo hazards and the errata related to -mfix-vr4130.
3916
3917(define_expand "mfhilo_<mode>"
3918  [(set (match_operand:GPR 0 "register_operand")
3919	(unspec:GPR [(match_operand:GPR 1 "register_operand")
3920		     (match_operand:GPR 2 "register_operand")]
3921		    UNSPEC_MFHILO))])
3922
3923(define_insn "*mfhilo_<mode>"
3924  [(set (match_operand:GPR 0 "register_operand" "=d,d")
3925	(unspec:GPR [(match_operand:GPR 1 "register_operand" "h,l")
3926		     (match_operand:GPR 2 "register_operand" "l,h")]
3927		    UNSPEC_MFHILO))]
3928  "!ISA_HAS_MACCHI"
3929  "mf%1\t%0"
3930  [(set_attr "type" "mfhilo")
3931   (set_attr "mode" "<MODE>")])
3932
3933(define_insn "*mfhilo_<mode>_macc"
3934  [(set (match_operand:GPR 0 "register_operand" "=d,d")
3935	(unspec:GPR [(match_operand:GPR 1 "register_operand" "h,l")
3936		     (match_operand:GPR 2 "register_operand" "l,h")]
3937		    UNSPEC_MFHILO))]
3938  "ISA_HAS_MACCHI"
3939{
3940  if (REGNO (operands[1]) == HI_REGNUM)
3941    return "<d>macchi\t%0,%.,%.";
3942  else
3943    return "<d>macc\t%0,%.,%.";
3944}
3945  [(set_attr "type" "mfhilo")
3946   (set_attr "mode" "<MODE>")])
3947
3948;; Patterns for loading or storing part of a paired floating point
3949;; register.  We need them because odd-numbered floating-point registers
3950;; are not fully independent: see mips_split_64bit_move.
3951
3952;; Load the low word of operand 0 with operand 1.
3953(define_insn "load_df_low"
3954  [(set (match_operand:DF 0 "register_operand" "=f,f")
3955	(unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")]
3956		   UNSPEC_LOAD_DF_LOW))]
3957  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
3958{
3959  operands[0] = mips_subword (operands[0], 0);
3960  return mips_output_move (operands[0], operands[1]);
3961}
3962  [(set_attr "type"	"xfer,fpload")
3963   (set_attr "mode"	"SF")])
3964
3965;; Load the high word of operand 0 from operand 1, preserving the value
3966;; in the low word.
3967(define_insn "load_df_high"
3968  [(set (match_operand:DF 0 "register_operand" "=f,f")
3969	(unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")
3970		    (match_operand:DF 2 "register_operand" "0,0")]
3971		   UNSPEC_LOAD_DF_HIGH))]
3972  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
3973{
3974  operands[0] = mips_subword (operands[0], 1);
3975  return mips_output_move (operands[0], operands[1]);
3976}
3977  [(set_attr "type"	"xfer,fpload")
3978   (set_attr "mode"	"SF")])
3979
3980;; Store the high word of operand 1 in operand 0.  The corresponding
3981;; low-word move is done in the normal way.
3982(define_insn "store_df_high"
3983  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
3984	(unspec:SI [(match_operand:DF 1 "register_operand" "f,f")]
3985		   UNSPEC_STORE_DF_HIGH))]
3986  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
3987{
3988  operands[1] = mips_subword (operands[1], 1);
3989  return mips_output_move (operands[0], operands[1]);
3990}
3991  [(set_attr "type"	"xfer,fpstore")
3992   (set_attr "mode"	"SF")])
3993
3994;; Insn to initialize $gp for n32/n64 abicalls.  Operand 0 is the offset
3995;; of _gp from the start of this function.  Operand 1 is the incoming
3996;; function address.
3997(define_insn_and_split "loadgp"
3998  [(unspec_volatile [(match_operand 0 "" "")
3999		     (match_operand 1 "register_operand" "")] UNSPEC_LOADGP)]
4000  "mips_current_loadgp_style () == LOADGP_NEWABI"
4001  "#"
4002  ""
4003  [(set (match_dup 2) (match_dup 3))
4004   (set (match_dup 2) (match_dup 4))
4005   (set (match_dup 2) (match_dup 5))]
4006{
4007  operands[2] = pic_offset_table_rtx;
4008  operands[3] = gen_rtx_HIGH (Pmode, operands[0]);
4009  operands[4] = gen_rtx_PLUS (Pmode, operands[2], operands[1]);
4010  operands[5] = gen_rtx_LO_SUM (Pmode, operands[2], operands[0]);
4011}
4012  [(set_attr "length" "12")])
4013
4014;; Likewise, for -mno-shared code.  Operand 0 is the __gnu_local_gp symbol.
4015(define_insn_and_split "loadgp_noshared"
4016  [(unspec_volatile [(match_operand 0 "" "")] UNSPEC_LOADGP)]
4017  "mips_current_loadgp_style () == LOADGP_ABSOLUTE"
4018  "#"
4019  ""
4020  [(const_int 0)]
4021{
4022  emit_move_insn (pic_offset_table_rtx, operands[0]);
4023  DONE;
4024}
4025  [(set_attr "length" "8")])
4026
4027;; The use of gp is hidden when not using explicit relocations.
4028;; This blockage instruction prevents the gp load from being
4029;; scheduled after an implicit use of gp.  It also prevents
4030;; the load from being deleted as dead.
4031(define_insn "loadgp_blockage"
4032  [(unspec_volatile [(reg:DI 28)] UNSPEC_BLOCKAGE)]
4033  ""
4034  ""
4035  [(set_attr "type"	"unknown")
4036   (set_attr "mode"	"none")
4037   (set_attr "length"	"0")])
4038
4039;; Emit a .cprestore directive, which normally expands to a single store
4040;; instruction.  Note that we continue to use .cprestore for explicit reloc
4041;; code so that jals inside inline asms will work correctly.
4042(define_insn "cprestore"
4043  [(unspec_volatile [(match_operand 0 "const_int_operand" "I,i")]
4044		    UNSPEC_CPRESTORE)]
4045  ""
4046{
4047  if (set_nomacro && which_alternative == 1)
4048    return ".set\tmacro\;.cprestore\t%0\;.set\tnomacro";
4049  else
4050    return ".cprestore\t%0";
4051}
4052  [(set_attr "type" "store")
4053   (set_attr "length" "4,12")])
4054
4055;; Block moves, see mips.c for more details.
4056;; Argument 0 is the destination
4057;; Argument 1 is the source
4058;; Argument 2 is the length
4059;; Argument 3 is the alignment
4060
4061(define_expand "movmemsi"
4062  [(parallel [(set (match_operand:BLK 0 "general_operand")
4063		   (match_operand:BLK 1 "general_operand"))
4064	      (use (match_operand:SI 2 ""))
4065	      (use (match_operand:SI 3 "const_int_operand"))])]
4066  "!TARGET_MIPS16 && !TARGET_MEMCPY"
4067{
4068  if (mips_expand_block_move (operands[0], operands[1], operands[2]))
4069    DONE;
4070  else
4071    FAIL;
4072})
4073
4074;;
4075;;  ....................
4076;;
4077;;	SHIFTS
4078;;
4079;;  ....................
4080
4081(define_expand "<optab><mode>3"
4082  [(set (match_operand:GPR 0 "register_operand")
4083	(any_shift:GPR (match_operand:GPR 1 "register_operand")
4084		       (match_operand:SI 2 "arith_operand")))]
4085  ""
4086{
4087  /* On the mips16, a shift of more than 8 is a four byte instruction,
4088     so, for a shift between 8 and 16, it is just as fast to do two
4089     shifts of 8 or less.  If there is a lot of shifting going on, we
4090     may win in CSE.  Otherwise combine will put the shifts back
4091     together again.  This can be called by function_arg, so we must
4092     be careful not to allocate a new register if we've reached the
4093     reload pass.  */
4094  if (TARGET_MIPS16
4095      && optimize
4096      && GET_CODE (operands[2]) == CONST_INT
4097      && INTVAL (operands[2]) > 8
4098      && INTVAL (operands[2]) <= 16
4099      && !reload_in_progress
4100      && !reload_completed)
4101    {
4102      rtx temp = gen_reg_rtx (<MODE>mode);
4103
4104      emit_insn (gen_<optab><mode>3 (temp, operands[1], GEN_INT (8)));
4105      emit_insn (gen_<optab><mode>3 (operands[0], temp,
4106				     GEN_INT (INTVAL (operands[2]) - 8)));
4107      DONE;
4108    }
4109})
4110
4111(define_insn "*<optab><mode>3"
4112  [(set (match_operand:GPR 0 "register_operand" "=d")
4113	(any_shift:GPR (match_operand:GPR 1 "register_operand" "d")
4114		       (match_operand:SI 2 "arith_operand" "dI")))]
4115  "!TARGET_MIPS16"
4116{
4117  if (GET_CODE (operands[2]) == CONST_INT)
4118    operands[2] = GEN_INT (INTVAL (operands[2])
4119			   & (GET_MODE_BITSIZE (<MODE>mode) - 1));
4120
4121  return "<d><insn>\t%0,%1,%2";
4122}
4123  [(set_attr "type" "shift")
4124   (set_attr "mode" "<MODE>")])
4125
4126(define_insn "*<optab>si3_extend"
4127  [(set (match_operand:DI 0 "register_operand" "=d")
4128	(sign_extend:DI
4129	   (any_shift:SI (match_operand:SI 1 "register_operand" "d")
4130			 (match_operand:SI 2 "arith_operand" "dI"))))]
4131  "TARGET_64BIT && !TARGET_MIPS16"
4132{
4133  if (GET_CODE (operands[2]) == CONST_INT)
4134    operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4135
4136  return "<insn>\t%0,%1,%2";
4137}
4138  [(set_attr "type" "shift")
4139   (set_attr "mode" "SI")])
4140
4141(define_insn "*<optab>si3_mips16"
4142  [(set (match_operand:SI 0 "register_operand" "=d,d")
4143	(any_shift:SI (match_operand:SI 1 "register_operand" "0,d")
4144		      (match_operand:SI 2 "arith_operand" "d,I")))]
4145  "TARGET_MIPS16"
4146{
4147  if (which_alternative == 0)
4148    return "<insn>\t%0,%2";
4149
4150  operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4151  return "<insn>\t%0,%1,%2";
4152}
4153  [(set_attr "type" "shift")
4154   (set_attr "mode" "SI")
4155   (set_attr_alternative "length"
4156		[(const_int 4)
4157		 (if_then_else (match_operand 2 "m16_uimm3_b")
4158			       (const_int 4)
4159			       (const_int 8))])])
4160
4161;; We need separate DImode MIPS16 patterns because of the irregularity
4162;; of right shifts.
4163(define_insn "*ashldi3_mips16"
4164  [(set (match_operand:DI 0 "register_operand" "=d,d")
4165	(ashift:DI (match_operand:DI 1 "register_operand" "0,d")
4166		   (match_operand:SI 2 "arith_operand" "d,I")))]
4167  "TARGET_64BIT && TARGET_MIPS16"
4168{
4169  if (which_alternative == 0)
4170    return "dsll\t%0,%2";
4171
4172  operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4173  return "dsll\t%0,%1,%2";
4174}
4175  [(set_attr "type" "shift")
4176   (set_attr "mode" "DI")
4177   (set_attr_alternative "length"
4178		[(const_int 4)
4179		 (if_then_else (match_operand 2 "m16_uimm3_b")
4180			       (const_int 4)
4181			       (const_int 8))])])
4182
4183(define_insn "*ashrdi3_mips16"
4184  [(set (match_operand:DI 0 "register_operand" "=d,d")
4185	(ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
4186		     (match_operand:SI 2 "arith_operand" "d,I")))]
4187  "TARGET_64BIT && TARGET_MIPS16"
4188{
4189  if (GET_CODE (operands[2]) == CONST_INT)
4190    operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4191
4192  return "dsra\t%0,%2";
4193}
4194  [(set_attr "type" "shift")
4195   (set_attr "mode" "DI")
4196   (set_attr_alternative "length"
4197		[(const_int 4)
4198		 (if_then_else (match_operand 2 "m16_uimm3_b")
4199			       (const_int 4)
4200			       (const_int 8))])])
4201
4202(define_insn "*lshrdi3_mips16"
4203  [(set (match_operand:DI 0 "register_operand" "=d,d")
4204	(lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
4205		     (match_operand:SI 2 "arith_operand" "d,I")))]
4206  "TARGET_64BIT && TARGET_MIPS16"
4207{
4208  if (GET_CODE (operands[2]) == CONST_INT)
4209    operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4210
4211  return "dsrl\t%0,%2";
4212}
4213  [(set_attr "type" "shift")
4214   (set_attr "mode" "DI")
4215   (set_attr_alternative "length"
4216		[(const_int 4)
4217		 (if_then_else (match_operand 2 "m16_uimm3_b")
4218			       (const_int 4)
4219			       (const_int 8))])])
4220
4221;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4222
4223(define_split
4224  [(set (match_operand:GPR 0 "register_operand")
4225	(any_shift:GPR (match_operand:GPR 1 "register_operand")
4226		       (match_operand:GPR 2 "const_int_operand")))]
4227  "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4228   && GET_CODE (operands[2]) == CONST_INT
4229   && INTVAL (operands[2]) > 8
4230   && INTVAL (operands[2]) <= 16"
4231  [(set (match_dup 0) (any_shift:GPR (match_dup 1) (const_int 8)))
4232   (set (match_dup 0) (any_shift:GPR (match_dup 0) (match_dup 2)))]
4233  { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4234
4235;; If we load a byte on the mips16 as a bitfield, the resulting
4236;; sequence of instructions is too complicated for combine, because it
4237;; involves four instructions: a load, a shift, a constant load into a
4238;; register, and an and (the key problem here is that the mips16 does
4239;; not have and immediate).  We recognize a shift of a load in order
4240;; to make it simple enough for combine to understand.
4241;;
4242;; The length here is the worst case: the length of the split version
4243;; will be more accurate.
4244(define_insn_and_split ""
4245  [(set (match_operand:SI 0 "register_operand" "=d")
4246	(lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
4247		     (match_operand:SI 2 "immediate_operand" "I")))]
4248  "TARGET_MIPS16"
4249  "#"
4250  ""
4251  [(set (match_dup 0) (match_dup 1))
4252   (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
4253  ""
4254  [(set_attr "type"	"load")
4255   (set_attr "mode"	"SI")
4256   (set_attr "length"	"16")])
4257
4258(define_insn "rotr<mode>3"
4259  [(set (match_operand:GPR 0 "register_operand" "=d")
4260	(rotatert:GPR (match_operand:GPR 1 "register_operand" "d")
4261		      (match_operand:SI 2 "arith_operand" "dI")))]
4262  "ISA_HAS_ROTR_<MODE>"
4263{
4264  if (GET_CODE (operands[2]) == CONST_INT)
4265    gcc_assert (INTVAL (operands[2]) >= 0
4266		&& INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode));
4267
4268  return "<d>ror\t%0,%1,%2";
4269}
4270  [(set_attr "type" "shift")
4271   (set_attr "mode" "<MODE>")])
4272
4273;;
4274;;  ....................
4275;;
4276;;	COMPARISONS
4277;;
4278;;  ....................
4279
4280;; Flow here is rather complex:
4281;;
4282;;  1)	The cmp{si,di,sf,df} routine is called.  It deposits the arguments
4283;;	into cmp_operands[] but generates no RTL.
4284;;
4285;;  2)	The appropriate branch define_expand is called, which then
4286;;	creates the appropriate RTL for the comparison and branch.
4287;;	Different CC modes are used, based on what type of branch is
4288;;	done, so that we can constrain things appropriately.  There
4289;;	are assumptions in the rest of GCC that break if we fold the
4290;;	operands into the branches for integer operations, and use cc0
4291;;	for floating point, so we use the fp status register instead.
4292;;	If needed, an appropriate temporary is created to hold the
4293;;	of the integer compare.
4294
4295(define_expand "cmp<mode>"
4296  [(set (cc0)
4297	(compare:CC (match_operand:GPR 0 "register_operand")
4298		    (match_operand:GPR 1 "nonmemory_operand")))]
4299  ""
4300{
4301  cmp_operands[0] = operands[0];
4302  cmp_operands[1] = operands[1];
4303  DONE;
4304})
4305
4306(define_expand "cmp<mode>"
4307  [(set (cc0)
4308	(compare:CC (match_operand:SCALARF 0 "register_operand")
4309		    (match_operand:SCALARF 1 "register_operand")))]
4310  ""
4311{
4312  cmp_operands[0] = operands[0];
4313  cmp_operands[1] = operands[1];
4314  DONE;
4315})
4316
4317;;
4318;;  ....................
4319;;
4320;;	CONDITIONAL BRANCHES
4321;;
4322;;  ....................
4323
4324;; Conditional branches on floating-point equality tests.
4325
4326(define_insn "*branch_fp"
4327  [(set (pc)
4328        (if_then_else
4329         (match_operator 0 "equality_operator"
4330                         [(match_operand:CC 2 "register_operand" "z")
4331			  (const_int 0)])
4332         (label_ref (match_operand 1 "" ""))
4333         (pc)))]
4334  "TARGET_HARD_FLOAT"
4335{
4336  return mips_output_conditional_branch (insn, operands,
4337					 MIPS_BRANCH ("b%F0", "%Z2%1"),
4338					 MIPS_BRANCH ("b%W0", "%Z2%1"));
4339}
4340  [(set_attr "type" "branch")
4341   (set_attr "mode" "none")])
4342
4343(define_insn "*branch_fp_inverted"
4344  [(set (pc)
4345        (if_then_else
4346         (match_operator 0 "equality_operator"
4347                         [(match_operand:CC 2 "register_operand" "z")
4348			  (const_int 0)])
4349         (pc)
4350         (label_ref (match_operand 1 "" ""))))]
4351  "TARGET_HARD_FLOAT"
4352{
4353  return mips_output_conditional_branch (insn, operands,
4354					 MIPS_BRANCH ("b%W0", "%Z2%1"),
4355					 MIPS_BRANCH ("b%F0", "%Z2%1"));
4356}
4357  [(set_attr "type" "branch")
4358   (set_attr "mode" "none")])
4359
4360;; Conditional branches on ordered comparisons with zero.
4361
4362(define_insn "*branch_order<mode>"
4363  [(set (pc)
4364	(if_then_else
4365	 (match_operator 0 "order_operator"
4366			 [(match_operand:GPR 2 "register_operand" "d")
4367			  (const_int 0)])
4368	 (label_ref (match_operand 1 "" ""))
4369	 (pc)))]
4370  "!TARGET_MIPS16"
4371  { return mips_output_order_conditional_branch (insn, operands, false); }
4372  [(set_attr "type" "branch")
4373   (set_attr "mode" "none")])
4374
4375(define_insn "*branch_order<mode>_inverted"
4376  [(set (pc)
4377	(if_then_else
4378	 (match_operator 0 "order_operator"
4379			 [(match_operand:GPR 2 "register_operand" "d")
4380			  (const_int 0)])
4381	 (pc)
4382	 (label_ref (match_operand 1 "" ""))))]
4383  "!TARGET_MIPS16"
4384  { return mips_output_order_conditional_branch (insn, operands, true); }
4385  [(set_attr "type" "branch")
4386   (set_attr "mode" "none")])
4387
4388;; Conditional branch on equality comparison.
4389
4390(define_insn "*branch_equality<mode>"
4391  [(set (pc)
4392	(if_then_else
4393	 (match_operator 0 "equality_operator"
4394			 [(match_operand:GPR 2 "register_operand" "d")
4395			  (match_operand:GPR 3 "reg_or_0_operand" "dJ")])
4396	 (label_ref (match_operand 1 "" ""))
4397	 (pc)))]
4398  "!TARGET_MIPS16"
4399{
4400  return mips_output_conditional_branch (insn, operands,
4401					 MIPS_BRANCH ("b%C0", "%2,%z3,%1"),
4402					 MIPS_BRANCH ("b%N0", "%2,%z3,%1"));
4403}
4404  [(set_attr "type" "branch")
4405   (set_attr "mode" "none")])
4406
4407(define_insn "*branch_equality<mode>_inverted"
4408  [(set (pc)
4409	(if_then_else
4410	 (match_operator 0 "equality_operator"
4411			 [(match_operand:GPR 2 "register_operand" "d")
4412			  (match_operand:GPR 3 "reg_or_0_operand" "dJ")])
4413	 (pc)
4414	 (label_ref (match_operand 1 "" ""))))]
4415  "!TARGET_MIPS16"
4416{
4417  return mips_output_conditional_branch (insn, operands,
4418					 MIPS_BRANCH ("b%N0", "%2,%z3,%1"),
4419					 MIPS_BRANCH ("b%C0", "%2,%z3,%1"));
4420}
4421  [(set_attr "type" "branch")
4422   (set_attr "mode" "none")])
4423
4424;; MIPS16 branches
4425
4426(define_insn "*branch_equality<mode>_mips16"
4427  [(set (pc)
4428	(if_then_else
4429	 (match_operator 0 "equality_operator"
4430			 [(match_operand:GPR 1 "register_operand" "d,t")
4431			  (const_int 0)])
4432	 (match_operand 2 "pc_or_label_operand" "")
4433	 (match_operand 3 "pc_or_label_operand" "")))]
4434  "TARGET_MIPS16"
4435{
4436  if (operands[2] != pc_rtx)
4437    {
4438      if (which_alternative == 0)
4439	return "b%C0z\t%1,%2";
4440      else
4441	return "bt%C0z\t%2";
4442    }
4443  else
4444    {
4445      if (which_alternative == 0)
4446	return "b%N0z\t%1,%3";
4447      else
4448	return "bt%N0z\t%3";
4449    }
4450}
4451  [(set_attr "type" "branch")
4452   (set_attr "mode" "none")
4453   (set_attr "length" "8")])
4454
4455(define_expand "b<code>"
4456  [(set (pc)
4457	(if_then_else (any_cond:CC (cc0)
4458				   (const_int 0))
4459		      (label_ref (match_operand 0 ""))
4460		      (pc)))]
4461  ""
4462{
4463  gen_conditional_branch (operands, <CODE>);
4464  DONE;
4465})
4466
4467;; Used to implement built-in functions.
4468(define_expand "condjump"
4469  [(set (pc)
4470	(if_then_else (match_operand 0)
4471		      (label_ref (match_operand 1))
4472		      (pc)))])
4473
4474;;
4475;;  ....................
4476;;
4477;;	SETTING A REGISTER FROM A COMPARISON
4478;;
4479;;  ....................
4480
4481(define_expand "seq"
4482  [(set (match_operand:SI 0 "register_operand")
4483	(eq:SI (match_dup 1)
4484	       (match_dup 2)))]
4485  ""
4486  { if (mips_emit_scc (EQ, operands[0])) DONE; else FAIL; })
4487
4488(define_insn "*seq_<mode>"
4489  [(set (match_operand:GPR 0 "register_operand" "=d")
4490	(eq:GPR (match_operand:GPR 1 "register_operand" "d")
4491		(const_int 0)))]
4492  "!TARGET_MIPS16"
4493  "sltu\t%0,%1,1"
4494  [(set_attr "type" "slt")
4495   (set_attr "mode" "<MODE>")])
4496
4497(define_insn "*seq_<mode>_mips16"
4498  [(set (match_operand:GPR 0 "register_operand" "=t")
4499	(eq:GPR (match_operand:GPR 1 "register_operand" "d")
4500		(const_int 0)))]
4501  "TARGET_MIPS16"
4502  "sltu\t%1,1"
4503  [(set_attr "type" "slt")
4504   (set_attr "mode" "<MODE>")])
4505
4506;; "sne" uses sltu instructions in which the first operand is $0.
4507;; This isn't possible in mips16 code.
4508
4509(define_expand "sne"
4510  [(set (match_operand:SI 0 "register_operand")
4511	(ne:SI (match_dup 1)
4512	       (match_dup 2)))]
4513  "!TARGET_MIPS16"
4514  { if (mips_emit_scc (NE, operands[0])) DONE; else FAIL; })
4515
4516(define_insn "*sne_<mode>"
4517  [(set (match_operand:GPR 0 "register_operand" "=d")
4518	(ne:GPR (match_operand:GPR 1 "register_operand" "d")
4519		(const_int 0)))]
4520  "!TARGET_MIPS16"
4521  "sltu\t%0,%.,%1"
4522  [(set_attr "type" "slt")
4523   (set_attr "mode" "<MODE>")])
4524
4525(define_expand "sgt"
4526  [(set (match_operand:SI 0 "register_operand")
4527	(gt:SI (match_dup 1)
4528	       (match_dup 2)))]
4529  ""
4530  { if (mips_emit_scc (GT, operands[0])) DONE; else FAIL; })
4531
4532(define_insn "*sgt_<mode>"
4533  [(set (match_operand:GPR 0 "register_operand" "=d")
4534	(gt:GPR (match_operand:GPR 1 "register_operand" "d")
4535		(match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
4536  "!TARGET_MIPS16"
4537  "slt\t%0,%z2,%1"
4538  [(set_attr "type" "slt")
4539   (set_attr "mode" "<MODE>")])
4540
4541(define_insn "*sgt_<mode>_mips16"
4542  [(set (match_operand:GPR 0 "register_operand" "=t")
4543	(gt:GPR (match_operand:GPR 1 "register_operand" "d")
4544		(match_operand:GPR 2 "register_operand" "d")))]
4545  "TARGET_MIPS16"
4546  "slt\t%2,%1"
4547  [(set_attr "type" "slt")
4548   (set_attr "mode" "<MODE>")])
4549
4550(define_expand "sge"
4551  [(set (match_operand:SI 0 "register_operand")
4552	(ge:SI (match_dup 1)
4553	       (match_dup 2)))]
4554  ""
4555  { if (mips_emit_scc (GE, operands[0])) DONE; else FAIL; })
4556
4557(define_insn "*sge_<mode>"
4558  [(set (match_operand:GPR 0 "register_operand" "=d")
4559	(ge:GPR (match_operand:GPR 1 "register_operand" "d")
4560		(const_int 1)))]
4561  "!TARGET_MIPS16"
4562  "slt\t%0,%.,%1"
4563  [(set_attr "type" "slt")
4564   (set_attr "mode" "<MODE>")])
4565
4566(define_expand "slt"
4567  [(set (match_operand:SI 0 "register_operand")
4568	(lt:SI (match_dup 1)
4569	       (match_dup 2)))]
4570  ""
4571  { if (mips_emit_scc (LT, operands[0])) DONE; else FAIL; })
4572
4573(define_insn "*slt_<mode>"
4574  [(set (match_operand:GPR 0 "register_operand" "=d")
4575	(lt:GPR (match_operand:GPR 1 "register_operand" "d")
4576		(match_operand:GPR 2 "arith_operand" "dI")))]
4577  "!TARGET_MIPS16"
4578  "slt\t%0,%1,%2"
4579  [(set_attr "type" "slt")
4580   (set_attr "mode" "<MODE>")])
4581
4582(define_insn "*slt_<mode>_mips16"
4583  [(set (match_operand:GPR 0 "register_operand" "=t,t")
4584	(lt:GPR (match_operand:GPR 1 "register_operand" "d,d")
4585		(match_operand:GPR 2 "arith_operand" "d,I")))]
4586  "TARGET_MIPS16"
4587  "slt\t%1,%2"
4588  [(set_attr "type" "slt")
4589   (set_attr "mode" "<MODE>")
4590   (set_attr_alternative "length"
4591		[(const_int 4)
4592		 (if_then_else (match_operand 2 "m16_uimm8_1")
4593			       (const_int 4)
4594			       (const_int 8))])])
4595
4596(define_expand "sle"
4597  [(set (match_operand:SI 0 "register_operand")
4598	(le:SI (match_dup 1)
4599	       (match_dup 2)))]
4600  ""
4601  { if (mips_emit_scc (LE, operands[0])) DONE; else FAIL; })
4602
4603(define_insn "*sle_<mode>"
4604  [(set (match_operand:GPR 0 "register_operand" "=d")
4605	(le:GPR (match_operand:GPR 1 "register_operand" "d")
4606		(match_operand:GPR 2 "sle_operand" "")))]
4607  "!TARGET_MIPS16"
4608{
4609  operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
4610  return "slt\t%0,%1,%2";
4611}
4612  [(set_attr "type" "slt")
4613   (set_attr "mode" "<MODE>")])
4614
4615(define_insn "*sle_<mode>_mips16"
4616  [(set (match_operand:GPR 0 "register_operand" "=t")
4617	(le:GPR (match_operand:GPR 1 "register_operand" "d")
4618		(match_operand:GPR 2 "sle_operand" "")))]
4619  "TARGET_MIPS16"
4620{
4621  operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
4622  return "slt\t%1,%2";
4623}
4624  [(set_attr "type" "slt")
4625   (set_attr "mode" "<MODE>")
4626   (set (attr "length") (if_then_else (match_operand 2 "m16_uimm8_m1_1")
4627				      (const_int 4)
4628				      (const_int 8)))])
4629
4630(define_expand "sgtu"
4631  [(set (match_operand:SI 0 "register_operand")
4632	(gtu:SI (match_dup 1)
4633		(match_dup 2)))]
4634  ""
4635  { if (mips_emit_scc (GTU, operands[0])) DONE; else FAIL; })
4636
4637(define_insn "*sgtu_<mode>"
4638  [(set (match_operand:GPR 0 "register_operand" "=d")
4639	(gtu:GPR (match_operand:GPR 1 "register_operand" "d")
4640		 (match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
4641  "!TARGET_MIPS16"
4642  "sltu\t%0,%z2,%1"
4643  [(set_attr "type" "slt")
4644   (set_attr "mode" "<MODE>")])
4645
4646(define_insn "*sgtu_<mode>_mips16"
4647  [(set (match_operand:GPR 0 "register_operand" "=t")
4648	(gtu:GPR (match_operand:GPR 1 "register_operand" "d")
4649		 (match_operand:GPR 2 "register_operand" "d")))]
4650  "TARGET_MIPS16"
4651  "sltu\t%2,%1"
4652  [(set_attr "type" "slt")
4653   (set_attr "mode" "<MODE>")])
4654
4655(define_expand "sgeu"
4656  [(set (match_operand:SI 0 "register_operand")
4657        (geu:SI (match_dup 1)
4658                (match_dup 2)))]
4659  ""
4660  { if (mips_emit_scc (GEU, operands[0])) DONE; else FAIL; })
4661
4662(define_insn "*sge_<mode>"
4663  [(set (match_operand:GPR 0 "register_operand" "=d")
4664	(geu:GPR (match_operand:GPR 1 "register_operand" "d")
4665	         (const_int 1)))]
4666  "!TARGET_MIPS16"
4667  "sltu\t%0,%.,%1"
4668  [(set_attr "type" "slt")
4669   (set_attr "mode" "<MODE>")])
4670
4671(define_expand "sltu"
4672  [(set (match_operand:SI 0 "register_operand")
4673	(ltu:SI (match_dup 1)
4674		(match_dup 2)))]
4675  ""
4676  { if (mips_emit_scc (LTU, operands[0])) DONE; else FAIL; })
4677
4678(define_insn "*sltu_<mode>"
4679  [(set (match_operand:GPR 0 "register_operand" "=d")
4680	(ltu:GPR (match_operand:GPR 1 "register_operand" "d")
4681		 (match_operand:GPR 2 "arith_operand" "dI")))]
4682  "!TARGET_MIPS16"
4683  "sltu\t%0,%1,%2"
4684  [(set_attr "type" "slt")
4685   (set_attr "mode" "<MODE>")])
4686
4687(define_insn "*sltu_<mode>_mips16"
4688  [(set (match_operand:GPR 0 "register_operand" "=t,t")
4689	(ltu:GPR (match_operand:GPR 1 "register_operand" "d,d")
4690		 (match_operand:GPR 2 "arith_operand" "d,I")))]
4691  "TARGET_MIPS16"
4692  "sltu\t%1,%2"
4693  [(set_attr "type" "slt")
4694   (set_attr "mode" "<MODE>")
4695   (set_attr_alternative "length"
4696		[(const_int 4)
4697		 (if_then_else (match_operand 2 "m16_uimm8_1")
4698			       (const_int 4)
4699			       (const_int 8))])])
4700
4701(define_expand "sleu"
4702  [(set (match_operand:SI 0 "register_operand")
4703	(leu:SI (match_dup 1)
4704		(match_dup 2)))]
4705  ""
4706  { if (mips_emit_scc (LEU, operands[0])) DONE; else FAIL; })
4707
4708(define_insn "*sleu_<mode>"
4709  [(set (match_operand:GPR 0 "register_operand" "=d")
4710	(leu:GPR (match_operand:GPR 1 "register_operand" "d")
4711	         (match_operand:GPR 2 "sleu_operand" "")))]
4712  "!TARGET_MIPS16"
4713{
4714  operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
4715  return "sltu\t%0,%1,%2";
4716}
4717  [(set_attr "type" "slt")
4718   (set_attr "mode" "<MODE>")])
4719
4720(define_insn "*sleu_<mode>_mips16"
4721  [(set (match_operand:GPR 0 "register_operand" "=t")
4722	(leu:GPR (match_operand:GPR 1 "register_operand" "d")
4723	         (match_operand:GPR 2 "sleu_operand" "")))]
4724  "TARGET_MIPS16"
4725{
4726  operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
4727  return "sltu\t%1,%2";
4728}
4729  [(set_attr "type" "slt")
4730   (set_attr "mode" "<MODE>")
4731   (set (attr "length") (if_then_else (match_operand 2 "m16_uimm8_m1_1")
4732				      (const_int 4)
4733				      (const_int 8)))])
4734
4735;;
4736;;  ....................
4737;;
4738;;	FLOATING POINT COMPARISONS
4739;;
4740;;  ....................
4741
4742(define_insn "s<code>_<mode>"
4743  [(set (match_operand:CC 0 "register_operand" "=z")
4744	(fcond:CC (match_operand:SCALARF 1 "register_operand" "f")
4745		  (match_operand:SCALARF 2 "register_operand" "f")))]
4746  ""
4747  "c.<fcond>.<fmt>\t%Z0%1,%2"
4748  [(set_attr "type" "fcmp")
4749   (set_attr "mode" "FPSW")])
4750
4751(define_insn "s<code>_<mode>"
4752  [(set (match_operand:CC 0 "register_operand" "=z")
4753	(swapped_fcond:CC (match_operand:SCALARF 1 "register_operand" "f")
4754		          (match_operand:SCALARF 2 "register_operand" "f")))]
4755  ""
4756  "c.<swapped_fcond>.<fmt>\t%Z0%2,%1"
4757  [(set_attr "type" "fcmp")
4758   (set_attr "mode" "FPSW")])
4759
4760;;
4761;;  ....................
4762;;
4763;;	UNCONDITIONAL BRANCHES
4764;;
4765;;  ....................
4766
4767;; Unconditional branches.
4768
4769(define_insn "jump"
4770  [(set (pc)
4771	(label_ref (match_operand 0 "" "")))]
4772  "!TARGET_MIPS16"
4773{
4774  if (flag_pic)
4775    {
4776      if (get_attr_length (insn) <= 8)
4777	return "%*b\t%l0%/";
4778      else
4779	{
4780	  output_asm_insn (mips_output_load_label (), operands);
4781	  return "%*jr\t%@%/%]";
4782	}
4783    }
4784  else
4785    return "%*j\t%l0%/";
4786}
4787  [(set_attr "type"	"jump")
4788   (set_attr "mode"	"none")
4789   (set (attr "length")
4790	;; We can't use `j' when emitting PIC.  Emit a branch if it's
4791	;; in range, otherwise load the address of the branch target into
4792	;; $at and then jump to it.
4793	(if_then_else
4794	 (ior (eq (symbol_ref "flag_pic") (const_int 0))
4795	      (lt (abs (minus (match_dup 0)
4796			      (plus (pc) (const_int 4))))
4797		  (const_int 131072)))
4798	 (const_int 4) (const_int 16)))])
4799
4800;; We need a different insn for the mips16, because a mips16 branch
4801;; does not have a delay slot.
4802
4803(define_insn ""
4804  [(set (pc)
4805	(label_ref (match_operand 0 "" "")))]
4806  "TARGET_MIPS16"
4807  "b\t%l0"
4808  [(set_attr "type"	"branch")
4809   (set_attr "mode"	"none")
4810   (set_attr "length"	"8")])
4811
4812(define_expand "indirect_jump"
4813  [(set (pc) (match_operand 0 "register_operand"))]
4814  ""
4815{
4816  operands[0] = force_reg (Pmode, operands[0]);
4817  if (Pmode == SImode)
4818    emit_jump_insn (gen_indirect_jumpsi (operands[0]));
4819  else
4820    emit_jump_insn (gen_indirect_jumpdi (operands[0]));
4821  DONE;
4822})
4823
4824(define_insn "indirect_jump<mode>"
4825  [(set (pc) (match_operand:P 0 "register_operand" "d"))]
4826  ""
4827  "%*j\t%0%/"
4828  [(set_attr "type" "jump")
4829   (set_attr "mode" "none")])
4830
4831(define_expand "tablejump"
4832  [(set (pc)
4833	(match_operand 0 "register_operand"))
4834   (use (label_ref (match_operand 1 "")))]
4835  ""
4836{
4837  if (TARGET_MIPS16)
4838    operands[0] = expand_binop (Pmode, add_optab,
4839				convert_to_mode (Pmode, operands[0], false),
4840				gen_rtx_LABEL_REF (Pmode, operands[1]),
4841				0, 0, OPTAB_WIDEN);
4842  else if (TARGET_GPWORD)
4843    operands[0] = expand_binop (Pmode, add_optab, operands[0],
4844				pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
4845
4846  if (Pmode == SImode)
4847    emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
4848  else
4849    emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
4850  DONE;
4851})
4852
4853(define_insn "tablejump<mode>"
4854  [(set (pc)
4855	(match_operand:P 0 "register_operand" "d"))
4856   (use (label_ref (match_operand 1 "" "")))]
4857  ""
4858  "%*j\t%0%/"
4859  [(set_attr "type" "jump")
4860   (set_attr "mode" "none")])
4861
4862;; For TARGET_ABICALLS, we save the gp in the jmp_buf as well.
4863;; While it is possible to either pull it off the stack (in the
4864;; o32 case) or recalculate it given t9 and our target label,
4865;; it takes 3 or 4 insns to do so.
4866
4867(define_expand "builtin_setjmp_setup"
4868  [(use (match_operand 0 "register_operand"))]
4869  "TARGET_ABICALLS"
4870{
4871  rtx addr;
4872
4873  addr = plus_constant (operands[0], GET_MODE_SIZE (Pmode) * 3);
4874  emit_move_insn (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
4875  DONE;
4876})
4877
4878;; Restore the gp that we saved above.  Despite the earlier comment, it seems
4879;; that older code did recalculate the gp from $25.  Continue to jump through
4880;; $25 for compatibility (we lose nothing by doing so).
4881
4882(define_expand "builtin_longjmp"
4883  [(use (match_operand 0 "register_operand"))]
4884  "TARGET_ABICALLS"
4885{
4886  /* The elements of the buffer are, in order:  */
4887  int W = GET_MODE_SIZE (Pmode);
4888  rtx fp = gen_rtx_MEM (Pmode, operands[0]);
4889  rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
4890  rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
4891  rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
4892  rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
4893  /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
4894     The target is bound to be using $28 as the global pointer
4895     but the current function might not be.  */
4896  rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
4897
4898  /* This bit is similar to expand_builtin_longjmp except that it
4899     restores $gp as well.  */
4900  emit_move_insn (hard_frame_pointer_rtx, fp);
4901  emit_move_insn (pv, lab);
4902  emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
4903  emit_move_insn (gp, gpv);
4904  emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
4905  emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4906  emit_insn (gen_rtx_USE (VOIDmode, gp));
4907  emit_indirect_jump (pv);
4908  DONE;
4909})
4910
4911;;
4912;;  ....................
4913;;
4914;;	Function prologue/epilogue
4915;;
4916;;  ....................
4917;;
4918
4919(define_expand "prologue"
4920  [(const_int 1)]
4921  ""
4922{
4923  mips_expand_prologue ();
4924  DONE;
4925})
4926
4927;; Block any insns from being moved before this point, since the
4928;; profiling call to mcount can use various registers that aren't
4929;; saved or used to pass arguments.
4930
4931(define_insn "blockage"
4932  [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
4933  ""
4934  ""
4935  [(set_attr "type"	"unknown")
4936   (set_attr "mode"	"none")
4937   (set_attr "length"	"0")])
4938
4939(define_expand "epilogue"
4940  [(const_int 2)]
4941  ""
4942{
4943  mips_expand_epilogue (false);
4944  DONE;
4945})
4946
4947(define_expand "sibcall_epilogue"
4948  [(const_int 2)]
4949  ""
4950{
4951  mips_expand_epilogue (true);
4952  DONE;
4953})
4954
4955;; Trivial return.  Make it look like a normal return insn as that
4956;; allows jump optimizations to work better.
4957
4958(define_insn "return"
4959  [(return)]
4960  "mips_can_use_return_insn ()"
4961  "%*j\t$31%/"
4962  [(set_attr "type"	"jump")
4963   (set_attr "mode"	"none")])
4964
4965;; Normal return.
4966
4967(define_insn "return_internal"
4968  [(return)
4969   (use (match_operand 0 "pmode_register_operand" ""))]
4970  ""
4971  "%*j\t%0%/"
4972  [(set_attr "type"	"jump")
4973   (set_attr "mode"	"none")])
4974
4975;; This is used in compiling the unwind routines.
4976(define_expand "eh_return"
4977  [(use (match_operand 0 "general_operand"))]
4978  ""
4979{
4980  enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
4981
4982  if (GET_MODE (operands[0]) != gpr_mode)
4983    operands[0] = convert_to_mode (gpr_mode, operands[0], 0);
4984  if (TARGET_64BIT)
4985    emit_insn (gen_eh_set_lr_di (operands[0]));
4986  else
4987    emit_insn (gen_eh_set_lr_si (operands[0]));
4988
4989  DONE;
4990})
4991
4992;; Clobber the return address on the stack.  We can't expand this
4993;; until we know where it will be put in the stack frame.
4994
4995(define_insn "eh_set_lr_si"
4996  [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
4997   (clobber (match_scratch:SI 1 "=&d"))]
4998  "! TARGET_64BIT"
4999  "#")
5000
5001(define_insn "eh_set_lr_di"
5002  [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
5003   (clobber (match_scratch:DI 1 "=&d"))]
5004  "TARGET_64BIT"
5005  "#")
5006
5007(define_split
5008  [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
5009   (clobber (match_scratch 1))]
5010  "reload_completed && !TARGET_DEBUG_D_MODE"
5011  [(const_int 0)]
5012{
5013  mips_set_return_address (operands[0], operands[1]);
5014  DONE;
5015})
5016
5017(define_insn_and_split "exception_receiver"
5018  [(set (reg:SI 28)
5019	(unspec_volatile:SI [(const_int 0)] UNSPEC_EH_RECEIVER))]
5020  "TARGET_ABICALLS && TARGET_OLDABI"
5021  "#"
5022  "&& reload_completed"
5023  [(const_int 0)]
5024{
5025  mips_restore_gp ();
5026  DONE;
5027}
5028  [(set_attr "type"   "load")
5029   (set_attr "length" "12")])
5030
5031;;
5032;;  ....................
5033;;
5034;;	FUNCTION CALLS
5035;;
5036;;  ....................
5037
5038;; Instructions to load a call address from the GOT.  The address might
5039;; point to a function or to a lazy binding stub.  In the latter case,
5040;; the stub will use the dynamic linker to resolve the function, which
5041;; in turn will change the GOT entry to point to the function's real
5042;; address.
5043;;
5044;; This means that every call, even pure and constant ones, can
5045;; potentially modify the GOT entry.  And once a stub has been called,
5046;; we must not call it again.
5047;;
5048;; We represent this restriction using an imaginary fixed register that
5049;; acts like a GOT version number.  By making the register call-clobbered,
5050;; we tell the target-independent code that the address could be changed
5051;; by any call insn.
5052(define_insn "load_call<mode>"
5053  [(set (match_operand:P 0 "register_operand" "=c")
5054	(unspec:P [(match_operand:P 1 "register_operand" "r")
5055		   (match_operand:P 2 "immediate_operand" "")
5056		   (reg:P FAKE_CALL_REGNO)]
5057		  UNSPEC_LOAD_CALL))]
5058  "TARGET_ABICALLS"
5059  "<load>\t%0,%R2(%1)"
5060  [(set_attr "type" "load")
5061   (set_attr "mode" "<MODE>")
5062   (set_attr "length" "4")])
5063
5064;; Sibling calls.  All these patterns use jump instructions.
5065
5066;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
5067;; addresses if a direct jump is acceptable.  Since the 'S' constraint
5068;; is defined in terms of call_insn_operand, the same is true of the
5069;; constraints.
5070
5071;; When we use an indirect jump, we need a register that will be
5072;; preserved by the epilogue.  Since TARGET_ABICALLS forces us to
5073;; use $25 for this purpose -- and $25 is never clobbered by the
5074;; epilogue -- we might as well use it for !TARGET_ABICALLS as well.
5075
5076(define_expand "sibcall"
5077  [(parallel [(call (match_operand 0 "")
5078		    (match_operand 1 ""))
5079	      (use (match_operand 2 ""))	;; next_arg_reg
5080	      (use (match_operand 3 ""))])]	;; struct_value_size_rtx
5081  "TARGET_SIBCALLS"
5082{
5083  mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true);
5084  DONE;
5085})
5086
5087(define_insn "sibcall_internal"
5088  [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
5089	 (match_operand 1 "" ""))]
5090  "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5091  { return MIPS_CALL ("j", operands, 0); }
5092  [(set_attr "type" "call")])
5093
5094(define_expand "sibcall_value"
5095  [(parallel [(set (match_operand 0 "")
5096		   (call (match_operand 1 "")
5097			 (match_operand 2 "")))
5098	      (use (match_operand 3 ""))])]		;; next_arg_reg
5099  "TARGET_SIBCALLS"
5100{
5101  mips_expand_call (operands[0], XEXP (operands[1], 0),
5102		    operands[2], operands[3], true);
5103  DONE;
5104})
5105
5106(define_insn "sibcall_value_internal"
5107  [(set (match_operand 0 "register_operand" "=df,df")
5108        (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
5109              (match_operand 2 "" "")))]
5110  "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5111  { return MIPS_CALL ("j", operands, 1); }
5112  [(set_attr "type" "call")])
5113
5114(define_insn "sibcall_value_multiple_internal"
5115  [(set (match_operand 0 "register_operand" "=df,df")
5116        (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
5117              (match_operand 2 "" "")))
5118   (set (match_operand 3 "register_operand" "=df,df")
5119	(call (mem:SI (match_dup 1))
5120	      (match_dup 2)))]
5121  "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5122  { return MIPS_CALL ("j", operands, 1); }
5123  [(set_attr "type" "call")])
5124
5125(define_expand "call"
5126  [(parallel [(call (match_operand 0 "")
5127		    (match_operand 1 ""))
5128	      (use (match_operand 2 ""))	;; next_arg_reg
5129	      (use (match_operand 3 ""))])]	;; struct_value_size_rtx
5130  ""
5131{
5132  mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false);
5133  DONE;
5134})
5135
5136;; This instruction directly corresponds to an assembly-language "jal".
5137;; There are four cases:
5138;;
5139;;    - -mno-abicalls:
5140;;	  Both symbolic and register destinations are OK.  The pattern
5141;;	  always expands to a single mips instruction.
5142;;
5143;;    - -mabicalls/-mno-explicit-relocs:
5144;;	  Again, both symbolic and register destinations are OK.
5145;;	  The call is treated as a multi-instruction black box.
5146;;
5147;;    - -mabicalls/-mexplicit-relocs with n32 or n64:
5148;;	  Only "jal $25" is allowed.  This expands to a single "jalr $25"
5149;;	  instruction.
5150;;
5151;;    - -mabicalls/-mexplicit-relocs with o32 or o64:
5152;;	  Only "jal $25" is allowed.  The call is actually two instructions:
5153;;	  "jalr $25" followed by an insn to reload $gp.
5154;;
5155;; In the last case, we can generate the individual instructions with
5156;; a define_split.  There are several things to be wary of:
5157;;
5158;;   - We can't expose the load of $gp before reload.  If we did,
5159;;     it might get removed as dead, but reload can introduce new
5160;;     uses of $gp by rematerializing constants.
5161;;
5162;;   - We shouldn't restore $gp after calls that never return.
5163;;     It isn't valid to insert instructions between a noreturn
5164;;     call and the following barrier.
5165;;
5166;;   - The splitter deliberately changes the liveness of $gp.  The unsplit
5167;;     instruction preserves $gp and so have no effect on its liveness.
5168;;     But once we generate the separate insns, it becomes obvious that
5169;;     $gp is not live on entry to the call.
5170;;
5171;; ??? The operands[2] = insn check is a hack to make the original insn
5172;; available to the splitter.
5173(define_insn_and_split "call_internal"
5174  [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
5175	 (match_operand 1 "" ""))
5176   (clobber (reg:SI 31))]
5177  ""
5178  { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 0); }
5179  "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)"
5180  [(const_int 0)]
5181{
5182  emit_call_insn (gen_call_split (operands[0], operands[1]));
5183  if (!find_reg_note (operands[2], REG_NORETURN, 0))
5184    mips_restore_gp ();
5185  DONE;
5186}
5187  [(set_attr "jal" "indirect,direct")
5188   (set_attr "extended_mips16" "no,yes")])
5189
5190(define_insn "call_split"
5191  [(call (mem:SI (match_operand 0 "call_insn_operand" "cS"))
5192	 (match_operand 1 "" ""))
5193   (clobber (reg:SI 31))
5194   (clobber (reg:SI 28))]
5195  "TARGET_SPLIT_CALLS"
5196  { return MIPS_CALL ("jal", operands, 0); }
5197  [(set_attr "type" "call")])
5198
5199(define_expand "call_value"
5200  [(parallel [(set (match_operand 0 "")
5201		   (call (match_operand 1 "")
5202			 (match_operand 2 "")))
5203	      (use (match_operand 3 ""))])]		;; next_arg_reg
5204  ""
5205{
5206  mips_expand_call (operands[0], XEXP (operands[1], 0),
5207		    operands[2], operands[3], false);
5208  DONE;
5209})
5210
5211;; See comment for call_internal.
5212(define_insn_and_split "call_value_internal"
5213  [(set (match_operand 0 "register_operand" "=df,df")
5214        (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
5215              (match_operand 2 "" "")))
5216   (clobber (reg:SI 31))]
5217  ""
5218  { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1); }
5219  "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)"
5220  [(const_int 0)]
5221{
5222  emit_call_insn (gen_call_value_split (operands[0], operands[1],
5223					operands[2]));
5224  if (!find_reg_note (operands[3], REG_NORETURN, 0))
5225    mips_restore_gp ();
5226  DONE;
5227}
5228  [(set_attr "jal" "indirect,direct")
5229   (set_attr "extended_mips16" "no,yes")])
5230
5231(define_insn "call_value_split"
5232  [(set (match_operand 0 "register_operand" "=df")
5233        (call (mem:SI (match_operand 1 "call_insn_operand" "cS"))
5234              (match_operand 2 "" "")))
5235   (clobber (reg:SI 31))
5236   (clobber (reg:SI 28))]
5237  "TARGET_SPLIT_CALLS"
5238  { return MIPS_CALL ("jal", operands, 1); }
5239  [(set_attr "type" "call")])
5240
5241;; See comment for call_internal.
5242(define_insn_and_split "call_value_multiple_internal"
5243  [(set (match_operand 0 "register_operand" "=df,df")
5244        (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
5245              (match_operand 2 "" "")))
5246   (set (match_operand 3 "register_operand" "=df,df")
5247	(call (mem:SI (match_dup 1))
5248	      (match_dup 2)))
5249   (clobber (reg:SI 31))]
5250  ""
5251  { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1); }
5252  "reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)"
5253  [(const_int 0)]
5254{
5255  emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1],
5256						 operands[2], operands[3]));
5257  if (!find_reg_note (operands[4], REG_NORETURN, 0))
5258    mips_restore_gp ();
5259  DONE;
5260}
5261  [(set_attr "jal" "indirect,direct")
5262   (set_attr "extended_mips16" "no,yes")])
5263
5264(define_insn "call_value_multiple_split"
5265  [(set (match_operand 0 "register_operand" "=df")
5266        (call (mem:SI (match_operand 1 "call_insn_operand" "cS"))
5267              (match_operand 2 "" "")))
5268   (set (match_operand 3 "register_operand" "=df")
5269	(call (mem:SI (match_dup 1))
5270	      (match_dup 2)))
5271   (clobber (reg:SI 31))
5272   (clobber (reg:SI 28))]
5273  "TARGET_SPLIT_CALLS"
5274  { return MIPS_CALL ("jal", operands, 1); }
5275  [(set_attr "type" "call")])
5276
5277;; Call subroutine returning any type.
5278
5279(define_expand "untyped_call"
5280  [(parallel [(call (match_operand 0 "")
5281		    (const_int 0))
5282	      (match_operand 1 "")
5283	      (match_operand 2 "")])]
5284  ""
5285{
5286  int i;
5287
5288  emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
5289
5290  for (i = 0; i < XVECLEN (operands[2], 0); i++)
5291    {
5292      rtx set = XVECEXP (operands[2], 0, i);
5293      emit_move_insn (SET_DEST (set), SET_SRC (set));
5294    }
5295
5296  emit_insn (gen_blockage ());
5297  DONE;
5298})
5299
5300;;
5301;;  ....................
5302;;
5303;;	MISC.
5304;;
5305;;  ....................
5306;;
5307
5308
5309(define_insn "prefetch"
5310  [(prefetch (match_operand:QI 0 "address_operand" "p")
5311	     (match_operand 1 "const_int_operand" "n")
5312	     (match_operand 2 "const_int_operand" "n"))]
5313  "ISA_HAS_PREFETCH && TARGET_EXPLICIT_RELOCS"
5314{
5315  operands[1] = mips_prefetch_cookie (operands[1], operands[2]);
5316  return "pref\t%1,%a0";
5317}
5318  [(set_attr "type" "prefetch")])
5319
5320(define_insn "*prefetch_indexed_<mode>"
5321  [(prefetch (plus:P (match_operand:P 0 "register_operand" "d")
5322		     (match_operand:P 1 "register_operand" "d"))
5323	     (match_operand 2 "const_int_operand" "n")
5324	     (match_operand 3 "const_int_operand" "n"))]
5325  "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5326{
5327  operands[2] = mips_prefetch_cookie (operands[2], operands[3]);
5328  return "prefx\t%2,%1(%0)";
5329}
5330  [(set_attr "type" "prefetchx")])
5331
5332(define_insn "nop"
5333  [(const_int 0)]
5334  ""
5335  "%(nop%)"
5336  [(set_attr "type"	"nop")
5337   (set_attr "mode"	"none")])
5338
5339;; Like nop, but commented out when outside a .set noreorder block.
5340(define_insn "hazard_nop"
5341  [(const_int 1)]
5342  ""
5343  {
5344    if (set_noreorder)
5345      return "nop";
5346    else
5347      return "#nop";
5348  }
5349  [(set_attr "type"	"nop")])
5350
5351;; MIPS4 Conditional move instructions.
5352
5353(define_insn "*mov<GPR:mode>_on_<MOVECC:mode>"
5354  [(set (match_operand:GPR 0 "register_operand" "=d,d")
5355	(if_then_else:GPR
5356	 (match_operator:MOVECC 4 "equality_operator"
5357		[(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>")
5358		 (const_int 0)])
5359	 (match_operand:GPR 2 "reg_or_0_operand" "dJ,0")
5360	 (match_operand:GPR 3 "reg_or_0_operand" "0,dJ")))]
5361  "ISA_HAS_CONDMOVE"
5362  "@
5363    mov%T4\t%0,%z2,%1
5364    mov%t4\t%0,%z3,%1"
5365  [(set_attr "type" "condmove")
5366   (set_attr "mode" "<GPR:MODE>")])
5367
5368(define_insn "*mov<SCALARF:mode>_on_<MOVECC:mode>"
5369  [(set (match_operand:SCALARF 0 "register_operand" "=f,f")
5370	(if_then_else:SCALARF
5371	 (match_operator:MOVECC 4 "equality_operator"
5372		[(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>")
5373		 (const_int 0)])
5374	 (match_operand:SCALARF 2 "register_operand" "f,0")
5375	 (match_operand:SCALARF 3 "register_operand" "0,f")))]
5376  "ISA_HAS_CONDMOVE"
5377  "@
5378    mov%T4.<fmt>\t%0,%2,%1
5379    mov%t4.<fmt>\t%0,%3,%1"
5380  [(set_attr "type" "condmove")
5381   (set_attr "mode" "<SCALARF:MODE>")])
5382
5383;; These are the main define_expand's used to make conditional moves.
5384
5385(define_expand "mov<mode>cc"
5386  [(set (match_dup 4) (match_operand 1 "comparison_operator"))
5387   (set (match_operand:GPR 0 "register_operand")
5388	(if_then_else:GPR (match_dup 5)
5389			  (match_operand:GPR 2 "reg_or_0_operand")
5390			  (match_operand:GPR 3 "reg_or_0_operand")))]
5391  "ISA_HAS_CONDMOVE"
5392{
5393  gen_conditional_move (operands);
5394  DONE;
5395})
5396
5397(define_expand "mov<mode>cc"
5398  [(set (match_dup 4) (match_operand 1 "comparison_operator"))
5399   (set (match_operand:SCALARF 0 "register_operand")
5400	(if_then_else:SCALARF (match_dup 5)
5401			      (match_operand:SCALARF 2 "register_operand")
5402			      (match_operand:SCALARF 3 "register_operand")))]
5403  "ISA_HAS_CONDMOVE"
5404{
5405  gen_conditional_move (operands);
5406  DONE;
5407})
5408
5409;;
5410;;  ....................
5411;;
5412;;	mips16 inline constant tables
5413;;
5414;;  ....................
5415;;
5416
5417(define_insn "consttable_int"
5418  [(unspec_volatile [(match_operand 0 "consttable_operand" "")
5419		     (match_operand 1 "const_int_operand" "")]
5420		    UNSPEC_CONSTTABLE_INT)]
5421  "TARGET_MIPS16"
5422{
5423  assemble_integer (operands[0], INTVAL (operands[1]),
5424		    BITS_PER_UNIT * INTVAL (operands[1]), 1);
5425  return "";
5426}
5427  [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
5428
5429(define_insn "consttable_float"
5430  [(unspec_volatile [(match_operand 0 "consttable_operand" "")]
5431		    UNSPEC_CONSTTABLE_FLOAT)]
5432  "TARGET_MIPS16"
5433{
5434  REAL_VALUE_TYPE d;
5435
5436  gcc_assert (GET_CODE (operands[0]) == CONST_DOUBLE);
5437  REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
5438  assemble_real (d, GET_MODE (operands[0]),
5439		 GET_MODE_BITSIZE (GET_MODE (operands[0])));
5440  return "";
5441}
5442  [(set (attr "length")
5443	(symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))])
5444
5445(define_insn "align"
5446  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)]
5447  ""
5448  ".align\t%0"
5449  [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))])
5450
5451(define_split
5452  [(match_operand 0 "small_data_pattern")]
5453  "reload_completed"
5454  [(match_dup 0)]
5455  { operands[0] = mips_rewrite_small_data (operands[0]); })
5456
5457; Thread-Local Storage
5458
5459; The TLS base pointer is accessed via "rdhwr $v1, $29".  No current
5460; MIPS architecture defines this register, and no current
5461; implementation provides it; instead, any OS which supports TLS is
5462; expected to trap and emulate this instruction.  rdhwr is part of the
5463; MIPS 32r2 specification, but we use it on any architecture because
5464; we expect it to be emulated.  Use .set to force the assembler to
5465; accept it.
5466
5467(define_insn "tls_get_tp_<mode>"
5468  [(set (match_operand:P 0 "register_operand" "=v")
5469	(unspec:P [(const_int 0)]
5470		  UNSPEC_TLS_GET_TP))]
5471  "HAVE_AS_TLS && !TARGET_MIPS16"
5472  ".set\tpush\;.set\tmips32r2\t\;rdhwr\t%0,$29\;.set\tpop"
5473  [(set_attr "type" "unknown")
5474   ; Since rdhwr always generates a trap for now, putting it in a delay
5475   ; slot would make the kernel's emulation of it much slower.
5476   (set_attr "can_delay" "no")
5477   (set_attr "mode" "<MODE>")])
5478
5479; The MIPS Paired-Single Floating Point and MIPS-3D Instructions.
5480
5481(include "mips-ps-3d.md")
5482
5483; The MIPS DSP Instructions.
5484
5485(include "mips-dsp.md")
5486