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