1;; Frv Machine Description
2;; Copyright (C) 1999-2019 Free Software Foundation, Inc.
3;; Contributed by Red Hat, Inc.
4
5;; This file is part of GCC.
6
7;; GCC is free software; you can redistribute it and/or modify
8;; it under the terms of the GNU General Public License as published by
9;; the Free Software Foundation; either version 3, or (at your option)
10;; any later version.
11
12;; GCC is distributed in the hope that it will be useful,
13;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15;; GNU General Public License for more details.
16
17;; You should have received a copy of the GNU General Public License
18;; along with GCC; see the file COPYING3.  If not see
19;; <http://www.gnu.org/licenses/>.
20
21;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
22
23
24;; ::::::::::::::::::::
25;; ::
26;; :: Unspec's used
27;; ::
28;; ::::::::::::::::::::
29
30;; GOT constants must go 12/HI/LO for the splitter to work
31
32(define_constants
33  [(UNSPEC_BLOCKAGE		0)
34   (UNSPEC_CC_TO_GPR		1)
35   (UNSPEC_GPR_TO_CC		2)
36   (UNSPEC_PIC_PROLOGUE		3)
37   (UNSPEC_CR_LOGIC		4)
38   (UNSPEC_STACK_ADJUST		5)
39   (UNSPEC_EH_RETURN_EPILOGUE	6)
40   (UNSPEC_GOT			7)
41   (UNSPEC_LDD			8)
42   (UNSPEC_OPTIONAL_MEMBAR	9)
43
44   (UNSPEC_GETTLSOFF			200)
45   (UNSPEC_TLS_LOAD_GOTTLSOFF12		201)
46   (UNSPEC_TLS_INDIRECT_CALL		202)
47   (UNSPEC_TLS_TLSDESC_LDD		203)
48   (UNSPEC_TLS_TLSDESC_LDD_AUX		204)
49   (UNSPEC_TLS_TLSOFF_LD		205)
50   (UNSPEC_TLS_LDDI			206)
51   (UNSPEC_TLSOFF_HILO			207)
52
53   (R_FRV_GOT12			11)
54   (R_FRV_GOTHI			12)
55   (R_FRV_GOTLO			13)
56   (R_FRV_FUNCDESC		14)
57   (R_FRV_FUNCDESC_GOT12	15)
58   (R_FRV_FUNCDESC_GOTHI	16)
59   (R_FRV_FUNCDESC_GOTLO	17)
60   (R_FRV_FUNCDESC_VALUE	18)
61   (R_FRV_FUNCDESC_GOTOFF12	19)
62   (R_FRV_FUNCDESC_GOTOFFHI	20)
63   (R_FRV_FUNCDESC_GOTOFFLO	21)
64   (R_FRV_GOTOFF12		22)
65   (R_FRV_GOTOFFHI		23)
66   (R_FRV_GOTOFFLO		24)
67   (R_FRV_GPREL12		25)
68   (R_FRV_GPRELHI		26)
69   (R_FRV_GPRELLO		27)
70   (R_FRV_GOTTLSOFF_HI		28)
71   (R_FRV_GOTTLSOFF_LO		29)
72   (R_FRV_TLSMOFFHI		30)
73   (R_FRV_TLSMOFFLO           	31)
74   (R_FRV_TLSMOFF12           	32)
75   (R_FRV_TLSDESCHI           	33)
76   (R_FRV_TLSDESCLO           	34)
77   (R_FRV_GOTTLSDESCHI		35)
78   (R_FRV_GOTTLSDESCLO		36)
79
80   (GR8_REG			8)
81   (GR9_REG			9)
82   (GR14_REG			14)
83   ;; LR_REG conflicts with definition in frv.h
84   (LRREG                       169)
85   (FDPIC_REG			15)
86   ])
87
88(define_mode_iterator IMODE [QI HI SI DI])
89(define_mode_attr IMODEsuffix [(QI "b") (HI "h") (SI "") (DI "d")])
90(define_mode_attr BREADsuffix [(QI "ub") (HI "uh") (SI "") (DI "d")])
91
92(define_attr "length" "" (const_int 4))
93
94;; Processor type -- this attribute must exactly match the processor_type
95;; enumeration in frv-protos.h.
96
97(define_attr "cpu" "generic,fr550,fr500,fr450,fr405,fr400,fr300,simple,tomcat"
98  (const (symbol_ref "(enum attr_cpu) frv_cpu_type")))
99
100;; Attribute is "yes" for branches and jumps that span too great a distance
101;; to be implemented in the most natural way.  Such instructions will use
102;; a call instruction in some way.
103
104(define_attr "far_jump" "yes,no" (const_string "no"))
105
106;; Instruction type
107;; "unknown" must come last.
108(define_attr "type"
109  "int,sethi,setlo,mul,div,gload,gstore,fload,fstore,movfg,movgf,macc,scan,cut,branch,jump,jumpl,call,spr,trap,fnop,fsconv,fsadd,fscmp,fsmul,fsmadd,fsdiv,sqrt_single,fdconv,fdadd,fdcmp,fdmul,fdmadd,fddiv,sqrt_double,mnop,mlogic,maveh,msath,maddh,mqaddh,mpackh,munpackh,mdpackh,mbhconv,mrot,mshift,mexpdhw,mexpdhd,mwcut,mmulh,mmulxh,mmach,mmrdh,mqmulh,mqmulxh,mqmach,mcpx,mqcpx,mcut,mclracc,mclracca,mdunpackh,mbhconve,mrdacc,mwtacc,maddacc,mdaddacc,mabsh,mdrot,mcpl,mdcut,mqsath,mqlimh,mqshift,mset,ccr,multi,load_or_call,unknown"
110  (const_string "unknown"))
111
112(define_attr "acc_group" "none,even,odd"
113  (symbol_ref "(enum attr_acc_group) frv_acc_group (insn)"))
114
115;; Scheduling and Packing Overview
116;; -------------------------------
117;;
118;; FR-V instructions are divided into five groups: integer, floating-point,
119;; media, branch and control.  Each group is associated with a separate set
120;; of processing units, the number and behavior of which depend on the target
121;; target processor.  Integer units have names like I0 and I1, floating-point
122;; units have names like F0 and F1, and so on.
123;;
124;; Each member of the FR-V family has its own restrictions on which
125;; instructions can issue to which units.  For example, some processors
126;; allow loads to issue to I0 or I1 while others only allow them to issue
127;; to I0.  As well as these processor-specific restrictions, there is a
128;; general rule that an instruction can only issue to unit X + 1 if an
129;; instruction in the same packet issued to unit X.
130;;
131;; Sometimes the only way to honor these restrictions is by adding nops
132;; to a packet.  For example, on the fr550, media instructions that access
133;; ACC4-7 can only issue to M1 or M3.  It is therefore only possible to
134;; execute these instructions by packing them with something that issues
135;; to M0.  When no useful M0 instruction exists, an "mnop" can be used
136;; instead.
137;;
138;; Having decided which instructions should issue to which units, the packet
139;; should be ordered according to the following template:
140;;
141;;     I0 F0/M0 I1 F1/M1 .... B0 B1 ...
142;;
143;; Note that VLIW packets execute strictly in parallel.  Every instruction
144;; in the packet will stall until all input operands are ready.  These
145;; operands are then read simultaneously before any registers are modified.
146;; This means that it's OK to have write-after-read hazards between
147;; instructions in the same packet, even if the write is listed earlier
148;; than the read.
149;;
150;; Three gcc passes are involved in generating VLIW packets:
151;;
152;;    (1) The scheduler.  This pass uses the standard scheduling code and
153;;	  behaves in much the same way as it would for a superscalar RISC
154;;	  architecture.
155;;
156;;    (2) frv_reorg.  This pass inserts nops into packets in order to meet
157;;	  the processor's issue requirements.  It also has code to optimize
158;;	  the type of padding used to align labels.
159;;
160;;    (3) frv_pack_insns.  The final packing phase, which puts the
161;;	  instructions into assembly language order according to the
162;;	  "I0 F0/M0 ..." template above.
163;;
164;; In the ideal case, these three passes will agree on which instructions
165;; should be packed together, but this won't always happen.  In particular:
166;;
167;;    (a) (2) might not pack predicated instructions in the same way as (1).
168;;	  The scheduler tries to schedule predicated instructions for the
169;;	  worst case, assuming the predicate is true.  However, if we have
170;;	  something like a predicated load, it isn't always possible to
171;;	  fill the load delay with useful instructions.  (2) should then
172;;	  pack the user of the loaded value as aggressively as possible,
173;;	  in order to optimize the case when the predicate is false.
174;;	  See frv_pack_insn_p for more details.
175;;
176;;    (b) The final shorten_branches pass runs between (2) and (3).
177;;	  Since (2) inserts nops, it is possible that some branches
178;;	  that were thought to be in range during (2) turned out to
179;;	  out-of-range in (3).
180;;
181;; All three passes use DFAs to model issue restrictions.  The main
182;; question that the DFAs are supposed to answer is simply: can these
183;; instructions be packed together?  The DFAs are not responsible for
184;; assigning instructions to execution units; that's the job of
185;; frv_sort_insn_group, see below for details.
186;;
187;; To get the best results, the DFAs should try to allow packets to
188;; be built in every possible order.  This gives the scheduler more
189;; flexibility, removing the need for things like multipass lookahead.
190;; It also means we can take more advantage of inter-packet dependencies.
191;;
192;; For example, suppose we're compiling for the fr400 and we have:
193;;
194;;	addi	gr4,#1,gr5
195;;	ldi	@(gr6,gr0),gr4
196;;
197;; We can pack these instructions together by assigning the load to I0 and
198;; the addition to I1.  However, because of the anti dependence between the
199;; two instructions, the scheduler must schedule the addition first.
200;; We should generally get better schedules if the DFA allows both
201;; (ldi, addi) and (addi, ldi), leaving the final packing pass to
202;; reorder the packet where appropriate.
203;;
204;; Almost all integer instructions can issue to any unit in the range I0
205;; to Ix, where the value of "x" depends on the type of instruction and
206;; on the target processor.  The rules for other instruction groups are
207;; usually similar.
208;;
209;; When the restrictions are as regular as this, we can get the desired
210;; behavior by claiming the DFA unit associated with the highest unused
211;; execution unit.  For example, if an instruction can issue to I0 or I1,
212;; the DFA first tries to take the DFA unit associated with I1, and will
213;; only take I0's unit if I1 isn't free.  (Note that, as mentioned above,
214;; the DFA does not assign instructions to units.  An instruction that
215;; claims DFA unit I1 will not necessarily issue to I1 in the final packet.)
216;;
217;; There are some cases, such as the fr550 media restriction mentioned
218;; above, where the rule is not as simple as "any unit between 0 and X".
219;; Even so, allocating higher units first brings us close to the ideal.
220;;
221;; Having divided instructions into packets, passes (2) and (3) must
222;; assign instructions to specific execution units.  They do this using
223;; the following algorithm:
224;;
225;;    1. Partition the instructions into groups (integer, float/media, etc.)
226;;
227;;    2. For each group of instructions:
228;;
229;;	 (a) Issue each instruction in the reset DFA state and use the
230;;	     DFA cpu_unit_query interface to find out which unit it picks
231;;	     first.
232;;
233;;	 (b) Sort the instructions into ascending order of picked units.
234;;	     Instructions that pick I1 first come after those that pick
235;;	     I0 first, and so on.  Let S be the sorted sequence and S[i]
236;;	     be the ith element of it (counting from zero).
237;;
238;;	 (c) If this is the control or branch group, goto (i)
239;;
240;;	 (d) Find the largest L such that S[0]...S[L-1] can be issued
241;;	     consecutively from the reset state and such that the DFA
242;;	     claims unit X when S[X] is added.  Let D be the DFA state
243;;	     after instructions S[0]...S[L-1] have been issued.
244;;
245;;	 (e) If L is the length of S, goto (i)
246;;
247;;	 (f) Let U be the number of units belonging to this group and #S be
248;;	     the length of S.  Create a new sequence S' by concatenating
249;;	     S[L]...S[#S-1] and (U - #S) nops.
250;;
251;;	 (g) For each permutation S'' of S', try issuing S'' from last to
252;;	     first, starting with state D.  See if the DFA claims unit
253;;	     X + L when each S''[X] is added.  If so, set S to the
254;;	     concatenation of S[0]...S[L-1] and S'', then goto (i).
255;;
256;;	 (h) If (g) found no permutation, abort.
257;;
258;;	 (i) S is now the sorted sequence for this group, meaning that S[X]
259;;	     issues to unit X.  Trim any unwanted nops from the end of S.
260;;
261;; The sequence calculated by (b) is trivially correct for control
262;; instructions since they can't be packed.  It is also correct for branch
263;; instructions due to their simple issue requirements.  For integer and
264;; floating-point/media instructions, the sequence calculated by (b) is
265;; often the correct answer; the rest of the algorithm is optimized for
266;; the case in which it is correct.
267;;
268;; If there were no irregularities in the issue restrictions then step
269;; (d) would not be needed.  It is mainly there to cope with the fr550
270;; integer restrictions, where a store can issue to I1, but only if a store
271;; also issues to I0.  (Note that if a packet has two stores, they will be
272;; at the beginning of the sequence calculated by (b).)  It also copes
273;; with fr400 M-2 instructions, which must issue to M0, and which cannot
274;; be issued together with an mnop in M1.
275;;
276;; Step (g) is the main one for integer and float/media instructions.
277;; The first permutation it tries is S' itself (because, as noted above,
278;; the sequence calculated by (b) is often correct).  If S' doesn't work,
279;; the implementation tries varying the beginning of the sequence first.
280;; Thus the nops towards the end of the sequence will only move to lower
281;; positions if absolutely necessary.
282;;
283;; The algorithm is theoretically exponential in the number of instructions
284;; in a group, although it's only O(n log(n)) if the sequence calculated by
285;; (b) is acceptable.  In practice, the algorithm completes quickly even
286;; in the rare cases where (g) needs to try other permutations.
287(define_automaton "integer, float_media, branch, control, idiv, div")
288
289;; The main issue units.  Note that not all units are available on
290;; all processors.
291(define_query_cpu_unit "i0,i1,i2,i3" "integer")
292(define_query_cpu_unit "f0,f1,f2,f3" "float_media")
293(define_query_cpu_unit "b0,b1" "branch")
294(define_query_cpu_unit "c" "control")
295
296;; Division units.
297(define_cpu_unit "idiv1,idiv2" "idiv")
298(define_cpu_unit "div1,div2,root" "div")
299
300;; Control instructions cannot be packed with others.
301(define_reservation "control" "i0+i1+i2+i3+f0+f1+f2+f3+b0+b1")
302
303;; Generic reservation for control insns
304(define_insn_reservation "control" 1
305  (eq_attr "type" "trap,spr,unknown,multi")
306  "c + control")
307
308;; Reservation for relaxable calls to gettlsoff.
309(define_insn_reservation "load_or_call" 3
310  (eq_attr "type" "load_or_call")
311  "c + control")
312
313;; ::::::::::::::::::::
314;; ::
315;; :: Generic/FR500 scheduler description
316;; ::
317;; ::::::::::::::::::::
318
319;; Integer insns
320;; Synthetic units used to describe issue restrictions.
321(define_automaton "fr500_integer")
322(define_cpu_unit "fr500_load0,fr500_load1,fr500_store0" "fr500_integer")
323(exclusion_set "fr500_load0,fr500_load1" "fr500_store0")
324
325(define_bypass 0 "fr500_i1_sethi" "fr500_i1_setlo")
326(define_insn_reservation "fr500_i1_sethi" 1
327  (and (eq_attr "cpu" "generic,fr500,tomcat")
328       (eq_attr "type" "sethi"))
329  "i1|i0")
330
331(define_insn_reservation "fr500_i1_setlo" 1
332  (and (eq_attr "cpu" "generic,fr500,tomcat")
333       (eq_attr "type" "setlo"))
334  "i1|i0")
335
336(define_insn_reservation "fr500_i1_int" 1
337  (and (eq_attr "cpu" "generic,fr500,tomcat")
338       (eq_attr "type" "int"))
339  "i1|i0")
340
341(define_insn_reservation "fr500_i1_mul" 3
342  (and (eq_attr "cpu" "generic,fr500,tomcat")
343       (eq_attr "type" "mul"))
344  "i1|i0")
345
346(define_insn_reservation "fr500_i1_div" 19
347  (and (eq_attr "cpu" "generic,fr500,tomcat")
348       (eq_attr "type" "div"))
349  "(i1|i0),(idiv1*18|idiv2*18)")
350
351(define_insn_reservation "fr500_i2" 4
352  (and (eq_attr "cpu" "generic,fr500,tomcat")
353       (eq_attr "type" "gload,fload"))
354  "(i1|i0) + (fr500_load0|fr500_load1)")
355
356(define_insn_reservation "fr500_i3" 0
357  (and (eq_attr "cpu" "generic,fr500,tomcat")
358       (eq_attr "type" "gstore,fstore"))
359  "i0 + fr500_store0")
360
361(define_insn_reservation "fr500_i4" 3
362  (and (eq_attr "cpu" "generic,fr500,tomcat")
363       (eq_attr "type" "movgf,movfg"))
364  "i0")
365
366(define_insn_reservation "fr500_i5" 0
367  (and (eq_attr "cpu" "generic,fr500,tomcat")
368       (eq_attr "type" "jumpl"))
369  "i0")
370
371;;
372;; Branch-instructions
373;;
374(define_insn_reservation "fr500_branch" 0
375  (and (eq_attr "cpu" "generic,fr500,tomcat")
376       (eq_attr "type" "jump,branch,ccr"))
377  "b1|b0")
378
379(define_insn_reservation "fr500_call" 0
380  (and (eq_attr "cpu" "generic,fr500,tomcat")
381       (eq_attr "type" "call"))
382  "b0")
383
384;; Floating point insns.  The default latencies are for non-media
385;; instructions; media instructions incur an extra cycle.
386
387(define_bypass 4 "fr500_farith" "fr500_m1,fr500_m2,fr500_m3,
388			         fr500_m4,fr500_m5,fr500_m6")
389(define_insn_reservation "fr500_farith" 3
390  (and (eq_attr "cpu" "generic,fr500,tomcat")
391       (eq_attr "type" "fnop,fsconv,fsadd,fsmul,fsmadd,fdconv,fdadd,fdmul,fdmadd"))
392  "(f1|f0)")
393
394(define_insn_reservation "fr500_fcmp" 4
395  (and (eq_attr "cpu" "generic,fr500,tomcat")
396       (eq_attr "type" "fscmp,fdcmp"))
397  "(f1|f0)")
398
399(define_bypass 11 "fr500_fdiv" "fr500_m1,fr500_m2,fr500_m3,
400			        fr500_m4,fr500_m5,fr500_m6")
401(define_insn_reservation "fr500_fdiv" 10
402  (and (eq_attr "cpu" "generic,fr500,tomcat")
403       (eq_attr "type" "fsdiv,fddiv"))
404  "(f1|f0),(div1*9 | div2*9)")
405
406(define_bypass 16 "fr500_froot" "fr500_m1,fr500_m2,fr500_m3,
407				 fr500_m4,fr500_m5,fr500_m6")
408(define_insn_reservation "fr500_froot" 15
409  (and (eq_attr "cpu" "generic,fr500,tomcat")
410       (eq_attr "type" "sqrt_single,sqrt_double"))
411  "(f1|f0) + root*15")
412
413;; Media insns.  Conflict table is as follows:
414;;
415;;           M1  M2  M3  M4  M5  M6
416;;        M1  -   -   -   -   -   -
417;;        M2  -   -   -   -   X   X
418;;        M3  -   -   -   -   X   X
419;;        M4  -   -   -   -   -   X
420;;        M5  -   X   X   -   X   X
421;;        M6  -   X   X   X   X   X
422;;
423;; where X indicates an invalid combination.
424;;
425;; Target registers are as follows:
426;;
427;;	  M1 : FPRs
428;;	  M2 : FPRs
429;;	  M3 : ACCs
430;;	  M4 : ACCs
431;;	  M5 : FPRs
432;;	  M6 : ACCs
433;;
434;; The default FPR latencies are for integer instructions.
435;; Floating-point instructions need one cycle more and media
436;; instructions need one cycle less.
437(define_automaton "fr500_media")
438(define_cpu_unit "fr500_m2_0,fr500_m2_1" "fr500_media")
439(define_cpu_unit "fr500_m3_0,fr500_m3_1" "fr500_media")
440(define_cpu_unit "fr500_m4_0,fr500_m4_1" "fr500_media")
441(define_cpu_unit "fr500_m5" "fr500_media")
442(define_cpu_unit "fr500_m6" "fr500_media")
443
444(exclusion_set "fr500_m5,fr500_m6" "fr500_m2_0,fr500_m2_1,
445				    fr500_m3_0,fr500_m3_1")
446(exclusion_set "fr500_m6" "fr500_m4_0,fr500_m4_1,fr500_m5")
447
448(define_bypass 2 "fr500_m1" "fr500_m1,fr500_m2,fr500_m3,
449			     fr500_m4,fr500_m5,fr500_m6")
450(define_bypass 4 "fr500_m1" "fr500_farith,fr500_fcmp,fr500_fdiv,fr500_froot")
451(define_insn_reservation "fr500_m1" 3
452  (and (eq_attr "cpu" "generic,fr500,tomcat")
453       (eq_attr "type" "mnop,mlogic,maveh,msath,maddh,mqaddh"))
454  "(f1|f0)")
455
456(define_bypass 2 "fr500_m2" "fr500_m1,fr500_m2,fr500_m3,
457			     fr500_m4,fr500_m5,fr500_m6")
458(define_bypass 4 "fr500_m2" "fr500_farith,fr500_fcmp,fr500_fdiv,fr500_froot")
459(define_insn_reservation "fr500_m2" 3
460  (and (eq_attr "cpu" "generic,fr500,tomcat")
461       (eq_attr "type" "mrdacc,mpackh,munpackh,mbhconv,mrot,mshift,mexpdhw,mexpdhd,mwcut,mcut,mdunpackh,mbhconve"))
462  "(f1|f0) + (fr500_m2_0|fr500_m2_1)")
463
464(define_bypass 1 "fr500_m3" "fr500_m4")
465(define_insn_reservation "fr500_m3" 2
466  (and (eq_attr "cpu" "generic,fr500,tomcat")
467       (eq_attr "type" "mclracc,mwtacc"))
468  "(f1|f0) + (fr500_m3_0|fr500_m3_1)")
469
470(define_bypass 1 "fr500_m4" "fr500_m4")
471(define_insn_reservation "fr500_m4" 2
472  (and (eq_attr "cpu" "generic,fr500,tomcat")
473       (eq_attr "type" "mmulh,mmulxh,mmach,mmrdh,mqmulh,mqmulxh,mqmach,mcpx,mqcpx"))
474  "(f1|f0) + (fr500_m4_0|fr500_m4_1)")
475
476(define_bypass 2 "fr500_m5" "fr500_m1,fr500_m2,fr500_m3,
477			     fr500_m4,fr500_m5,fr500_m6")
478(define_bypass 4 "fr500_m5" "fr500_farith,fr500_fcmp,fr500_fdiv,fr500_froot")
479(define_insn_reservation "fr500_m5" 3
480  (and (eq_attr "cpu" "generic,fr500,tomcat")
481       (eq_attr "type" "mdpackh"))
482  "(f1|f0) + fr500_m5")
483
484(define_bypass 1 "fr500_m6" "fr500_m4")
485(define_insn_reservation "fr500_m6" 2
486  (and (eq_attr "cpu" "generic,fr500,tomcat")
487       (eq_attr "type" "mclracca"))
488  "(f1|f0) + fr500_m6")
489
490;; ::::::::::::::::::::
491;; ::
492;; :: FR400 scheduler description
493;; ::
494;; ::::::::::::::::::::
495
496;; Category 2 media instructions use both media units, but can be packed
497;; with non-media instructions.  Use fr400_m1unit to claim the M1 unit
498;; without claiming a slot.
499
500;; Name		Class	Units	Latency
501;; ====	        =====	=====	=======
502;; int		I1	I0/I1	1
503;; sethi	I1	I0/I1	0       -- does not interfere with setlo
504;; setlo	I1	I0/I1	1
505;; mul		I1	I0	3  (*)
506;; div		I1	I0	20 (*)
507;; gload	I2	I0	4  (*)
508;; fload	I2	I0	4       -- only 3 if read by a media insn
509;; gstore	I3	I0	0       -- provides no result
510;; fstore	I3	I0	0       -- provides no result
511;; movfg	I4	I0	3  (*)
512;; movgf	I4	I0	3  (*)
513;; jumpl	I5	I0	0       -- provides no result
514;;
515;; (*) The results of these instructions can be read one cycle earlier
516;; than indicated.  The penalty given is for instructions with write-after-
517;; write dependencies.
518
519;; The FR400 can only do loads and stores in I0, so we there's no danger
520;; of memory unit collision in the same packet.  There's only one divide
521;; unit too.
522
523(define_automaton "fr400_integer")
524(define_cpu_unit "fr400_mul" "fr400_integer")
525
526(define_insn_reservation "fr400_i1_int" 1
527  (and (eq_attr "cpu" "fr400,fr405,fr450")
528       (eq_attr "type" "int"))
529  "i1|i0")
530
531(define_bypass 0 "fr400_i1_sethi" "fr400_i1_setlo")
532(define_insn_reservation "fr400_i1_sethi" 1
533  (and (eq_attr "cpu" "fr400,fr405,fr450")
534       (eq_attr "type" "sethi"))
535  "i1|i0")
536
537(define_insn_reservation "fr400_i1_setlo" 1
538  (and (eq_attr "cpu" "fr400,fr405,fr450")
539       (eq_attr "type" "setlo"))
540  "i1|i0")
541
542;; 3 is the worst case (write-after-write hazard).
543(define_insn_reservation "fr400_i1_mul" 3
544  (and (eq_attr "cpu" "fr400,fr405")
545       (eq_attr "type" "mul"))
546  "i0 + fr400_mul")
547
548(define_insn_reservation "fr450_i1_mul" 2
549  (and (eq_attr "cpu" "fr450")
550       (eq_attr "type" "mul"))
551  "i0 + fr400_mul")
552
553(define_bypass 1 "fr400_i1_macc" "fr400_i1_macc")
554(define_insn_reservation "fr400_i1_macc" 2
555  (and (eq_attr "cpu" "fr405,fr450")
556       (eq_attr "type" "macc"))
557  "(i0|i1) + fr400_mul")
558
559(define_insn_reservation "fr400_i1_scan" 1
560  (and (eq_attr "cpu" "fr400,fr405,fr450")
561       (eq_attr "type" "scan"))
562  "i0")
563
564(define_insn_reservation "fr400_i1_cut" 2
565  (and (eq_attr "cpu" "fr405,fr450")
566       (eq_attr "type" "cut"))
567  "i0 + fr400_mul")
568
569;; 20 is for a write-after-write hazard.
570(define_insn_reservation "fr400_i1_div" 20
571  (and (eq_attr "cpu" "fr400,fr405")
572       (eq_attr "type" "div"))
573  "i0 + idiv1*19")
574
575(define_insn_reservation "fr450_i1_div" 19
576  (and (eq_attr "cpu" "fr450")
577       (eq_attr "type" "div"))
578  "i0 + idiv1*19")
579
580;; 4 is for a write-after-write hazard.
581(define_insn_reservation "fr400_i2" 4
582  (and (eq_attr "cpu" "fr400,fr405")
583       (eq_attr "type" "gload,fload"))
584  "i0")
585
586(define_insn_reservation "fr450_i2_gload" 3
587  (and (eq_attr "cpu" "fr450")
588       (eq_attr "type" "gload"))
589  "i0")
590
591;; 4 is for a write-after-write hazard.
592(define_insn_reservation "fr450_i2_fload" 4
593  (and (eq_attr "cpu" "fr450")
594       (eq_attr "type" "fload"))
595  "i0")
596
597(define_insn_reservation "fr400_i3" 0
598  (and (eq_attr "cpu" "fr400,fr405,fr450")
599       (eq_attr "type" "gstore,fstore"))
600  "i0")
601
602;; 3 is for a write-after-write hazard.
603(define_insn_reservation "fr400_i4" 3
604  (and (eq_attr "cpu" "fr400,fr405")
605       (eq_attr "type" "movfg,movgf"))
606  "i0")
607
608(define_insn_reservation "fr450_i4_movfg" 2
609  (and (eq_attr "cpu" "fr450")
610       (eq_attr "type" "movfg"))
611  "i0")
612
613;; 3 is for a write-after-write hazard.
614(define_insn_reservation "fr450_i4_movgf" 3
615  (and (eq_attr "cpu" "fr450")
616       (eq_attr "type" "movgf"))
617  "i0")
618
619(define_insn_reservation "fr400_i5" 0
620  (and (eq_attr "cpu" "fr400,fr405,fr450")
621       (eq_attr "type" "jumpl"))
622  "i0")
623
624;; The bypass between FPR loads and media instructions, described above.
625
626(define_bypass 3
627  "fr400_i2"
628  "fr400_m1_1,fr400_m1_2,\
629   fr400_m2_1,fr400_m2_2,\
630   fr400_m3_1,fr400_m3_2,\
631   fr400_m4_1,fr400_m4_2,\
632   fr400_m5")
633
634;; The branch instructions all use the B unit and produce no result.
635
636(define_insn_reservation "fr400_b" 0
637  (and (eq_attr "cpu" "fr400,fr405,fr450")
638       (eq_attr "type" "jump,branch,ccr,call"))
639  "b0")
640
641;; FP->FP moves are marked as "fsconv" instructions in the define_insns
642;; below, but are implemented on the FR400 using "mlogic" instructions.
643;; It's easier to class "fsconv" as a "m1:1" instruction than provide
644;; separate define_insns for the FR400.
645
646;; M1 instructions store their results in FPRs.  Any instruction can read
647;; the result in the following cycle, so no penalty occurs.
648
649(define_automaton "fr400_media")
650(define_cpu_unit "fr400_m1a,fr400_m1b,fr400_m2a" "fr400_media")
651(exclusion_set "fr400_m1a,fr400_m1b" "fr400_m2a")
652
653(define_reservation "fr400_m1" "(f1|f0) + (fr400_m1a|fr400_m1b)")
654(define_reservation "fr400_m2" "f0 + fr400_m2a")
655
656(define_insn_reservation "fr400_m1_1" 1
657  (and (eq_attr "cpu" "fr400,fr405")
658       (eq_attr "type" "fsconv,mnop,mlogic,maveh,msath,maddh,mabsh,mset"))
659  "fr400_m1")
660
661(define_insn_reservation "fr400_m1_2" 1
662  (and (eq_attr "cpu" "fr400,fr405")
663       (eq_attr "type" "mqaddh,mqsath,mqlimh,mqshift"))
664  "fr400_m2")
665
666;; M2 instructions store their results in accumulators, which are read
667;; by M2 or M4 media commands.  M2 instructions can read the results in
668;; the following cycle, but M4 instructions must wait a cycle more.
669
670(define_bypass 1
671  "fr400_m2_1,fr400_m2_2"
672  "fr400_m2_1,fr400_m2_2")
673
674(define_insn_reservation "fr400_m2_1" 2
675  (and (eq_attr "cpu" "fr400,fr405")
676       (eq_attr "type" "mmulh,mmulxh,mmach,mmrdh,mcpx,maddacc"))
677  "fr400_m1")
678
679(define_insn_reservation "fr400_m2_2" 2
680  (and (eq_attr "cpu" "fr400,fr405")
681       (eq_attr "type" "mqmulh,mqmulxh,mqmach,mqcpx,mdaddacc"))
682  "fr400_m2")
683
684;; For our purposes, there seems to be little real difference between
685;; M1 and M3 instructions.  Keep them separate anyway in case the distinction
686;; is needed later.
687
688(define_insn_reservation "fr400_m3_1" 1
689  (and (eq_attr "cpu" "fr400,fr405")
690       (eq_attr "type" "mpackh,mrot,mshift,mexpdhw"))
691  "fr400_m1")
692
693(define_insn_reservation "fr400_m3_2" 1
694  (and (eq_attr "cpu" "fr400,fr405")
695       (eq_attr "type" "munpackh,mdpackh,mbhconv,mexpdhd,mwcut,mdrot,mcpl"))
696  "fr400_m2")
697
698;; M4 instructions write to accumulators or FPRs.  MOVFG and STF
699;; instructions can read an FPR result in the following cycle, but
700;; M-unit instructions must wait a cycle more for either kind of result.
701
702(define_bypass 1 "fr400_m4_1,fr400_m4_2" "fr400_i3,fr400_i4")
703
704(define_insn_reservation "fr400_m4_1" 2
705  (and (eq_attr "cpu" "fr400,fr405")
706       (eq_attr "type" "mrdacc,mcut,mclracc"))
707  "fr400_m1")
708
709(define_insn_reservation "fr400_m4_2" 2
710  (and (eq_attr "cpu" "fr400,fr405")
711       (eq_attr "type" "mclracca,mdcut"))
712  "fr400_m2")
713
714;; M5 instructions always incur a 1-cycle penalty.
715
716(define_insn_reservation "fr400_m5" 2
717  (and (eq_attr "cpu" "fr400,fr405")
718       (eq_attr "type" "mwtacc"))
719  "fr400_m2")
720
721;; ::::::::::::::::::::
722;; ::
723;; :: FR450 media scheduler description
724;; ::
725;; ::::::::::::::::::::
726
727;; The FR451 media restrictions are similar to the FR400's, but not as
728;; strict and not as regular.  There are 6 categories with the following
729;; restrictions:
730;;
731;;		          M1
732;;	      M-1  M-2  M-3  M-4  M-5  M-6
733;;	M-1:         x         x         x
734;;	M-2:    x    x    x    x    x    x
735;;  M0	M-3:         x         x         x
736;;	M-4:    x    x    x    x
737;;	M-5:         x         x         x
738;;	M-6:    x    x    x    x    x    x
739;;
740;; where "x" indicates a conflict.
741;;
742;; There is no difference between M-1 and M-3 as far as issue
743;; restrictions are concerned, so they are combined as "m13".
744
745;; Units for odd-numbered categories.  There can be two of these
746;; in a packet.
747(define_cpu_unit "fr450_m13a,fr450_m13b" "float_media")
748(define_cpu_unit "fr450_m5a,fr450_m5b" "float_media")
749
750;; Units for even-numbered categories.  There can only be one per packet.
751(define_cpu_unit "fr450_m2a,fr450_m4a,fr450_m6a" "float_media")
752
753;; Enforce the restriction matrix above.
754(exclusion_set "fr450_m2a,fr450_m4a,fr450_m6a" "fr450_m13a,fr450_m13b")
755(exclusion_set "fr450_m2a,fr450_m6a" "fr450_m5a,fr450_m5b")
756(exclusion_set "fr450_m4a,fr450_m6a" "fr450_m2a")
757
758(define_reservation "fr450_m13" "(f1|f0) + (fr450_m13a|fr450_m13b)")
759(define_reservation "fr450_m2" "f0 + fr450_m2a")
760(define_reservation "fr450_m4" "f0 + fr450_m4a")
761(define_reservation "fr450_m5" "(f1|f0) + (fr450_m5a|fr450_m5b)")
762(define_reservation "fr450_m6" "(f0|f1) + fr450_m6a")
763
764;; MD-1, MD-3 and MD-8 instructions, which are the same as far
765;; as scheduling is concerned.  The inputs and outputs are FPRs.
766;; Instructions that have 32-bit inputs and outputs belong to M-1 while
767;; the rest belong to M-2.
768;;
769;; ??? Arithmetic shifts (MD-6) have an extra cycle latency, but we don't
770;; make the distinction between them and logical shifts.
771(define_insn_reservation "fr450_md138_1" 1
772  (and (eq_attr "cpu" "fr450")
773       (eq_attr "type" "fsconv,mnop,mlogic,maveh,msath,maddh,mabsh,mset,
774			mrot,mshift,mexpdhw,mpackh"))
775  "fr450_m13")
776
777(define_insn_reservation "fr450_md138_2" 1
778  (and (eq_attr "cpu" "fr450")
779       (eq_attr "type" "mqaddh,mqsath,mqlimh,
780			mdrot,mwcut,mqshift,mexpdhd,
781			munpackh,mdpackh,mbhconv,mcpl"))
782  "fr450_m2")
783
784;; MD-2 instructions.  These take FPR or ACC inputs and produce an ACC output.
785;; Instructions that write to double ACCs belong to M-3 while those that write
786;; to quad ACCs belong to M-4.
787(define_insn_reservation "fr450_md2_3" 2
788  (and (eq_attr "cpu" "fr450")
789       (eq_attr "type" "mmulh,mmach,mcpx,mmulxh,mmrdh,maddacc"))
790  "fr450_m13")
791
792(define_insn_reservation "fr450_md2_4" 2
793  (and (eq_attr "cpu" "fr450")
794       (eq_attr "type" "mqmulh,mqmach,mqcpx,mqmulxh,mdaddacc"))
795  "fr450_m4")
796
797;; Another MD-2 instruction can use the result on the following cycle.
798(define_bypass 1 "fr450_md2_3,fr450_md2_4" "fr450_md2_3,fr450_md2_4")
799
800;; MD-4 instructions that write to ACCs.
801(define_insn_reservation "fr450_md4_3" 2
802  (and (eq_attr "cpu" "fr450")
803       (eq_attr "type" "mclracc"))
804  "fr450_m13")
805
806(define_insn_reservation "fr450_md4_4" 3
807  (and (eq_attr "cpu" "fr450")
808       (eq_attr "type" "mclracca"))
809  "fr450_m4")
810
811;; MD-4 instructions that write to FPRs.
812(define_insn_reservation "fr450_md4_1" 2
813  (and (eq_attr "cpu" "fr450")
814       (eq_attr "type" "mcut"))
815  "fr450_m13")
816
817(define_insn_reservation "fr450_md4_5" 2
818  (and (eq_attr "cpu" "fr450")
819       (eq_attr "type" "mrdacc"))
820  "fr450_m5")
821
822(define_insn_reservation "fr450_md4_6" 2
823  (and (eq_attr "cpu" "fr450")
824       (eq_attr "type" "mdcut"))
825  "fr450_m6")
826
827;; Integer instructions can read the FPR result of an MD-4 instruction on
828;; the following cycle.
829(define_bypass 1 "fr450_md4_1,fr450_md4_5,fr450_md4_6"
830		 "fr400_i3,fr450_i4_movfg")
831
832;; MD-5 instructions, which belong to M-3.  They take FPR inputs and
833;; write to ACCs.
834(define_insn_reservation "fr450_md5_3" 2
835  (and (eq_attr "cpu" "fr450")
836       (eq_attr "type" "mwtacc"))
837  "fr450_m13")
838
839;; ::::::::::::::::::::
840;; ::
841;; :: FR550 scheduler description
842;; ::
843;; ::::::::::::::::::::
844
845;; Prevent loads and stores from being issued in the same packet.
846;; These units must go into the generic "integer" reservation because
847;; of the constraints on fr550_store0 and fr550_store1.
848(define_cpu_unit "fr550_load0,fr550_load1" "integer")
849(define_cpu_unit "fr550_store0,fr550_store1" "integer")
850(exclusion_set "fr550_load0,fr550_load1" "fr550_store0,fr550_store1")
851
852;; A store can only issue to I1 if one has also been issued to I0.
853(presence_set "fr550_store1" "fr550_store0")
854
855(define_bypass 0 "fr550_sethi" "fr550_setlo")
856(define_insn_reservation "fr550_sethi" 1
857  (and (eq_attr "cpu" "fr550")
858       (eq_attr "type" "sethi"))
859  "i3|i2|i1|i0")
860
861(define_insn_reservation "fr550_setlo" 1
862  (and (eq_attr "cpu" "fr550")
863       (eq_attr "type" "setlo"))
864  "i3|i2|i1|i0")
865
866(define_insn_reservation "fr550_int" 1
867  (and (eq_attr "cpu" "fr550")
868       (eq_attr "type" "int"))
869  "i3|i2|i1|i0")
870
871(define_insn_reservation "fr550_mul" 2
872  (and (eq_attr "cpu" "fr550")
873       (eq_attr "type" "mul"))
874  "i1|i0")
875
876(define_insn_reservation "fr550_div" 19
877  (and (eq_attr "cpu" "fr550")
878       (eq_attr "type" "div"))
879  "(i1|i0),(idiv1*18 | idiv2*18)")
880
881(define_insn_reservation "fr550_load" 3
882  (and (eq_attr "cpu" "fr550")
883       (eq_attr "type" "gload,fload"))
884  "(i1|i0)+(fr550_load0|fr550_load1)")
885
886;; We can only issue a store to I1 if one was also issued to I0.
887;; This means that, as far as frv_reorder_packet is concerned,
888;; the instruction has the same priority as an I0-only instruction.
889(define_insn_reservation "fr550_store" 1
890  (and (eq_attr "cpu" "fr550")
891       (eq_attr "type" "gstore,fstore"))
892  "(i0+fr550_store0)|(i1+fr550_store1)")
893
894(define_insn_reservation "fr550_transfer" 2
895  (and (eq_attr "cpu" "fr550")
896       (eq_attr "type" "movgf,movfg"))
897  "i0")
898
899(define_insn_reservation "fr550_jumpl" 0
900  (and (eq_attr "cpu" "fr550")
901       (eq_attr "type" "jumpl"))
902  "i0")
903
904(define_cpu_unit "fr550_ccr0,fr550_ccr1" "float_media")
905
906(define_insn_reservation "fr550_branch" 0
907  (and (eq_attr "cpu" "fr550")
908       (eq_attr "type" "jump,branch"))
909  "b1|b0")
910
911(define_insn_reservation "fr550_ccr" 0
912  (and (eq_attr "cpu" "fr550")
913       (eq_attr "type" "ccr"))
914  "(b1|b0) + (fr550_ccr1|fr550_ccr0)")
915
916(define_insn_reservation "fr550_call" 0
917  (and (eq_attr "cpu" "fr550")
918       (eq_attr "type" "call"))
919  "b0")
920
921(define_automaton "fr550_float_media")
922(define_cpu_unit "fr550_add0,fr550_add1" "fr550_float_media")
923
924;; There are three possible combinations of floating-point/media instructions:
925;;
926;;    - one media and one float
927;;    - up to four float, no media
928;;    - up to four media, no float
929(define_cpu_unit "fr550_f0,fr550_f1,fr550_f2,fr550_f3" "fr550_float_media")
930(define_cpu_unit "fr550_m0,fr550_m1,fr550_m2,fr550_m3" "fr550_float_media")
931(exclusion_set "fr550_f1,fr550_f2,fr550_f3" "fr550_m1,fr550_m2,fr550_m3")
932(exclusion_set "fr550_m0" "fr550_f1,fr550_f2,fr550_f3")
933;; FIXME: This next exclusion set should be defined as well, so that we do
934;; not get a packet containing multiple media instructions plus a single
935;; floating point instruction.  At the moment we can get away with not
936;; defining it because gcc does not seem to generate such packets.
937;;
938;; If we do enable the exclusion however the insertion of fnop insns into
939;; a packet containing media instructions will stop working, because the
940;; fnop insn counts as a floating point instruction.  The correct solution
941;; is to fix the reservation for the fnop insn so that it does not have the
942;; same restrictions as ordinary floating point insns.
943;;(exclusion_set "fr550_f0" "fr550_m1,fr550_m2,fr550_m3")
944
945(define_reservation "fr550_float" "fr550_f0|fr550_f1|fr550_f2|fr550_f3")
946(define_reservation "fr550_media" "fr550_m0|fr550_m1|fr550_m2|fr550_m3")
947
948(define_insn_reservation "fr550_f1" 0
949  (and (eq_attr "cpu" "fr550")
950       (eq_attr "type" "fnop"))
951  "(f3|f2|f1|f0) + fr550_float")
952
953(define_insn_reservation "fr550_f2" 3
954  (and (eq_attr "cpu" "fr550")
955       (eq_attr "type" "fsconv,fsadd,fscmp"))
956  "(f3|f2|f1|f0) + (fr550_add0|fr550_add1) + fr550_float")
957
958(define_insn_reservation "fr550_f3_mul" 3
959  (and (eq_attr "cpu" "fr550")
960       (eq_attr "type" "fsmul"))
961  "(f1|f0) + fr550_float")
962
963(define_insn_reservation "fr550_f3_div" 10
964  (and (eq_attr "cpu" "fr550")
965       (eq_attr "type" "fsdiv"))
966  "(f1|f0) + fr550_float")
967
968(define_insn_reservation "fr550_f3_sqrt" 15
969  (and (eq_attr "cpu" "fr550")
970       (eq_attr "type" "sqrt_single"))
971  "(f1|f0) + fr550_float")
972
973;; Synthetic units for enforcing media issue restrictions.  Certain types
974;; of insn in M2 conflict with certain types in M0:
975;;
976;;			     M2
977;;               MNOP   MALU   MSFT   MMAC   MSET
978;;         MNOP     -      -      x      -      -
979;;         MALU     -      x      x      -      -
980;;   M0    MSFT     -      -      x      -      x
981;;         MMAC     -      -      x      x      -
982;;         MSET     -      -      x      -      -
983;;
984;; where "x" indicates a conflict.  The same restrictions apply to
985;; M3 and M1.
986;;
987;; In addition -- and this is the awkward bit! -- instructions that
988;; access ACC0-3 can only issue to M0 or M2.  Those that access ACC4-7
989;; can only issue to M1 or M3.  We refer to such instructions as "even"
990;; and "odd" respectively.
991(define_cpu_unit "fr550_malu0,fr550_malu1" "float_media")
992(define_cpu_unit "fr550_malu2,fr550_malu3" "float_media")
993(define_cpu_unit "fr550_msft0,fr550_msft1" "float_media")
994(define_cpu_unit "fr550_mmac0,fr550_mmac1" "float_media")
995(define_cpu_unit "fr550_mmac2,fr550_mmac3" "float_media")
996(define_cpu_unit "fr550_mset0,fr550_mset1" "float_media")
997(define_cpu_unit "fr550_mset2,fr550_mset3" "float_media")
998
999(exclusion_set "fr550_malu0" "fr550_malu2")
1000(exclusion_set "fr550_malu1" "fr550_malu3")
1001
1002(exclusion_set "fr550_msft0" "fr550_mset2")
1003(exclusion_set "fr550_msft1" "fr550_mset3")
1004
1005(exclusion_set "fr550_mmac0" "fr550_mmac2")
1006(exclusion_set "fr550_mmac1" "fr550_mmac3")
1007
1008;; If an MSFT or MMAC instruction issues to a unit other than M0, we may
1009;; need to insert some nops.  In the worst case, the packet will end up
1010;; having 4 integer instructions and 4 media instructions, leaving no
1011;; room for any branch instructions that the DFA might have accepted.
1012;;
1013;; This doesn't matter for JUMP_INSNs and CALL_INSNs because they are
1014;; always the last instructions to be passed to the DFA, and could be
1015;; pushed out to a separate packet once the nops have been added.
1016;; However, it does cause problems for ccr instructions since they
1017;; can occur anywhere in the unordered packet.
1018(exclusion_set "fr550_msft1,fr550_mmac1,fr550_mmac2,fr550_mmac3"
1019	       "fr550_ccr0,fr550_ccr1")
1020
1021(define_reservation "fr550_malu"
1022  "(f3 + fr550_malu3) | (f2 + fr550_malu2)
1023   | (f1 + fr550_malu1) | (f0 + fr550_malu0)")
1024
1025(define_reservation "fr550_msft_even"
1026  "f0 + fr550_msft0")
1027
1028(define_reservation "fr550_msft_odd"
1029  "f1 + fr550_msft1")
1030
1031(define_reservation "fr550_msft_either"
1032  "(f1 + fr550_msft1) | (f0 + fr550_msft0)")
1033
1034(define_reservation "fr550_mmac_even"
1035  "(f2 + fr550_mmac2) | (f0 + fr550_mmac0)")
1036
1037(define_reservation "fr550_mmac_odd"
1038  "(f3 + fr550_mmac3) | (f1 + fr550_mmac1)")
1039
1040(define_reservation "fr550_mset"
1041  "(f3 + fr550_mset3) | (f2 + fr550_mset2)
1042    | (f1 + fr550_mset1) | (f0 + fr550_mset0)")
1043
1044(define_insn_reservation "fr550_mnop" 0
1045  (and (eq_attr "cpu" "fr550")
1046       (eq_attr "type" "mnop"))
1047  "fr550_media + (f3|f2|f1|f0)")
1048
1049(define_insn_reservation "fr550_malu" 2
1050  (and (eq_attr "cpu" "fr550")
1051       (eq_attr "type" "mlogic,maveh,msath,mabsh,maddh,mqaddh,mqsath"))
1052  "fr550_media + fr550_malu")
1053
1054;; These insns only operate on FPRs and so don't need to be classified
1055;; as even/odd.
1056(define_insn_reservation "fr550_msft_1_either" 2
1057  (and (eq_attr "cpu" "fr550")
1058       (eq_attr "type" "mrot,mwcut,mshift,mexpdhw,mexpdhd,mpackh,
1059			munpackh,mdpackh,mbhconv,mdrot,mcpl"))
1060  "fr550_media + fr550_msft_either")
1061
1062;; These insns read from ACC0-3.
1063(define_insn_reservation "fr550_msft_1_even" 2
1064  (and (eq_attr "cpu" "fr550")
1065       (and (eq_attr "type" "mcut,mrdacc,mdcut")
1066	    (eq_attr "acc_group" "even")))
1067  "fr550_media + fr550_msft_even")
1068
1069;; These insns read from ACC4-7.
1070(define_insn_reservation "fr550_msft_1_odd" 2
1071  (and (eq_attr "cpu" "fr550")
1072       (and (eq_attr "type" "mcut,mrdacc,mdcut")
1073	    (eq_attr "acc_group" "odd")))
1074  "fr550_media + fr550_msft_odd")
1075
1076;; MCLRACC with A=1 can issue to either M0 or M1.
1077(define_insn_reservation "fr550_msft_2_either" 2
1078  (and (eq_attr "cpu" "fr550")
1079       (eq_attr "type" "mclracca"))
1080  "fr550_media + fr550_msft_either")
1081
1082;; These insns write to ACC0-3.
1083(define_insn_reservation "fr550_msft_2_even" 2
1084  (and (eq_attr "cpu" "fr550")
1085       (and (eq_attr "type" "mclracc,mwtacc")
1086	    (eq_attr "acc_group" "even")))
1087  "fr550_media + fr550_msft_even")
1088
1089;; These insns write to ACC4-7.
1090(define_insn_reservation "fr550_msft_2_odd" 2
1091  (and (eq_attr "cpu" "fr550")
1092       (and (eq_attr "type" "mclracc,mwtacc")
1093	    (eq_attr "acc_group" "odd")))
1094  "fr550_media + fr550_msft_odd")
1095
1096;; These insns read from and write to ACC0-3.
1097(define_insn_reservation "fr550_mmac_even" 2
1098  (and (eq_attr "cpu" "fr550")
1099       (and (eq_attr "type" "mmulh,mmulxh,mmach,mmrdh,mqmulh,mqmulxh,mqmach,
1100			     maddacc,mdaddacc,mcpx,mqcpx")
1101	    (eq_attr "acc_group" "even")))
1102  "fr550_media + fr550_mmac_even")
1103
1104;; These insns read from and write to ACC4-7.
1105(define_insn_reservation "fr550_mmac_odd" 2
1106  (and (eq_attr "cpu" "fr550")
1107       (and (eq_attr "type" "mmulh,mmulxh,mmach,mmrdh,mqmulh,mqmulxh,mqmach,
1108			     maddacc,mdaddacc,mcpx,mqcpx")
1109	    (eq_attr "acc_group" "odd")))
1110  "fr550_media + fr550_mmac_odd")
1111
1112(define_insn_reservation "fr550_mset" 1
1113  (and (eq_attr "cpu" "fr550")
1114       (eq_attr "type" "mset"))
1115  "fr550_media + fr550_mset")
1116
1117;; ::::::::::::::::::::
1118;; ::
1119;; :: Simple/FR300 scheduler description
1120;; ::
1121;; ::::::::::::::::::::
1122
1123;; Fr300 or simple processor.  To describe it as 1 insn issue
1124;; processor, we use control unit.
1125
1126(define_insn_reservation "fr300_lat1" 1
1127  (and (eq_attr "cpu" "fr300,simple")
1128       (eq_attr "type" "!gload,fload,movfg,movgf"))
1129  "c + control")
1130
1131(define_insn_reservation "fr300_lat2" 2
1132  (and (eq_attr "cpu" "fr300,simple")
1133       (eq_attr "type" "gload,fload,movfg,movgf"))
1134  "c + control")
1135
1136
1137;; ::::::::::::::::::::
1138;; ::
1139;; :: Delay Slots
1140;; ::
1141;; ::::::::::::::::::::
1142
1143;; The insn attribute mechanism can be used to specify the requirements for
1144;; delay slots, if any, on a target machine.  An instruction is said to require
1145;; a "delay slot" if some instructions that are physically after the
1146;; instruction are executed as if they were located before it.  Classic
1147;; examples are branch and call instructions, which often execute the following
1148;; instruction before the branch or call is performed.
1149
1150;; On some machines, conditional branch instructions can optionally "annul"
1151;; instructions in the delay slot.  This means that the instruction will not be
1152;; executed for certain branch outcomes.  Both instructions that annul if the
1153;; branch is true and instructions that annul if the branch is false are
1154;; supported.
1155
1156;; Delay slot scheduling differs from instruction scheduling in that
1157;; determining whether an instruction needs a delay slot is dependent only
1158;; on the type of instruction being generated, not on data flow between the
1159;; instructions.  See the next section for a discussion of data-dependent
1160;; instruction scheduling.
1161
1162;; The requirement of an insn needing one or more delay slots is indicated via
1163;; the `define_delay' expression.  It has the following form:
1164;;
1165;; (define_delay TEST
1166;;   [DELAY-1 ANNUL-TRUE-1 ANNUL-FALSE-1
1167;;    DELAY-2 ANNUL-TRUE-2 ANNUL-FALSE-2
1168;;    ...])
1169
1170;; TEST is an attribute test that indicates whether this `define_delay' applies
1171;; to a particular insn.  If so, the number of required delay slots is
1172;; determined by the length of the vector specified as the second argument.  An
1173;; insn placed in delay slot N must satisfy attribute test DELAY-N.
1174;; ANNUL-TRUE-N is an attribute test that specifies which insns may be annulled
1175;; if the branch is true.  Similarly, ANNUL-FALSE-N specifies which insns in
1176;; the delay slot may be annulled if the branch is false.  If annulling is not
1177;; supported for that delay slot, `(nil)' should be coded.
1178
1179;; For example, in the common case where branch and call insns require a single
1180;; delay slot, which may contain any insn other than a branch or call, the
1181;; following would be placed in the `md' file:
1182
1183;; (define_delay (eq_attr "type" "branch,call")
1184;;		 [(eq_attr "type" "!branch,call") (nil) (nil)])
1185
1186;; Multiple `define_delay' expressions may be specified.  In this case, each
1187;; such expression specifies different delay slot requirements and there must
1188;; be no insn for which tests in two `define_delay' expressions are both true.
1189
1190;; For example, if we have a machine that requires one delay slot for branches
1191;; but two for calls, no delay slot can contain a branch or call insn, and any
1192;; valid insn in the delay slot for the branch can be annulled if the branch is
1193;; true, we might represent this as follows:
1194
1195;; (define_delay (eq_attr "type" "branch")
1196;;   [(eq_attr "type" "!branch,call")
1197;;    (eq_attr "type" "!branch,call")
1198;;    (nil)])
1199;;
1200;; (define_delay (eq_attr "type" "call")
1201;;   [(eq_attr "type" "!branch,call") (nil) (nil)
1202;;    (eq_attr "type" "!branch,call") (nil) (nil)])
1203
1204;; Note - it is the backend's responsibility to fill any unfilled delay slots
1205;; at assembler generation time.  This is usually done by adding a special print
1206;; operand to the delayed instruction, and then in the PRINT_OPERAND function
1207;; calling dbr_sequence_length() to determine how many delay slots were filled.
1208;; For example:
1209;;
1210;; --------------<machine>.md-----------------
1211;; (define_insn "call"
1212;;  [(call (match_operand 0 "memory_operand" "m")
1213;;         (match_operand 1 "" ""))]
1214;;   ""
1215;;   "call_delayed %0,%1,%2%#"
1216;;  [(set_attr "length" "4")
1217;;   (set_attr "type" "call")])
1218;;
1219;; -------------<machine>.h-------------------
1220;; #define PRINT_OPERAND_PUNCT_VALID_P(CODE) (CODE == '#')
1221;;
1222;;  ------------<machine>.c------------------
1223;; void
1224;; machine_print_operand (file, x, code)
1225;;     FILE * file;
1226;;     rtx    x;
1227;;     int    code;
1228;; {
1229;;   switch (code)
1230;;   {
1231;;   case '#':
1232;;     if (dbr_sequence_length () == 0)
1233;;       fputs ("\n\tnop", file);
1234;;     return;
1235
1236;; ::::::::::::::::::::
1237;; ::
1238;; :: Notes on Patterns
1239;; ::
1240;; ::::::::::::::::::::
1241
1242;; If you need to construct a sequence of assembler instructions in order
1243;; to implement a pattern be sure to escape any backslashes and double quotes
1244;; that you use, e.g.:
1245;;
1246;; (define_insn "an example"
1247;;   [(some rtl)]
1248;;   ""
1249;;   "*
1250;;    { static char buffer [100];
1251;;      sprintf (buffer, \"insn \\t %d\", REGNO (operands[1]));
1252;;      return buffer;
1253;;    }"
1254;; )
1255;;
1256;; Also if there is more than one instruction, they can be separated by \\;
1257;; which is a space saving synonym for \\n\\t:
1258;;
1259;; (define_insn "another example"
1260;;   [(some rtl)]
1261;;   ""
1262;;   "*
1263;;    { static char buffer [100];
1264;;      sprintf (buffer, \"insn1 \\t %d\\;insn2 \\t %%1\",
1265;;        REGNO (operands[1]));
1266;;      return buffer;
1267;;    }"
1268;; )
1269;;
1270
1271(include "predicates.md")
1272(include "constraints.md")
1273
1274;; ::::::::::::::::::::
1275;; ::
1276;; :: Moves
1277;; ::
1278;; ::::::::::::::::::::
1279
1280;; Wrap moves in define_expand to prevent memory->memory moves from being
1281;; generated at the RTL level, which generates better code for most machines
1282;; which can't do mem->mem moves.
1283
1284;; If operand 0 is a `subreg' with mode M of a register whose own mode is wider
1285;; than M, the effect of this instruction is to store the specified value in
1286;; the part of the register that corresponds to mode M.  The effect on the rest
1287;; of the register is undefined.
1288
1289;; This class of patterns is special in several ways.  First of all, each of
1290;; these names *must* be defined, because there is no other way to copy a datum
1291;; from one place to another.
1292
1293;; Second, these patterns are not used solely in the RTL generation pass.  Even
1294;; the reload pass can generate move insns to copy values from stack slots into
1295;; temporary registers.  When it does so, one of the operands is a hard
1296;; register and the other is an operand that can need to be reloaded into a
1297;; register.
1298
1299;; Therefore, when given such a pair of operands, the pattern must
1300;; generate RTL which needs no reloading and needs no temporary
1301;; registers--no registers other than the operands.  For example, if
1302;; you support the pattern with a `define_expand', then in such a
1303;; case the `define_expand' mustn't call `force_reg' or any other such
1304;; function which might generate new pseudo registers.
1305
1306;; This requirement exists even for subword modes on a RISC machine
1307;; where fetching those modes from memory normally requires several
1308;; insns and some temporary registers.  Look in `spur.md' to see how
1309;; the requirement can be satisfied.
1310
1311;; During reload a memory reference with an invalid address may be passed as an
1312;; operand.  Such an address will be replaced with a valid address later in the
1313;; reload pass.  In this case, nothing may be done with the address except to
1314;; use it as it stands.  If it is copied, it will not be replaced with a valid
1315;; address.  No attempt should be made to make such an address into a valid
1316;; address and no routine (such as `change_address') that will do so may be
1317;; called.  Note that `general_operand' will fail when applied to such an
1318;; address.
1319;;
1320;; The global variable `reload_in_progress' (which must be explicitly declared
1321;; if required) can be used to determine whether such special handling is
1322;; required.
1323;;
1324;; The variety of operands that have reloads depends on the rest of
1325;; the machine description, but typically on a RISC machine these can
1326;; only be pseudo registers that did not get hard registers, while on
1327;; other machines explicit memory references will get optional
1328;; reloads.
1329;;
1330;; If a scratch register is required to move an object to or from memory, it
1331;; can be allocated using `gen_reg_rtx' prior to reload.  But this is
1332;; impossible during and after reload.  If there are cases needing scratch
1333;; registers after reload, you must define `SECONDARY_INPUT_RELOAD_CLASS' and
1334;; perhaps also `SECONDARY_OUTPUT_RELOAD_CLASS' to detect them, and provide
1335;; patterns `reload_inM' or `reload_outM' to handle them.
1336
1337;; The constraints on a `moveM' must permit moving any hard register to any
1338;; other hard register provided that `TARGET_HARD_REGNO_MODE_OK' permits
1339;; mode M in both registers and `REGISTER_MOVE_COST' applied to their
1340;; classes returns a value of 2.
1341
1342;; It is obligatory to support floating point `moveM' instructions
1343;; into and out of any registers that can hold fixed point values,
1344;; because unions and structures (which have modes `SImode' or
1345;; `DImode') can be in those registers and they may have floating
1346;; point members.
1347
1348;; There may also be a need to support fixed point `moveM' instructions
1349;; in and out of floating point registers.  Unfortunately, I have
1350;; forgotten why this was so, and I don't know whether it is still true.
1351;; If `TARGET_HARD_REGNO_MODE_OK' rejects fixed point values in floating
1352;; point registers, then the constraints of the fixed point `moveM'
1353;; instructions must be designed to avoid ever trying to reload into a
1354;; floating point register.
1355
1356(define_expand "movqi"
1357  [(set (match_operand:QI 0 "general_operand" "")
1358	(match_operand:QI 1 "general_operand" ""))]
1359  ""
1360  "{ frv_emit_move (QImode, operands[0], operands[1]); DONE; }")
1361
1362(define_insn "*movqi_load"
1363  [(set (match_operand:QI 0 "register_operand" "=d,f")
1364	(match_operand:QI 1 "frv_load_operand" "m,m"))]
1365  ""
1366  "* return output_move_single (operands, insn);"
1367  [(set_attr "length" "4")
1368   (set_attr "type" "gload,fload")])
1369
1370(define_insn "*movqi_internal"
1371  [(set (match_operand:QI 0 "move_destination_operand" "=d,d,m,m,?f,?f,?d,?m,f,d,f")
1372	(match_operand:QI 1 "move_source_operand"       "L,d,d,O, d, f, f, f,GO,!m,!m"))]
1373  "register_operand(operands[0], QImode) || reg_or_0_operand (operands[1], QImode)"
1374  "* return output_move_single (operands, insn);"
1375  [(set_attr "length" "4")
1376   (set_attr "type" "int,int,gstore,gstore,movgf,fsconv,movfg,fstore,movgf,gload,fload")])
1377
1378(define_expand "movhi"
1379  [(set (match_operand:HI 0 "general_operand" "")
1380	(match_operand:HI 1 "general_operand" ""))]
1381  ""
1382  "{ frv_emit_move (HImode, operands[0], operands[1]); DONE; }")
1383
1384(define_insn "*movhi_load"
1385  [(set (match_operand:HI 0 "register_operand" "=d,f")
1386	(match_operand:HI 1 "frv_load_operand" "m,m"))]
1387  ""
1388  "* return output_move_single (operands, insn);"
1389  [(set_attr "length" "4")
1390   (set_attr "type" "gload,fload")])
1391
1392(define_insn "*movhi_internal"
1393  [(set (match_operand:HI 0 "move_destination_operand" "=d,d,d,m,m,?f,?f,?d,?m,f,d,f")
1394	(match_operand:HI 1 "move_source_operand"       "L,n,d,d,O, d, f, f, f,GO,!m,!m"))]
1395  "register_operand(operands[0], HImode) || reg_or_0_operand (operands[1], HImode)"
1396  "* return output_move_single (operands, insn);"
1397  [(set_attr "length" "4,8,4,4,4,4,4,4,4,4,4,4")
1398   (set_attr "type" "int,multi,int,gstore,gstore,movgf,fsconv,movfg,fstore,movgf,gload,fload")])
1399
1400;; Split 2 word load of constants into sethi/setlo instructions
1401(define_split
1402  [(set (match_operand:HI 0 "integer_register_operand" "")
1403	(match_operand:HI 1 "int_2word_operand" ""))]
1404  "reload_completed"
1405  [(set (match_dup 0)
1406	(high:HI (match_dup 1)))
1407   (set (match_dup 0)
1408	(lo_sum:HI (match_dup 0)
1409		(match_dup 1)))]
1410  "")
1411
1412(define_insn "movhi_high"
1413  [(set (match_operand:HI 0 "integer_register_operand" "=d")
1414	(high:HI (match_operand:HI 1 "int_2word_operand" "i")))]
1415  ""
1416  "sethi #hi(%1), %0"
1417  [(set_attr "type" "sethi")
1418   (set_attr "length" "4")])
1419
1420(define_insn "movhi_lo_sum"
1421  [(set (match_operand:HI 0 "integer_register_operand" "+d")
1422	(lo_sum:HI (match_dup 0)
1423		   (match_operand:HI 1 "int_2word_operand" "i")))]
1424  ""
1425  "setlo #lo(%1), %0"
1426  [(set_attr "type" "setlo")
1427   (set_attr "length" "4")])
1428
1429(define_expand "movsi"
1430  [(set (match_operand:SI 0 "move_destination_operand" "")
1431	(match_operand:SI 1 "move_source_operand" ""))]
1432  ""
1433  "{ frv_emit_move (SImode, operands[0], operands[1]); DONE; }")
1434
1435;; Note - it is best to only have one movsi pattern and to handle
1436;; all the various contingencies by the use of alternatives.  This
1437;; allows reload the greatest amount of flexibility (since reload will
1438;; only choose amongst alternatives for a selected insn, it will not
1439;; replace the insn with another one).
1440
1441;; Unfortunately, we do have to separate out load-type moves from the rest,
1442;; and only allow memory source operands in the former.  If we do memory and
1443;; constant loads in a single pattern, reload will be tempted to force
1444;; constants into memory when the destination is a floating-point register.
1445;; That may make a function use a PIC pointer when it didn't before, and we
1446;; cannot change PIC usage (and hence stack layout) so late in the game.
1447;; The resulting sequences for loading constants into FPRs are preferable
1448;; even when we're not generating PIC code.
1449
1450;; However, if we don't accept input from memory at all in the generic
1451;; movsi pattern, reloads for asm instructions that reference pseudos
1452;; that end up assigned to memory will fail to match, because we
1453;; recognize them right after they're emitted, and we don't
1454;; re-recognize them again after the substitution for memory.  So keep
1455;; a memory constraint available, just make sure reload won't be
1456;; tempted to use it.
1457;;
1458
1459
1460(define_insn "*movsi_load"
1461  [(set (match_operand:SI 0 "register_operand" "=d,f")
1462	(match_operand:SI 1 "frv_load_operand" "m,m"))]
1463  ""
1464  "* return output_move_single (operands, insn);"
1465  [(set_attr "length" "4")
1466   (set_attr "type" "gload,fload")])
1467
1468(define_insn "*movsi_got"
1469  [(set (match_operand:SI 0 "integer_register_operand" "=d")
1470	(match_operand:SI 1 "got12_operand" ""))]
1471  ""
1472  "addi gr0, %1, %0"
1473  [(set_attr "type" "int")
1474   (set_attr "length" "4")])
1475
1476(define_insn "*movsi_high_got"
1477  [(set (match_operand:SI 0 "integer_register_operand" "=d")
1478	(high:SI (match_operand:SI 1 "const_unspec_operand" "")))]
1479  ""
1480  "sethi %1, %0"
1481  [(set_attr "type" "sethi")
1482   (set_attr "length" "4")])
1483
1484(define_insn "*movsi_lo_sum_got"
1485  [(set (match_operand:SI 0 "integer_register_operand" "=d")
1486	(lo_sum:SI (match_operand:SI 1 "integer_register_operand" "0")
1487		   (match_operand:SI 2 "const_unspec_operand" "")))]
1488  ""
1489  "setlo %2, %0"
1490  [(set_attr "type" "setlo")
1491   (set_attr "length" "4")])
1492
1493(define_insn "*movsi_internal"
1494  [(set (match_operand:SI 0 "move_destination_operand" "=d,d,d,m,m,z,d,d,f,f,m,?f,?z,d,f")
1495	(match_operand:SI 1 "move_source_operand"      "L,n,d,d,O,d,z,f,d,f,f,GO,GO,!m,!m"))]
1496  "register_operand (operands[0], SImode) || reg_or_0_operand (operands[1], SImode)"
1497  "* return output_move_single (operands, insn);"
1498  [(set_attr "length" "4,8,4,4,4,4,4,4,4,4,4,4,4,4,4")
1499   (set_attr "type" "int,multi,int,gstore,gstore,spr,spr,movfg,movgf,fsconv,fstore,movgf,spr,gload,fload")])
1500
1501;; Split 2 word load of constants into sethi/setlo instructions
1502(define_insn_and_split "*movsi_2word"
1503  [(set (match_operand:SI 0 "integer_register_operand" "=d")
1504	(match_operand:SI 1 "int_2word_operand" "i"))]
1505  ""
1506  "#"
1507  "reload_completed"
1508  [(set (match_dup 0)
1509	(high:SI (match_dup 1)))
1510   (set (match_dup 0)
1511	(lo_sum:SI (match_dup 0)
1512		(match_dup 1)))]
1513  ""
1514  [(set_attr "length" "8")
1515   (set_attr "type" "multi")])
1516
1517(define_insn "movsi_high"
1518  [(set (match_operand:SI 0 "integer_register_operand" "=d")
1519	(high:SI (match_operand:SI 1 "int_2word_operand" "i")))]
1520  ""
1521  "sethi #hi(%1), %0"
1522  [(set_attr "type" "sethi")
1523   (set_attr "length" "4")])
1524
1525(define_insn "movsi_lo_sum"
1526  [(set (match_operand:SI 0 "integer_register_operand" "+d")
1527	(lo_sum:SI (match_dup 0)
1528		   (match_operand:SI 1 "int_2word_operand" "i")))]
1529  ""
1530  "setlo #lo(%1), %0"
1531  [(set_attr "type" "setlo")
1532   (set_attr "length" "4")])
1533
1534(define_expand "movdi"
1535  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1536	(match_operand:DI 1 "general_operand" ""))]
1537  ""
1538  "{ frv_emit_move (DImode, operands[0], operands[1]); DONE; }")
1539
1540(define_insn "*movdi_double"
1541  [(set (match_operand:DI 0 "move_destination_operand" "=e,?h,??d,??f,R,?R,??m,??m,e,?h,??d,??f,?e,??d,?h,??f,R,m,e,??d,e,??d,?h,??f")
1542	(match_operand:DI 1 "move_source_operand"      " e,h,d,f,e,h,d,f,R,R,m,m,h,f,e,d,GO,GO,GO,GO,nF,nF,GO,GO"))]
1543  "TARGET_DOUBLE
1544   && (register_operand (operands[0], DImode)
1545       || reg_or_0_operand (operands[1], DImode))"
1546  "* return output_move_double (operands, insn);"
1547  [(set_attr "length" "8,4,8,8,4,4,8,8,4,4,8,8,4,8,4,8,4,8,8,8,16,16,8,8")
1548   (set_attr "type" "multi,fdconv,multi,multi,gstore,fstore,gstore,fstore,gload,fload,gload,fload,movfg,movfg,movgf,movgf,gstore,gstore,multi,multi,multi,multi,movgf,movgf")])
1549
1550(define_insn "*movdi_nodouble"
1551  [(set (match_operand:DI 0 "move_destination_operand" "=e,?h,??d,??f,R,?R,??m,??m,e,?h,??d,??f,?e,??d,?h,??f,R,m,e,??d,e,??d,?h,??f")
1552	(match_operand:DI 1 "move_source_operand"      " e,h,d,f,e,h,d,f,R,R,m,m,h,f,e,d,GO,GO,GO,GO,nF,nF,GO,GO"))]
1553  "!TARGET_DOUBLE
1554   && (register_operand (operands[0], DImode)
1555       || reg_or_0_operand (operands[1], DImode))"
1556  "* return output_move_double (operands, insn);"
1557  [(set_attr "length" "8,8,8,8,4,4,8,8,4,4,8,8,8,8,8,8,4,8,8,8,16,16,8,8")
1558   (set_attr "type" "multi,multi,multi,multi,gstore,fstore,gstore,fstore,gload,fload,gload,fload,movfg,movfg,movgf,movgf,gstore,gstore,multi,multi,multi,multi,movgf,movgf")])
1559
1560(define_split
1561  [(set (match_operand:DI 0 "register_operand" "")
1562	(match_operand:DI 1 "dbl_memory_two_insn_operand" ""))]
1563  "reload_completed"
1564  [(const_int 0)]
1565  "frv_split_double_load (operands[0], operands[1]);")
1566
1567(define_split
1568  [(set (match_operand:DI 0 "odd_reg_operand" "")
1569	(match_operand:DI 1 "memory_operand" ""))]
1570  "reload_completed"
1571  [(const_int 0)]
1572  "frv_split_double_load (operands[0], operands[1]);")
1573
1574(define_split
1575  [(set (match_operand:DI 0 "dbl_memory_two_insn_operand" "")
1576	(match_operand:DI 1 "reg_or_0_operand" ""))]
1577  "reload_completed"
1578  [(const_int 0)]
1579  "frv_split_double_store (operands[0], operands[1]);")
1580
1581(define_split
1582  [(set (match_operand:DI 0 "memory_operand" "")
1583	(match_operand:DI 1 "odd_reg_operand" ""))]
1584  "reload_completed"
1585  [(const_int 0)]
1586  "frv_split_double_store (operands[0], operands[1]);")
1587
1588(define_split
1589  [(set (match_operand:DI 0 "register_operand" "")
1590	(match_operand:DI 1 "register_operand" ""))]
1591  "reload_completed
1592   && (odd_reg_operand (operands[0], DImode)
1593       || odd_reg_operand (operands[1], DImode)
1594       || (integer_register_operand (operands[0], DImode)
1595	   && integer_register_operand (operands[1], DImode))
1596       || (!TARGET_DOUBLE
1597	   && fpr_operand (operands[0], DImode)
1598	   && fpr_operand (operands[1], DImode)))"
1599  [(set (match_dup 2) (match_dup 4))
1600   (set (match_dup 3) (match_dup 5))]
1601  "
1602{
1603  rtx op0      = operands[0];
1604  rtx op0_low  = gen_lowpart (SImode, op0);
1605  rtx op0_high = gen_highpart (SImode, op0);
1606  rtx op1      = operands[1];
1607  rtx op1_low  = gen_lowpart (SImode, op1);
1608  rtx op1_high = gen_highpart (SImode, op1);
1609
1610  /* We normally copy the low-numbered register first.  However, if the first
1611     register operand 0 is the same as the second register of operand 1, we
1612     must copy in the opposite order.  */
1613
1614  if (REGNO (op0_high) == REGNO (op1_low))
1615    {
1616      operands[2] = op0_low;
1617      operands[3] = op0_high;
1618      operands[4] = op1_low;
1619      operands[5] = op1_high;
1620    }
1621  else
1622    {
1623      operands[2] = op0_high;
1624      operands[3] = op0_low;
1625      operands[4] = op1_high;
1626      operands[5] = op1_low;
1627    }
1628}")
1629
1630(define_split
1631  [(set (match_operand:DI 0 "register_operand" "")
1632	(match_operand:DI 1 "const_int_operand" ""))]
1633  "reload_completed"
1634  [(set (match_dup 2) (match_dup 4))
1635   (set (match_dup 3) (match_dup 5))]
1636  "
1637{
1638  rtx op0 = operands[0];
1639  rtx op1 = operands[1];
1640
1641  operands[2] = gen_highpart (SImode, op0);
1642  operands[3] = gen_lowpart (SImode, op0);
1643  if (HOST_BITS_PER_WIDE_INT <= 32)
1644    {
1645      operands[4] = GEN_INT ((INTVAL (op1) < 0) ? -1 : 0);
1646      operands[5] = op1;
1647    }
1648  else
1649    {
1650      operands[4] = gen_int_mode ((INTVAL (op1) >> 16) >> 16, SImode);
1651      operands[5] = gen_int_mode (INTVAL (op1), SImode);
1652    }
1653}")
1654
1655(define_split
1656  [(set (match_operand:DI 0 "register_operand" "")
1657	(match_operand:DI 1 "const_double_operand" ""))]
1658  "reload_completed"
1659  [(set (match_dup 2) (match_dup 4))
1660   (set (match_dup 3) (match_dup 5))]
1661  "
1662{
1663  rtx op0 = operands[0];
1664  rtx op1 = operands[1];
1665
1666  operands[2] = gen_highpart (SImode, op0);
1667  operands[3] = gen_lowpart (SImode, op0);
1668  operands[4] = GEN_INT (CONST_DOUBLE_HIGH (op1));
1669  operands[5] = GEN_INT (CONST_DOUBLE_LOW (op1));
1670}")
1671
1672;; Floating Point Moves
1673;;
1674;; Note - Patterns for SF mode moves are compulsory, but
1675;; patterns for DF are optional, as GCC can synthesize them.
1676
1677(define_expand "movsf"
1678  [(set (match_operand:SF 0 "general_operand" "")
1679	(match_operand:SF 1 "general_operand" ""))]
1680  ""
1681  "{ frv_emit_move (SFmode, operands[0], operands[1]); DONE; }")
1682
1683(define_split
1684  [(set (match_operand:SF 0 "integer_register_operand" "")
1685	(match_operand:SF 1 "int_2word_operand" ""))]
1686  "reload_completed"
1687  [(set (match_dup 0)
1688	(high:SF (match_dup 1)))
1689   (set (match_dup 0)
1690	(lo_sum:SF (match_dup 0)
1691		(match_dup 1)))]
1692  "")
1693
1694(define_insn "*movsf_load_has_fprs"
1695  [(set (match_operand:SF 0 "register_operand" "=f,d")
1696	(match_operand:SF 1 "frv_load_operand" "m,m"))]
1697  "TARGET_HAS_FPRS"
1698  "* return output_move_single (operands, insn);"
1699  [(set_attr "length" "4")
1700   (set_attr "type" "fload,gload")])
1701
1702(define_insn "*movsf_internal_has_fprs"
1703  [(set (match_operand:SF 0 "move_destination_operand" "=f,f,m,m,?f,?d,?d,m,?d")
1704	(match_operand:SF 1 "move_source_operand" "f,OG,f,OG,d,f,d,d,F"))]
1705  "TARGET_HAS_FPRS
1706   && (register_operand (operands[0], SFmode) || reg_or_0_operand (operands[1], SFmode))"
1707  "* return output_move_single (operands, insn);"
1708  [(set_attr "length" "4,4,4,4,4,4,4,4,8")
1709   (set_attr "type" "fsconv,movgf,fstore,gstore,movgf,movfg,int,gstore,multi")])
1710
1711;; If we don't support the double instructions, prefer gprs over fprs, since it
1712;; will all be emulated
1713(define_insn "*movsf_internal_no_fprs"
1714  [(set (match_operand:SF 0 "move_destination_operand" "=d,d,m,d,d")
1715	(match_operand:SF 1 "move_source_operand"      " d,OG,dOG,m,F"))]
1716  "!TARGET_HAS_FPRS
1717   && (register_operand (operands[0], SFmode) || reg_or_0_operand (operands[1], SFmode))"
1718  "* return output_move_single (operands, insn);"
1719  [(set_attr "length" "4,4,4,4,8")
1720   (set_attr "type" "int,int,gstore,gload,multi")])
1721
1722(define_insn "movsf_high"
1723  [(set (match_operand:SF 0 "integer_register_operand" "=d")
1724	(high:SF (match_operand:SF 1 "int_2word_operand" "i")))]
1725  ""
1726  "sethi #hi(%1), %0"
1727  [(set_attr "type" "sethi")
1728   (set_attr "length" "4")])
1729
1730(define_insn "movsf_lo_sum"
1731  [(set (match_operand:SF 0 "integer_register_operand" "+d")
1732	(lo_sum:SF (match_dup 0)
1733		   (match_operand:SF 1 "int_2word_operand" "i")))]
1734  ""
1735  "setlo #lo(%1), %0"
1736  [(set_attr "type" "setlo")
1737   (set_attr "length" "4")])
1738
1739(define_expand "movdf"
1740  [(set (match_operand:DF 0 "nonimmediate_operand" "")
1741	(match_operand:DF 1 "general_operand" ""))]
1742  ""
1743  "{ frv_emit_move (DFmode, operands[0], operands[1]); DONE; }")
1744
1745(define_insn "*movdf_double"
1746  [(set (match_operand:DF 0 "move_destination_operand" "=h,?e,??f,??d,R,?R,??m,??m,h,?e,??f,??d,?h,??f,?e,??d,R,m,h,??f,e,??d,e,??d")
1747	(match_operand:DF 1 "move_source_operand"      " h,e,f,d,h,e,f,d,R,R,m,m,e,d,h,f,GO,GO,GO,GO,GO,GO,F,F"))]
1748  "TARGET_DOUBLE
1749   && (register_operand (operands[0], DFmode)
1750       || reg_or_0_operand (operands[1], DFmode))"
1751  "* return output_move_double (operands, insn);"
1752  [(set_attr "length" "4,8,8,8,4,4,8,8,4,4,8,8,4,8,4,8,4,8,8,8,8,8,16,16")
1753   (set_attr "type" "fdconv,multi,multi,multi,fstore,gstore,fstore,gstore,fload,gload,fload,gload,movgf,movgf,movfg,movfg,gstore,gstore,movgf,movgf,multi,multi,multi,multi")])
1754
1755;; If we don't support the double instructions, prefer gprs over fprs, since it
1756;; will all be emulated
1757(define_insn "*movdf_nodouble"
1758  [(set (match_operand:DF 0 "move_destination_operand" "=e,?h,??d,??f,R,?R,??m,??m,e,?h,??d,??f,?e,??d,?h,??f,R,m,e,??d,e,??d,?h,??f")
1759	(match_operand:DF 1 "move_source_operand"      " e,h,d,f,e,h,d,f,R,R,m,m,h,f,e,d,GO,GO,GO,GO,nF,nF,GO,GO"))]
1760  "!TARGET_DOUBLE
1761   && (register_operand (operands[0], DFmode)
1762       || reg_or_0_operand (operands[1], DFmode))"
1763  "* return output_move_double (operands, insn);"
1764  [(set_attr "length" "8,8,8,8,4,4,8,8,4,4,8,8,8,8,8,8,4,8,8,8,16,16,8,8")
1765   (set_attr "type" "multi,multi,multi,multi,gstore,fstore,gstore,fstore,gload,fload,gload,fload,movfg,movfg,movgf,movgf,gstore,gstore,multi,multi,multi,multi,movgf,movgf")])
1766
1767(define_split
1768  [(set (match_operand:DF 0 "register_operand" "")
1769	(match_operand:DF 1 "dbl_memory_two_insn_operand" ""))]
1770  "reload_completed"
1771  [(const_int 0)]
1772  "frv_split_double_load (operands[0], operands[1]);")
1773
1774(define_split
1775  [(set (match_operand:DF 0 "odd_reg_operand" "")
1776	(match_operand:DF 1 "memory_operand" ""))]
1777  "reload_completed"
1778  [(const_int 0)]
1779  "frv_split_double_load (operands[0], operands[1]);")
1780
1781(define_split
1782  [(set (match_operand:DF 0 "dbl_memory_two_insn_operand" "")
1783	(match_operand:DF 1 "reg_or_0_operand" ""))]
1784  "reload_completed"
1785  [(const_int 0)]
1786  "frv_split_double_store (operands[0], operands[1]);")
1787
1788(define_split
1789  [(set (match_operand:DF 0 "memory_operand" "")
1790	(match_operand:DF 1 "odd_reg_operand" ""))]
1791  "reload_completed"
1792  [(const_int 0)]
1793  "frv_split_double_store (operands[0], operands[1]);")
1794
1795(define_split
1796  [(set (match_operand:DF 0 "register_operand" "")
1797	(match_operand:DF 1 "register_operand" ""))]
1798  "reload_completed
1799   && (odd_reg_operand (operands[0], DFmode)
1800       || odd_reg_operand (operands[1], DFmode)
1801       || (integer_register_operand (operands[0], DFmode)
1802	   && integer_register_operand (operands[1], DFmode))
1803       || (!TARGET_DOUBLE
1804	   && fpr_operand (operands[0], DFmode)
1805	   && fpr_operand (operands[1], DFmode)))"
1806  [(set (match_dup 2) (match_dup 4))
1807   (set (match_dup 3) (match_dup 5))]
1808  "
1809{
1810  rtx op0      = operands[0];
1811  rtx op0_low  = gen_lowpart (SImode, op0);
1812  rtx op0_high = gen_highpart (SImode, op0);
1813  rtx op1      = operands[1];
1814  rtx op1_low  = gen_lowpart (SImode, op1);
1815  rtx op1_high = gen_highpart (SImode, op1);
1816
1817  /* We normally copy the low-numbered register first.  However, if the first
1818     register operand 0 is the same as the second register of operand 1, we
1819     must copy in the opposite order.  */
1820
1821  if (REGNO (op0_high) == REGNO (op1_low))
1822    {
1823      operands[2] = op0_low;
1824      operands[3] = op0_high;
1825      operands[4] = op1_low;
1826      operands[5] = op1_high;
1827    }
1828  else
1829    {
1830      operands[2] = op0_high;
1831      operands[3] = op0_low;
1832      operands[4] = op1_high;
1833      operands[5] = op1_low;
1834    }
1835}")
1836
1837(define_split
1838  [(set (match_operand:DF 0 "register_operand" "")
1839	(match_operand:DF 1 "const_int_operand" ""))]
1840  "reload_completed"
1841  [(set (match_dup 2) (match_dup 4))
1842   (set (match_dup 3) (match_dup 5))]
1843  "
1844{
1845  rtx op0 = operands[0];
1846  rtx op1 = operands[1];
1847
1848  operands[2] = gen_highpart (SImode, op0);
1849  operands[3] = gen_lowpart (SImode, op0);
1850  if (HOST_BITS_PER_WIDE_INT <= 32)
1851    {
1852      operands[4] = GEN_INT ((INTVAL (op1) < 0) ? -1 : 0);
1853      operands[5] = op1;
1854    }
1855  else
1856    {
1857      operands[4] = GEN_INT (((((unsigned HOST_WIDE_INT)INTVAL (op1) >> 16)
1858			      >> 16) ^ ((unsigned HOST_WIDE_INT)1 << 31))
1859			     - ((unsigned HOST_WIDE_INT)1 << 31));
1860      operands[5] = GEN_INT (trunc_int_for_mode (INTVAL (op1), SImode));
1861    }
1862}")
1863
1864(define_split
1865  [(set (match_operand:DF 0 "register_operand" "")
1866	(match_operand:DF 1 "const_double_operand" ""))]
1867  "reload_completed"
1868  [(set (match_dup 2) (match_dup 4))
1869   (set (match_dup 3) (match_dup 5))]
1870  "
1871{
1872  rtx op0 = operands[0];
1873  rtx op1 = operands[1];
1874  long l[2];
1875
1876  REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (op1), l);
1877
1878  operands[2] = gen_highpart (SImode, op0);
1879  operands[3] = gen_lowpart (SImode, op0);
1880  operands[4] = GEN_INT (l[0]);
1881  operands[5] = GEN_INT (l[1]);
1882}")
1883
1884;; String/block move insn.
1885;; Argument 0 is the destination
1886;; Argument 1 is the source
1887;; Argument 2 is the length
1888;; Argument 3 is the alignment
1889
1890(define_expand "movmemsi"
1891  [(parallel [(set (match_operand:BLK 0 "" "")
1892		   (match_operand:BLK 1 "" ""))
1893	      (use (match_operand:SI 2 "" ""))
1894	      (use (match_operand:SI 3 "" ""))])]
1895  ""
1896  "
1897{
1898  if (frv_expand_block_move (operands))
1899    DONE;
1900  else
1901    FAIL;
1902}")
1903
1904;; String/block set insn.
1905;; Argument 0 is the destination
1906;; Argument 1 is the length
1907;; Argument 2 is the byte value -- ignore any value but zero
1908;; Argument 3 is the alignment
1909
1910(define_expand "setmemsi"
1911  [(parallel [(set (match_operand:BLK 0 "" "")
1912		   (match_operand 2 "" ""))
1913	      (use (match_operand:SI 1 "" ""))
1914	      (use (match_operand:SI 3 "" ""))])]
1915  ""
1916  "
1917{
1918  /* If value to set is not zero, use the library routine.  */
1919  if (operands[2] != const0_rtx)
1920    FAIL;
1921
1922  if (frv_expand_block_clear (operands))
1923    DONE;
1924  else
1925    FAIL;
1926}")
1927
1928
1929;; The "membar" part of a __builtin_read* or __builtin_write* function.
1930;; Operand 0 is a volatile reference to the memory that the function reads
1931;; or writes.  Operand 1 is the address being accessed, or zero if the
1932;; address isn't a known constant.  Operand 2 describes the __builtin
1933;; function (either FRV_IO_READ or FRV_IO_WRITE).
1934(define_insn "optional_membar_<mode>"
1935  [(set (match_operand:IMODE 0 "memory_operand" "=m")
1936	(unspec:IMODE [(match_operand 1 "const_int_operand" "")
1937		       (match_operand 2 "const_int_operand" "")]
1938		      UNSPEC_OPTIONAL_MEMBAR))]
1939  ""
1940  "membar"
1941  [(set_attr "length" "4")])
1942
1943;; ::::::::::::::::::::
1944;; ::
1945;; :: Reload CC registers
1946;; ::
1947;; ::::::::::::::::::::
1948
1949;; Use as a define_expand so that cse/gcse/combine can't accidentally
1950;; create movcc insns.
1951
1952(define_expand "movcc"
1953  [(parallel [(set (match_operand:CC 0 "move_destination_operand" "")
1954		   (match_operand:CC 1 "move_source_operand" ""))
1955	      (clobber (match_dup 2))])]
1956  ""
1957  "
1958{
1959 if (! reload_in_progress && ! reload_completed)
1960    FAIL;
1961
1962 operands[2] = gen_rtx_REG (CC_CCRmode, ICR_TEMP);
1963}")
1964
1965(define_insn "*internal_movcc"
1966  [(set (match_operand:CC 0 "move_destination_operand" "=t,d,d,m,d")
1967	(match_operand:CC 1 "move_source_operand" "d,d,m,d,t"))
1968   (clobber (match_scratch:CC_CCR 2 "=X,X,X,X,&v"))]
1969  "reload_in_progress || reload_completed"
1970  "@
1971   cmpi %1, #0, %0
1972   mov %1, %0
1973   ld%I1%U1 %M1, %0
1974   st%I0%U0 %1, %M0
1975   #"
1976  [(set_attr "length" "4,4,4,4,20")
1977   (set_attr "type" "int,int,gload,gstore,multi")])
1978
1979;; To move an ICC value to a GPR for a signed comparison, we create a value
1980;; that when compared to 0, sets the N and Z flags appropriately (we don't care
1981;; about the V and C flags, since these comparisons are signed).
1982
1983(define_split
1984  [(set (match_operand:CC 0 "integer_register_operand" "")
1985	(match_operand:CC 1 "icc_operand" ""))
1986   (clobber (match_operand:CC_CCR 2 "icr_operand" ""))]
1987  "reload_in_progress || reload_completed"
1988  [(match_dup 3)]
1989  "
1990{
1991  rtx dest = simplify_gen_subreg (SImode, operands[0], CCmode, 0);
1992  rtx icc  = operands[1];
1993  rtx icr  = operands[2];
1994
1995  start_sequence ();
1996
1997  emit_insn (gen_rtx_SET (icr, gen_rtx_LT (CC_CCRmode, icc, const0_rtx)));
1998
1999  emit_insn (gen_movsi (dest, const1_rtx));
2000
2001  emit_insn (gen_rtx_COND_EXEC (VOIDmode,
2002				gen_rtx_NE (CC_CCRmode, icr, const0_rtx),
2003				gen_rtx_SET (dest,
2004					     gen_rtx_NEG (SImode, dest))));
2005
2006  emit_insn (gen_rtx_SET (icr, gen_rtx_EQ (CC_CCRmode, icc, const0_rtx)));
2007
2008  emit_insn (gen_rtx_COND_EXEC (VOIDmode,
2009				gen_rtx_NE (CC_CCRmode, icr, const0_rtx),
2010				gen_rtx_SET (dest, const0_rtx)));
2011
2012  operands[3] = get_insns ();
2013  end_sequence ();
2014}")
2015
2016;; Reload CC_UNSmode for unsigned integer comparisons
2017;; Use define_expand so that cse/gcse/combine can't create movcc_uns insns
2018
2019(define_expand "movcc_uns"
2020  [(parallel [(set (match_operand:CC_UNS 0 "move_destination_operand" "")
2021		   (match_operand:CC_UNS 1 "move_source_operand" ""))
2022	      (clobber (match_dup 2))])]
2023  ""
2024  "
2025{
2026 if (! reload_in_progress && ! reload_completed)
2027    FAIL;
2028 operands[2] = gen_rtx_REG (CC_CCRmode, ICR_TEMP);
2029}")
2030
2031(define_insn "*internal_movcc_uns"
2032  [(set (match_operand:CC_UNS 0 "move_destination_operand" "=t,d,d,m,d")
2033	(match_operand:CC_UNS 1 "move_source_operand" "d,d,m,d,t"))
2034   (clobber (match_scratch:CC_CCR 2 "=X,X,X,X,&v"))]
2035  "reload_in_progress || reload_completed"
2036  "@
2037   cmpi %1, #1, %0
2038   mov %1, %0
2039   ld%I1%U1 %M1, %0
2040   st%I0%U0 %1, %M0
2041   #"
2042  [(set_attr "length" "4,4,4,4,20")
2043   (set_attr "type" "int,int,gload,gstore,multi")])
2044
2045;; To move an ICC value to a GPR for an unsigned comparison, we create a value
2046;; that when compared to 1, sets the Z, V, and C flags appropriately (we don't
2047;; care about the N flag, since these comparisons are unsigned).
2048
2049(define_split
2050  [(set (match_operand:CC_UNS 0 "integer_register_operand" "")
2051	(match_operand:CC_UNS 1 "icc_operand" ""))
2052   (clobber (match_operand:CC_CCR 2 "icr_operand" ""))]
2053  "reload_in_progress || reload_completed"
2054  [(match_dup 3)]
2055  "
2056{
2057  rtx dest = simplify_gen_subreg (SImode, operands[0], CC_UNSmode, 0);
2058  rtx icc  = operands[1];
2059  rtx icr  = operands[2];
2060
2061  start_sequence ();
2062
2063  emit_insn (gen_rtx_SET (icr, gen_rtx_GTU (CC_CCRmode, icc, const0_rtx)));
2064
2065  emit_insn (gen_movsi (dest, const1_rtx));
2066
2067  emit_insn (gen_rtx_COND_EXEC (VOIDmode,
2068				gen_rtx_NE (CC_CCRmode, icr, const0_rtx),
2069				gen_addsi3 (dest, dest, dest)));
2070
2071  emit_insn (gen_rtx_SET (icr, gen_rtx_LTU (CC_CCRmode, icc, const0_rtx)));
2072
2073  emit_insn (gen_rtx_COND_EXEC (VOIDmode,
2074				gen_rtx_NE (CC_CCRmode, icr, const0_rtx),
2075				gen_rtx_SET (dest, const0_rtx)));
2076
2077  operands[3] = get_insns ();
2078  end_sequence ();
2079}")
2080
2081;; Reload CC_NZmode.  This is mostly the same as the CCmode and CC_UNSmode
2082;; handling, but it uses different sequences for moving between GPRs and ICCs.
2083
2084(define_expand "movcc_nz"
2085  [(parallel [(set (match_operand:CC_NZ 0 "move_destination_operand" "")
2086		   (match_operand:CC_NZ 1 "move_source_operand" ""))
2087	      (clobber (match_dup 2))])]
2088  ""
2089  "
2090{
2091  if (!reload_in_progress && !reload_completed)
2092    FAIL;
2093  operands[2] = gen_rtx_REG (CC_CCRmode, ICR_TEMP);
2094}")
2095
2096(define_insn "*internal_movcc_nz"
2097  [(set (match_operand:CC_NZ 0 "move_destination_operand" "=t,d,d,m,d")
2098	(match_operand:CC_NZ 1 "move_source_operand" "d,d,m,d,t"))
2099   (clobber (match_scratch:CC_CCR 2 "=X,X,X,X,&v"))]
2100  "reload_in_progress || reload_completed"
2101  "@
2102   cmpi %1, #0, %0
2103   mov %1, %0
2104   ld%I1%U1 %M1, %0
2105   st%I0%U0 %1, %M0
2106   #"
2107  [(set_attr "length" "4,4,4,4,20")
2108   (set_attr "type" "int,int,gload,gstore,multi")])
2109
2110;; Set the destination to a value that, when compared with zero, will
2111;; restore the value of the Z and N flags.  The values of the other
2112;; flags don't matter.  The sequence is:
2113;;
2114;;     setlos op0,#-1
2115;;     ckp op1,op2
2116;;     csub gr0,op0,op0,op2
2117;;     ckeq op1,op2
2118;;     cmov gr0,op0,op2
2119(define_split
2120  [(set (match_operand:CC_NZ 0 "integer_register_operand" "")
2121	(match_operand:CC_NZ 1 "icc_operand" ""))
2122   (clobber (match_operand:CC_CCR 2 "icr_operand" ""))]
2123  "reload_in_progress || reload_completed"
2124  [(set (match_dup 3)
2125	(const_int -1))
2126   (set (match_dup 2)
2127	(ge:CC_CCR (match_dup 1)
2128		   (const_int 0)))
2129   (cond_exec (ne:CC_CCR (match_dup 2)
2130			 (const_int 0))
2131	      (set (match_dup 3)
2132		   (neg:SI (match_dup 3))))
2133   (set (match_dup 2)
2134	(eq:CC_CCR (match_dup 1)
2135		   (const_int 0)))
2136   (cond_exec (ne:CC_CCR (match_dup 2)
2137			 (const_int 0))
2138	      (set (match_dup 3) (const_int 0)))]
2139  "operands[3] = simplify_gen_subreg (SImode, operands[0], CC_NZmode, 0);")
2140
2141;; Reload CC_FPmode for floating point comparisons
2142;; We use a define_expand here so that cse/gcse/combine can't accidentally
2143;; create movcc insns.  If this was a named define_insn, we would not be able
2144;; to make it conditional on reload.
2145
2146(define_expand "movcc_fp"
2147  [(set (match_operand:CC_FP 0 "movcc_fp_destination_operand" "")
2148	(match_operand:CC_FP 1 "move_source_operand" ""))]
2149  "TARGET_HAS_FPRS"
2150  "
2151{
2152 if (! reload_in_progress && ! reload_completed)
2153    FAIL;
2154}")
2155
2156(define_insn "*movcc_fp_internal"
2157  [(set (match_operand:CC_FP 0 "movcc_fp_destination_operand" "=d,d,d,m")
2158	(match_operand:CC_FP 1 "move_source_operand" "u,d,m,d"))]
2159  "TARGET_HAS_FPRS && (reload_in_progress || reload_completed)"
2160  "@
2161   #
2162   mov %1, %0
2163   ld%I1%U1 %M1, %0
2164   st%I0%U0 %1, %M0"
2165  [(set_attr "length" "12,4,4,4")
2166   (set_attr "type" "multi,int,gload,gstore")])
2167
2168
2169(define_expand "reload_incc_fp"
2170  [(match_operand:CC_FP 0 "fcc_operand" "=u")
2171   (match_operand:CC_FP 1 "gpr_or_memory_operand_with_scratch" "m")
2172   (match_operand:TI 2 "integer_register_operand" "=&d")]
2173  "TARGET_HAS_FPRS"
2174  "
2175{
2176  rtx cc_op2 = simplify_gen_subreg (CC_FPmode, operands[2], TImode, 0);
2177  rtx int_op2 = simplify_gen_subreg (SImode, operands[2], TImode, 0);
2178  rtx temp1 = simplify_gen_subreg (SImode, operands[2], TImode, 4);
2179  rtx temp2 = simplify_gen_subreg (SImode, operands[2], TImode, 8);
2180  int shift = CC_SHIFT_RIGHT (REGNO (operands[0]));
2181  HOST_WIDE_INT mask;
2182
2183  if (!gpr_or_memory_operand (operands[1], CC_FPmode))
2184    {
2185      rtx addr;
2186      rtx temp3 = simplify_gen_subreg (SImode, operands[2], TImode, 12);
2187
2188      gcc_assert (GET_CODE (operands[1]) == MEM);
2189
2190      addr = XEXP (operands[1], 0);
2191
2192      gcc_assert (GET_CODE (addr) == PLUS);
2193
2194      emit_move_insn (temp3, XEXP (addr, 1));
2195
2196      operands[1] = replace_equiv_address (operands[1],
2197					   gen_rtx_PLUS (GET_MODE (addr),
2198							 XEXP (addr, 0),
2199							 temp3));
2200    }
2201
2202  emit_insn (gen_movcc_fp (cc_op2, operands[1]));
2203  if (shift)
2204    emit_insn (gen_ashlsi3 (int_op2, int_op2, GEN_INT (shift)));
2205
2206  mask = ~ ((HOST_WIDE_INT)CC_MASK << shift);
2207  emit_insn (gen_movsi (temp1, GEN_INT (mask)));
2208  emit_insn (gen_update_fcc (operands[0], int_op2, temp1, temp2));
2209  DONE;
2210}")
2211
2212(define_expand "reload_outcc_fp"
2213  [(set (match_operand:CC_FP 2 "integer_register_operand" "=&d")
2214	(match_operand:CC_FP 1 "fcc_operand" "u"))
2215   (set (match_operand:CC_FP 0 "memory_operand" "=m")
2216	(match_dup 2))]
2217  "TARGET_HAS_FPRS"
2218 "")
2219
2220;; Convert a FCC value to gpr
2221(define_insn "read_fcc"
2222  [(set (match_operand:SI 0 "integer_register_operand" "=d")
2223	(unspec:SI [(match_operand:CC_FP 1 "fcc_operand" "u")]
2224		   UNSPEC_CC_TO_GPR))]
2225  "TARGET_HAS_FPRS"
2226  "movsg ccr, %0"
2227  [(set_attr "type" "spr")
2228   (set_attr "length" "4")])
2229
2230(define_split
2231  [(set (match_operand:CC_FP 0 "integer_register_operand" "")
2232	(match_operand:CC_FP 1 "fcc_operand" ""))]
2233  "reload_completed && TARGET_HAS_FPRS"
2234  [(match_dup 2)]
2235  "
2236{
2237  rtx int_op0 = simplify_gen_subreg (SImode, operands[0], CC_FPmode, 0);
2238  int shift = CC_SHIFT_RIGHT (REGNO (operands[1]));
2239
2240  start_sequence ();
2241
2242  emit_insn (gen_read_fcc (int_op0, operands[1]));
2243  if (shift)
2244    emit_insn (gen_lshrsi3 (int_op0, int_op0, GEN_INT (shift)));
2245
2246  emit_insn (gen_andsi3 (int_op0, int_op0, GEN_INT (CC_MASK)));
2247
2248  operands[2] = get_insns ();
2249  end_sequence ();
2250}")
2251
2252;; Move a gpr value to FCC.
2253;; Operand0 = FCC
2254;; Operand1 = reloaded value shifted appropriately
2255;; Operand2 = mask to eliminate current register
2256;; Operand3 = temporary to load/store ccr
2257(define_insn "update_fcc"
2258  [(set (match_operand:CC_FP 0 "fcc_operand" "=u")
2259	(unspec:CC_FP [(match_operand:SI 1 "integer_register_operand" "d")
2260		       (match_operand:SI 2 "integer_register_operand" "d")]
2261		      UNSPEC_GPR_TO_CC))
2262   (clobber (match_operand:SI 3 "integer_register_operand" "=&d"))]
2263  "TARGET_HAS_FPRS"
2264  "movsg ccr, %3\;and %2, %3, %3\;or %1, %3, %3\;movgs %3, ccr"
2265  [(set_attr "type" "multi")
2266   (set_attr "length" "16")])
2267
2268;; Reload CC_CCRmode for conditional execution registers
2269(define_insn "movcc_ccr"
2270  [(set (match_operand:CC_CCR 0 "move_destination_operand" "=d,d,d,m,v,?w,C,d")
2271	(match_operand:CC_CCR 1 "move_source_operand" "C,d,m,d,n,n,C,L"))]
2272  ""
2273  "@
2274   #
2275   mov %1, %0
2276   ld%I1%U1 %M1, %0
2277   st%I0%U0 %1, %M0
2278   #
2279   #
2280   orcr %1, %1, %0
2281   setlos #%1, %0"
2282  [(set_attr "length" "8,4,4,4,8,12,4,4")
2283   (set_attr "type" "multi,int,gload,gstore,multi,multi,ccr,int")])
2284
2285(define_expand "reload_incc_ccr"
2286  [(match_operand:CC_CCR 0 "cr_operand" "=C")
2287   (match_operand:CC_CCR 1 "memory_operand" "m")
2288   (match_operand:CC_CCR 2 "integer_register_operand" "=&d")]
2289  ""
2290  "
2291{
2292  rtx icc = gen_rtx_REG (CCmode, ICC_TEMP);
2293  rtx int_op2 = simplify_gen_subreg (SImode, operands[2], CC_CCRmode, 0);
2294  rtx icr = (ICR_P (REGNO (operands[0]))
2295	     ? operands[0] : gen_rtx_REG (CC_CCRmode, ICR_TEMP));
2296
2297  emit_insn (gen_movcc_ccr (operands[2], operands[1]));
2298  emit_insn (gen_cmpsi_cc (icc, int_op2, const0_rtx));
2299  emit_insn (gen_movcc_ccr (icr, gen_rtx_NE (CC_CCRmode, icc, const0_rtx)));
2300
2301  if (! ICR_P (REGNO (operands[0])))
2302    emit_insn (gen_movcc_ccr (operands[0], icr));
2303
2304  DONE;
2305}")
2306
2307(define_expand "reload_outcc_ccr"
2308  [(set (match_operand:CC_CCR 2 "integer_register_operand" "=&d")
2309	(match_operand:CC_CCR 1 "cr_operand" "C"))
2310   (set (match_operand:CC_CCR 0 "memory_operand" "=m")
2311	(match_dup 2))]
2312  ""
2313  "")
2314
2315(define_split
2316  [(set (match_operand:CC_CCR 0 "integer_register_operand" "")
2317	(match_operand:CC_CCR 1 "cr_operand" ""))]
2318  "reload_completed"
2319  [(match_dup 2)]
2320  "
2321{
2322  rtx int_op0 = simplify_gen_subreg (SImode, operands[0], CC_CCRmode, 0);
2323
2324  start_sequence ();
2325  emit_move_insn (operands[0], const1_rtx);
2326  emit_insn (gen_rtx_COND_EXEC (VOIDmode,
2327				gen_rtx_EQ (CC_CCRmode,
2328					    operands[1],
2329					    const0_rtx),
2330				gen_rtx_SET (int_op0, const0_rtx)));
2331
2332  operands[2] = get_insns ();
2333  end_sequence ();
2334}")
2335
2336(define_split
2337  [(set (match_operand:CC_CCR 0 "cr_operand" "")
2338	(match_operand:CC_CCR 1 "const_int_operand" ""))]
2339  "reload_completed"
2340  [(match_dup 2)]
2341  "
2342{
2343  rtx icc = gen_rtx_REG (CCmode, ICC_TEMP);
2344  rtx r0  = gen_rtx_REG (SImode, GPR_FIRST);
2345  rtx icr = (ICR_P (REGNO (operands[0]))
2346	     ? operands[0] : gen_rtx_REG (CC_CCRmode, ICR_TEMP));
2347
2348  start_sequence ();
2349
2350 emit_insn (gen_cmpsi_cc (icc, r0, const0_rtx));
2351
2352  emit_insn (gen_movcc_ccr (icr,
2353			    gen_rtx_fmt_ee (((INTVAL (operands[1]) == 0)
2354					     ? EQ : NE), CC_CCRmode,
2355					    r0, const0_rtx)));
2356
2357  if (! ICR_P (REGNO (operands[0])))
2358    emit_insn (gen_movcc_ccr (operands[0], icr));
2359
2360  operands[2] = get_insns ();
2361  end_sequence ();
2362}")
2363
2364
2365;; ::::::::::::::::::::
2366;; ::
2367;; :: Conversions
2368;; ::
2369;; ::::::::::::::::::::
2370
2371;; Signed conversions from a smaller integer to a larger integer
2372;;
2373;; These operations are optional.  If they are not
2374;; present GCC will synthesize them for itself
2375;; Even though frv does not provide these instructions, we define them
2376;; to allow load + sign extend to be collapsed together
2377(define_insn "extendqihi2"
2378  [(set (match_operand:HI 0 "integer_register_operand" "=d,d")
2379	(sign_extend:HI (match_operand:QI 1 "gpr_or_memory_operand" "d,m")))]
2380  ""
2381  "@
2382   #
2383   ldsb%I1%U1 %M1,%0"
2384  [(set_attr "length" "8,4")
2385   (set_attr "type" "multi,gload")])
2386
2387(define_split
2388  [(set (match_operand:HI 0 "integer_register_operand" "")
2389	(sign_extend:HI (match_operand:QI 1 "integer_register_operand" "")))]
2390  "reload_completed"
2391  [(match_dup 2)
2392   (match_dup 3)]
2393  "
2394{
2395  rtx op0   = gen_lowpart (SImode, operands[0]);
2396  rtx op1   = gen_lowpart (SImode, operands[1]);
2397  rtx shift = GEN_INT (24);
2398
2399  operands[2] = gen_ashlsi3 (op0, op1, shift);
2400  operands[3] = gen_ashrsi3 (op0, op0, shift);
2401}")
2402
2403(define_insn "extendqisi2"
2404  [(set (match_operand:SI 0 "integer_register_operand" "=d,d")
2405	(sign_extend:SI (match_operand:QI 1 "gpr_or_memory_operand" "d,m")))]
2406  ""
2407  "@
2408   #
2409   ldsb%I1%U1 %M1,%0"
2410  [(set_attr "length" "8,4")
2411   (set_attr "type" "multi,gload")])
2412
2413(define_split
2414  [(set (match_operand:SI 0 "integer_register_operand" "")
2415	(sign_extend:SI (match_operand:QI 1 "integer_register_operand" "")))]
2416  "reload_completed"
2417  [(match_dup 2)
2418   (match_dup 3)]
2419  "
2420{
2421  rtx op0   = gen_lowpart (SImode, operands[0]);
2422  rtx op1   = gen_lowpart (SImode, operands[1]);
2423  rtx shift = GEN_INT (24);
2424
2425  operands[2] = gen_ashlsi3 (op0, op1, shift);
2426  operands[3] = gen_ashrsi3 (op0, op0, shift);
2427}")
2428
2429;;(define_insn "extendqidi2"
2430;;  [(set (match_operand:DI 0 "register_operand" "=r")
2431;;	(sign_extend:DI (match_operand:QI 1 "general_operand" "g")))]
2432;;  ""
2433;;  "extendqihi2 %0,%1"
2434;;  [(set_attr "length" "4")])
2435
2436(define_insn "extendhisi2"
2437  [(set (match_operand:SI 0 "integer_register_operand" "=d,d")
2438	(sign_extend:SI (match_operand:HI 1 "gpr_or_memory_operand" "d,m")))]
2439  ""
2440  "@
2441   #
2442   ldsh%I1%U1 %M1,%0"
2443  [(set_attr "length" "8,4")
2444   (set_attr "type" "multi,gload")])
2445
2446(define_split
2447  [(set (match_operand:SI 0 "integer_register_operand" "")
2448	(sign_extend:SI (match_operand:HI 1 "integer_register_operand" "")))]
2449  "reload_completed"
2450  [(match_dup 2)
2451   (match_dup 3)]
2452  "
2453{
2454  rtx op0   = gen_lowpart (SImode, operands[0]);
2455  rtx op1   = gen_lowpart (SImode, operands[1]);
2456  rtx shift = GEN_INT (16);
2457
2458  operands[2] = gen_ashlsi3 (op0, op1, shift);
2459  operands[3] = gen_ashrsi3 (op0, op0, shift);
2460}")
2461
2462;;(define_insn "extendhidi2"
2463;;  [(set (match_operand:DI 0 "register_operand" "=r")
2464;;	(sign_extend:DI (match_operand:HI 1 "general_operand" "g")))]
2465;;  ""
2466;;  "extendhihi2 %0,%1"
2467;;  [(set_attr "length" "4")])
2468;;
2469;;(define_insn "extendsidi2"
2470;;  [(set (match_operand:DI 0 "register_operand" "=r")
2471;;	(sign_extend:DI (match_operand:SI 1 "general_operand" "g")))]
2472;;  ""
2473;;  "extendsidi2 %0,%1"
2474;;  [(set_attr "length" "4")])
2475
2476;; Unsigned conversions from a smaller integer to a larger integer
2477(define_insn "zero_extendqihi2"
2478  [(set (match_operand:HI 0 "integer_register_operand" "=d,d,d")
2479	(zero_extend:HI
2480	  (match_operand:QI 1 "gpr_or_memory_operand" "d,L,m")))]
2481  ""
2482  "@
2483   andi %1,#0xff,%0
2484   setlos %1,%0
2485   ldub%I1%U1 %M1,%0"
2486  [(set_attr "length" "4")
2487   (set_attr "type" "int,int,gload")])
2488
2489(define_insn "zero_extendqisi2"
2490  [(set (match_operand:SI 0 "integer_register_operand" "=d,d,d")
2491	(zero_extend:SI
2492	  (match_operand:QI 1 "gpr_or_memory_operand" "d,L,m")))]
2493  ""
2494  "@
2495   andi %1,#0xff,%0
2496   setlos %1,%0
2497   ldub%I1%U1 %M1,%0"
2498  [(set_attr "length" "4")
2499   (set_attr "type" "int,int,gload")])
2500
2501;;(define_insn "zero_extendqidi2"
2502;;  [(set (match_operand:DI 0 "register_operand" "=r")
2503;;	(zero_extend:DI (match_operand:QI 1 "general_operand" "g")))]
2504;;  ""
2505;;  "zero_extendqihi2 %0,%1"
2506;;  [(set_attr "length" "4")])
2507
2508;; Do not set the type for the sethi to "sethi", since the scheduler will think
2509;; the sethi takes 0 cycles as part of allowing sethi/setlo to be in the same
2510;; VLIW instruction.
2511(define_insn "zero_extendhisi2"
2512  [(set (match_operand:SI 0 "integer_register_operand" "=d,d")
2513	(zero_extend:SI (match_operand:HI 1 "gpr_or_memory_operand" "0,m")))]
2514  ""
2515  "@
2516    sethi #hi(#0),%0
2517    lduh%I1%U1 %M1,%0"
2518  [(set_attr "length" "4")
2519   (set_attr "type" "int,gload")])
2520
2521;;(define_insn "zero_extendhidi2"
2522;;  [(set (match_operand:DI 0 "register_operand" "=r")
2523;;	(zero_extend:DI (match_operand:HI 1 "general_operand" "g")))]
2524;;  ""
2525;;  "zero_extendhihi2 %0,%1"
2526;;  [(set_attr "length" "4")])
2527;;
2528;;(define_insn "zero_extendsidi2"
2529;;  [(set (match_operand:DI 0 "register_operand" "=r")
2530;;	(zero_extend:DI (match_operand:SI 1 "general_operand" "g")))]
2531;;  ""
2532;;  "zero_extendsidi2 %0,%1"
2533;;  [(set_attr "length" "4")])
2534;;
2535;;;; Convert between floating point types of different sizes.
2536;;
2537;;(define_insn "extendsfdf2"
2538;;  [(set (match_operand:DF 0 "register_operand" "=r")
2539;;	(float_extend:DF (match_operand:SF 1 "register_operand" "r")))]
2540;;  ""
2541;;  "extendsfdf2 %0,%1"
2542;;  [(set_attr "length" "4")])
2543;;
2544;;(define_insn "truncdfsf2"
2545;;  [(set (match_operand:SF 0 "register_operand" "=r")
2546;;	(float_truncate:SF (match_operand:DF 1 "register_operand" "r")))]
2547;;  ""
2548;;  "truncdfsf2 %0,%1"
2549;;  [(set_attr "length" "4")])
2550
2551;;;; Convert between signed integer types and floating point.
2552(define_insn "floatsisf2"
2553  [(set (match_operand:SF 0 "fpr_operand" "=f")
2554	(float:SF (match_operand:SI 1 "fpr_operand" "f")))]
2555  "TARGET_HARD_FLOAT"
2556  "fitos %1,%0"
2557  [(set_attr "length" "4")
2558   (set_attr "type" "fsconv")])
2559
2560(define_insn "floatsidf2"
2561  [(set (match_operand:DF 0 "fpr_operand" "=h")
2562	(float:DF (match_operand:SI 1 "fpr_operand" "f")))]
2563  "TARGET_HARD_FLOAT && TARGET_DOUBLE"
2564  "fitod %1,%0"
2565  [(set_attr "length" "4")
2566   (set_attr "type" "fdconv")])
2567
2568;;(define_insn "floatdisf2"
2569;;  [(set (match_operand:SF 0 "register_operand" "=r")
2570;;	(float:SF (match_operand:DI 1 "register_operand" "r")))]
2571;;  ""
2572;;  "floatdisf2 %0,%1"
2573;;  [(set_attr "length" "4")])
2574;;
2575;;(define_insn "floatdidf2"
2576;;  [(set (match_operand:DF 0 "register_operand" "=r")
2577;;	(float:DF (match_operand:DI 1 "register_operand" "r")))]
2578;;  ""
2579;;  "floatdidf2 %0,%1"
2580;;  [(set_attr "length" "4")])
2581
2582(define_insn "fix_truncsfsi2"
2583  [(set (match_operand:SI 0 "fpr_operand" "=f")
2584	(fix:SI (match_operand:SF 1 "fpr_operand" "f")))]
2585  "TARGET_HARD_FLOAT"
2586  "fstoi %1,%0"
2587  [(set_attr "length" "4")
2588   (set_attr "type" "fsconv")])
2589
2590(define_insn "fix_truncdfsi2"
2591  [(set (match_operand:SI 0 "fpr_operand" "=f")
2592	(fix:SI (match_operand:DF 1 "fpr_operand" "h")))]
2593  "TARGET_HARD_FLOAT && TARGET_DOUBLE"
2594  "fdtoi %1,%0"
2595  [(set_attr "length" "4")
2596   (set_attr "type" "fdconv")])
2597
2598;;(define_insn "fix_truncsfdi2"
2599;;  [(set (match_operand:DI 0 "register_operand" "=r")
2600;;	(fix:DI (match_operand:SF 1 "register_operand" "r")))]
2601;;  ""
2602;;  "fix_truncsfdi2 %0,%1"
2603;;  [(set_attr "length" "4")])
2604;;
2605;;(define_insn "fix_truncdfdi2"
2606;;  [(set (match_operand:DI 0 "register_operand" "=r")
2607;;	(fix:DI (match_operand:DF 1 "register_operand" "r")))]
2608;;  ""
2609;;  "fix_truncdfdi2 %0,%1"
2610;;  [(set_attr "length" "4")])
2611;;
2612;;;; Convert between unsigned integer types and floating point.
2613;;
2614;;(define_insn "floatunssisf2"
2615;;  [(set (match_operand:SF 0 "register_operand" "=r")
2616;;	(unsigned_float:SF (match_operand:SI 1 "register_operand" "r")))]
2617;;  ""
2618;;  "floatunssisf2 %0,%1"
2619;;  [(set_attr "length" "4")])
2620;;
2621;;(define_insn "floatunssidf2"
2622;;  [(set (match_operand:DF 0 "register_operand" "=r")
2623;;	(unsigned_float:DF (match_operand:SI 1 "register_operand" "r")))]
2624;;  ""
2625;;  "floatunssidf2 %0,%1"
2626;;  [(set_attr "length" "4")])
2627;;
2628;;(define_insn "floatunsdisf2"
2629;;  [(set (match_operand:SF 0 "register_operand" "=r")
2630;;	(unsigned_float:SF (match_operand:DI 1 "register_operand" "r")))]
2631;;  ""
2632;;  "floatunsdisf2 %0,%1"
2633;;  [(set_attr "length" "4")])
2634;;
2635;;(define_insn "floatunsdidf2"
2636;;  [(set (match_operand:DF 0 "register_operand" "=r")
2637;;	(unsigned_float:DF (match_operand:DI 1 "register_operand" "r")))]
2638;;  ""
2639;;  "floatunsdidf2 %0,%1"
2640;;  [(set_attr "length" "4")])
2641;;
2642;;(define_insn "fixuns_truncsfsi2"
2643;;  [(set (match_operand:SI 0 "register_operand" "=r")
2644;;	(unsigned_fix:SI (match_operand:SF 1 "register_operand" "r")))]
2645;;  ""
2646;;  "fixuns_truncsfsi2 %0,%1"
2647;;  [(set_attr "length" "4")])
2648;;
2649;;(define_insn "fixuns_truncdfsi2"
2650;;  [(set (match_operand:SI 0 "register_operand" "=r")
2651;;	(unsigned_fix:SI (match_operand:DF 1 "register_operand" "r")))]
2652;;  ""
2653;;  "fixuns_truncdfsi2 %0,%1"
2654;;  [(set_attr "length" "4")])
2655;;
2656;;(define_insn "fixuns_truncsfdi2"
2657;;  [(set (match_operand:DI 0 "register_operand" "=r")
2658;;	(unsigned_fix:DI (match_operand:SF 1 "register_operand" "r")))]
2659;;  ""
2660;;  "fixuns_truncsfdi2 %0,%1"
2661;;  [(set_attr "length" "4")])
2662;;
2663;;(define_insn "fixuns_truncdfdi2"
2664;;  [(set (match_operand:DI 0 "register_operand" "=r")
2665;;	(unsigned_fix:DI (match_operand:DF 1 "register_operand" "r")))]
2666;;  ""
2667;;  "fixuns_truncdfdi2 %0,%1"
2668;;  [(set_attr "length" "4")])
2669
2670
2671;; ::::::::::::::::::::
2672;; ::
2673;; :: 32-bit Integer arithmetic
2674;; ::
2675;; ::::::::::::::::::::
2676
2677;; Addition
2678(define_insn "addsi3"
2679  [(set (match_operand:SI 0 "integer_register_operand" "=d")
2680	(plus:SI (match_operand:SI 1 "integer_register_operand" "%d")
2681		 (match_operand:SI 2 "gpr_or_int12_operand" "dNOPQ")))]
2682  ""
2683  "add%I2 %1,%2,%0"
2684  [(set_attr "length" "4")
2685   (set_attr "type" "int")])
2686
2687;; Subtraction.  No need to worry about constants, since the compiler
2688;; canonicalizes them into addsi3's.  We prevent SUBREG's here to work around a
2689;; combine bug, that combines the 32x32->upper 32 bit multiply that uses a
2690;; SUBREG with a minus that shows up in modulus by constants.
2691(define_insn "subsi3"
2692  [(set (match_operand:SI 0 "integer_register_operand" "=d")
2693	(minus:SI (match_operand:SI 1 "gpr_no_subreg_operand" "d")
2694		  (match_operand:SI 2 "gpr_no_subreg_operand" "d")))]
2695  ""
2696  "sub %1,%2,%0"
2697  [(set_attr "length" "4")
2698   (set_attr "type" "int")])
2699
2700;; Signed multiplication producing 64-bit results from 32-bit inputs
2701;; Note, frv doesn't have a 32x32->32 bit multiply, but the compiler
2702;; will do the 32x32->64 bit multiply and use the bottom word.
2703(define_expand "mulsidi3"
2704  [(set (match_operand:DI 0 "integer_register_operand" "")
2705	(mult:DI (sign_extend:DI (match_operand:SI 1 "integer_register_operand" ""))
2706		 (sign_extend:DI (match_operand:SI 2 "gpr_or_int12_operand" ""))))]
2707  ""
2708  "
2709{
2710  if (GET_CODE (operands[2]) == CONST_INT)
2711    {
2712      emit_insn (gen_mulsidi3_const (operands[0], operands[1], operands[2]));
2713      DONE;
2714    }
2715}")
2716
2717(define_insn "*mulsidi3_reg"
2718  [(set (match_operand:DI 0 "even_gpr_operand" "=e")
2719	(mult:DI (sign_extend:DI (match_operand:SI 1 "integer_register_operand" "%d"))
2720		 (sign_extend:DI (match_operand:SI 2 "integer_register_operand" "d"))))]
2721  ""
2722  "smul %1,%2,%0"
2723  [(set_attr "length" "4")
2724   (set_attr "type" "mul")])
2725
2726(define_insn "mulsidi3_const"
2727  [(set (match_operand:DI 0 "even_gpr_operand" "=e")
2728	(mult:DI (sign_extend:DI (match_operand:SI 1 "integer_register_operand" "d"))
2729		 (match_operand:SI 2 "int12_operand" "NOP")))]
2730  ""
2731  "smuli %1,%2,%0"
2732  [(set_attr "length" "4")
2733   (set_attr "type" "mul")])
2734
2735;; Unsigned multiplication producing 64-bit results from 32-bit inputs
2736(define_expand "umulsidi3"
2737  [(set (match_operand:DI 0 "even_gpr_operand" "")
2738	(mult:DI (zero_extend:DI (match_operand:SI 1 "integer_register_operand" ""))
2739		 (zero_extend:DI (match_operand:SI 2 "gpr_or_int12_operand" ""))))]
2740  ""
2741  "
2742{
2743  if (GET_CODE (operands[2]) == CONST_INT)
2744    {
2745      emit_insn (gen_umulsidi3_const (operands[0], operands[1], operands[2]));
2746      DONE;
2747    }
2748}")
2749
2750(define_insn "*mulsidi3_reg"
2751  [(set (match_operand:DI 0 "even_gpr_operand" "=e")
2752	(mult:DI (zero_extend:DI (match_operand:SI 1 "integer_register_operand" "%d"))
2753		 (zero_extend:DI (match_operand:SI 2 "integer_register_operand" "d"))))]
2754  ""
2755  "umul %1,%2,%0"
2756  [(set_attr "length" "4")
2757   (set_attr "type" "mul")])
2758
2759(define_insn "umulsidi3_const"
2760  [(set (match_operand:DI 0 "even_gpr_operand" "=e")
2761	(mult:DI (zero_extend:DI (match_operand:SI 1 "integer_register_operand" "d"))
2762		 (match_operand:SI 2 "int12_operand" "NOP")))]
2763  ""
2764  "umuli %1,%2,%0"
2765  [(set_attr "length" "4")
2766   (set_attr "type" "mul")])
2767
2768;; Signed Division
2769(define_insn "divsi3"
2770  [(set (match_operand:SI 0 "register_operand" "=d,d")
2771	(div:SI (match_operand:SI 1 "register_operand" "d,d")
2772		(match_operand:SI 2 "gpr_or_int12_operand" "d,NOP")))]
2773  ""
2774  "sdiv%I2 %1,%2,%0"
2775  [(set_attr "length" "4")
2776   (set_attr "type" "div")])
2777
2778;; Unsigned Division
2779(define_insn "udivsi3"
2780  [(set (match_operand:SI 0 "register_operand" "=d,d")
2781	(udiv:SI (match_operand:SI 1 "register_operand" "d,d")
2782		 (match_operand:SI 2 "gpr_or_int12_operand" "d,NOP")))]
2783  ""
2784  "udiv%I2 %1,%2,%0"
2785  [(set_attr "length" "4")
2786   (set_attr "type" "div")])
2787
2788;; Negation
2789(define_insn "negsi2"
2790  [(set (match_operand:SI 0 "integer_register_operand" "=d")
2791	(neg:SI (match_operand:SI 1 "integer_register_operand" "d")))]
2792  ""
2793  "sub %.,%1,%0"
2794  [(set_attr "length" "4")
2795   (set_attr "type" "int")])
2796
2797;; Find first one bit
2798;; (define_insn "ffssi2"
2799;;   [(set (match_operand:SI 0 "register_operand" "=r")
2800;; 	(ffs:SI (match_operand:SI 1 "register_operand" "r")))]
2801;;   ""
2802;;   "ffssi2 %0,%1"
2803;;   [(set_attr "length" "4")])
2804
2805
2806;; ::::::::::::::::::::
2807;; ::
2808;; :: 64-bit Integer arithmetic
2809;; ::
2810;; ::::::::::::::::::::
2811
2812;; Addition
2813(define_insn_and_split "adddi3"
2814  [(set (match_operand:DI 0 "integer_register_operand" "=&e,e")
2815	(plus:DI (match_operand:DI 1 "integer_register_operand" "%e,0")
2816		 (match_operand:DI 2 "gpr_or_int10_operand" "eJ,eJ")))
2817   (clobber (match_scratch:CC 3 "=t,t"))]
2818  ""
2819  "#"
2820  "reload_completed"
2821  [(match_dup 4)
2822   (match_dup 5)]
2823  "
2824{
2825  rtx parts[3][2];
2826  int op, part;
2827
2828  for (op = 0; op < 3; op++)
2829    for (part = 0; part < 2; part++)
2830      parts[op][part] = simplify_gen_subreg (SImode, operands[op],
2831					     DImode, part * UNITS_PER_WORD);
2832
2833  operands[4] = gen_adddi3_lower (parts[0][1], parts[1][1], parts[2][1],
2834				  operands[3]);
2835  operands[5] = gen_adddi3_upper (parts[0][0], parts[1][0], parts[2][0],
2836				  copy_rtx (operands[3]));
2837}"
2838  [(set_attr "length" "8")
2839   (set_attr "type" "multi")])
2840
2841;; Subtraction  No need to worry about constants, since the compiler
2842;; canonicalizes them into adddi3's.
2843(define_insn_and_split "subdi3"
2844  [(set (match_operand:DI 0 "integer_register_operand" "=&e,e,e")
2845	(minus:DI (match_operand:DI 1 "integer_register_operand" "e,0,e")
2846		  (match_operand:DI 2 "integer_register_operand" "e,e,0")))
2847   (clobber (match_scratch:CC 3 "=t,t,t"))]
2848  ""
2849  "#"
2850  "reload_completed"
2851  [(match_dup 4)
2852   (match_dup 5)]
2853  "
2854{
2855  rtx op0_high = gen_highpart (SImode, operands[0]);
2856  rtx op1_high = gen_highpart (SImode, operands[1]);
2857  rtx op2_high = gen_highpart (SImode, operands[2]);
2858  rtx op0_low  = gen_lowpart (SImode, operands[0]);
2859  rtx op1_low  = gen_lowpart (SImode, operands[1]);
2860  rtx op2_low  = gen_lowpart (SImode, operands[2]);
2861  rtx op3 = operands[3];
2862
2863  operands[4] = gen_subdi3_lower (op0_low, op1_low, op2_low, op3);
2864  operands[5] = gen_subdi3_upper (op0_high, op1_high, op2_high, op3);
2865}"
2866  [(set_attr "length" "8")
2867   (set_attr "type" "multi")])
2868
2869;; Patterns for addsi3/subdi3 after splitting
2870(define_insn "adddi3_lower"
2871  [(set (match_operand:SI 0 "integer_register_operand" "=d")
2872	(plus:SI (match_operand:SI 1 "integer_register_operand" "d")
2873		 (match_operand:SI 2 "gpr_or_int10_operand" "dJ")))
2874   (set (match_operand:CC 3 "icc_operand" "=t")
2875	(compare:CC (plus:SI (match_dup 1)
2876			     (match_dup 2))
2877		    (const_int 0)))]
2878  ""
2879  "add%I2cc %1,%2,%0,%3"
2880  [(set_attr "length" "4")
2881   (set_attr "type" "int")])
2882
2883(define_insn "adddi3_upper"
2884  [(set (match_operand:SI 0 "integer_register_operand" "=d")
2885	(plus:SI (match_operand:SI 1 "integer_register_operand" "d")
2886		 (plus:SI (match_operand:SI 2 "gpr_or_int10_operand" "dJ")
2887			  (match_operand:CC 3 "icc_operand" "t"))))]
2888  ""
2889  "addx%I2 %1,%2,%0,%3"
2890  [(set_attr "length" "4")
2891   (set_attr "type" "int")])
2892
2893(define_insn "subdi3_lower"
2894  [(set (match_operand:SI 0 "integer_register_operand" "=d")
2895	(minus:SI (match_operand:SI 1 "integer_register_operand" "d")
2896		  (match_operand:SI 2 "integer_register_operand" "d")))
2897   (set (match_operand:CC 3 "icc_operand" "=t")
2898	(compare:CC (plus:SI (match_dup 1)
2899			     (match_dup 2))
2900		    (const_int 0)))]
2901  ""
2902  "subcc %1,%2,%0,%3"
2903  [(set_attr "length" "4")
2904   (set_attr "type" "int")])
2905
2906(define_insn "subdi3_upper"
2907  [(set (match_operand:SI 0 "integer_register_operand" "=d")
2908	(minus:SI (match_operand:SI 1 "integer_register_operand" "d")
2909		  (minus:SI (match_operand:SI 2 "integer_register_operand" "d")
2910			    (match_operand:CC 3 "icc_operand" "t"))))]
2911  ""
2912  "subx %1,%2,%0,%3"
2913  [(set_attr "length" "4")
2914   (set_attr "type" "int")])
2915
2916(define_insn_and_split "negdi2"
2917  [(set (match_operand:DI 0 "integer_register_operand" "=&e,e")
2918	(neg:DI (match_operand:DI 1 "integer_register_operand" "e,0")))
2919   (clobber (match_scratch:CC 2 "=t,t"))]
2920  ""
2921  "#"
2922  "reload_completed"
2923  [(match_dup 3)
2924   (match_dup 4)]
2925  "
2926{
2927  rtx op0_high = gen_highpart (SImode, operands[0]);
2928  rtx op1_high = gen_rtx_REG (SImode, GPR_FIRST);
2929  rtx op2_high = gen_highpart (SImode, operands[1]);
2930  rtx op0_low  = gen_lowpart (SImode, operands[0]);
2931  rtx op1_low  = op1_high;
2932  rtx op2_low  = gen_lowpart (SImode, operands[1]);
2933  rtx op3 = operands[2];
2934
2935  operands[3] = gen_subdi3_lower (op0_low, op1_low, op2_low, op3);
2936  operands[4] = gen_subdi3_upper (op0_high, op1_high, op2_high, op3);
2937}"
2938  [(set_attr "length" "8")
2939   (set_attr "type" "multi")])
2940
2941;; Multiplication (same size)
2942;; (define_insn "muldi3"
2943;;   [(set (match_operand:DI 0 "register_operand" "=r")
2944;; 	(mult:DI (match_operand:DI 1 "register_operand" "%r")
2945;; 		 (match_operand:DI 2 "nonmemory_operand" "ri")))]
2946;;   ""
2947;;   "muldi3 %0,%1,%2"
2948;;   [(set_attr "length" "4")])
2949
2950;; Signed Division
2951;; (define_insn "divdi3"
2952;;   [(set (match_operand:DI 0 "register_operand" "=r")
2953;; 	(div:DI (match_operand:DI 1 "register_operand" "r")
2954;; 		(match_operand:DI 2 "nonmemory_operand" "ri")))]
2955;;   ""
2956;;   "divdi3 %0,%1,%2"
2957;;   [(set_attr "length" "4")])
2958
2959;; Undsgned Division
2960;; (define_insn "udivdi3"
2961;;   [(set (match_operand:DI 0 "register_operand" "=r")
2962;; 	(udiv:DI (match_operand:DI 1 "register_operand" "r")
2963;; 		 (match_operand:DI 2 "nonmemory_operand" "ri")))]
2964;;   ""
2965;;   "udivdi3 %0,%1,%2"
2966;;   [(set_attr "length" "4")])
2967
2968;; Negation
2969;; (define_insn "negdi2"
2970;;   [(set (match_operand:DI 0 "register_operand" "=r")
2971;; 	(neg:DI (match_operand:DI 1 "register_operand" "r")))]
2972;;   ""
2973;;   "negdi2 %0,%1"
2974;;   [(set_attr "length" "4")])
2975
2976;; Find first one bit
2977;; (define_insn "ffsdi2"
2978;;   [(set (match_operand:DI 0 "register_operand" "=r")
2979;; 	(ffs:DI (match_operand:DI 1 "register_operand" "r")))]
2980;;   ""
2981;;   "ffsdi2 %0,%1"
2982;;   [(set_attr "length" "4")])
2983
2984
2985;; ::::::::::::::::::::
2986;; ::
2987;; :: 32-bit floating point arithmetic
2988;; ::
2989;; ::::::::::::::::::::
2990
2991;; Addition
2992(define_insn "addsf3"
2993  [(set (match_operand:SF 0 "fpr_operand" "=f")
2994	(plus:SF (match_operand:SF 1 "fpr_operand" "%f")
2995		 (match_operand:SF 2 "fpr_operand" "f")))]
2996  "TARGET_HARD_FLOAT"
2997  "fadds %1,%2,%0"
2998  [(set_attr "length" "4")
2999   (set_attr "type" "fsadd")])
3000
3001;; Subtraction
3002(define_insn "subsf3"
3003  [(set (match_operand:SF 0 "fpr_operand" "=f")
3004	(minus:SF (match_operand:SF 1 "fpr_operand" "f")
3005		  (match_operand:SF 2 "fpr_operand" "f")))]
3006  "TARGET_HARD_FLOAT"
3007  "fsubs %1,%2,%0"
3008  [(set_attr "length" "4")
3009   (set_attr "type" "fsadd")])
3010
3011;; Multiplication
3012(define_insn "mulsf3"
3013  [(set (match_operand:SF 0 "fpr_operand" "=f")
3014	(mult:SF (match_operand:SF 1 "fpr_operand" "%f")
3015		 (match_operand:SF 2 "fpr_operand" "f")))]
3016  "TARGET_HARD_FLOAT"
3017  "fmuls %1,%2,%0"
3018  [(set_attr "length" "4")
3019   (set_attr "type" "fsmul")])
3020
3021;; Multiplication with addition/subtraction
3022(define_insn "fmasf4"
3023  [(set (match_operand:SF 0 "fpr_operand" "=f")
3024	(fma:SF (match_operand:SF 1 "fpr_operand" "f")
3025		(match_operand:SF 2 "fpr_operand" "f")
3026		(match_operand:SF 3 "fpr_operand" "0")))]
3027  "TARGET_HARD_FLOAT && TARGET_MULADD"
3028  "fmadds %1,%2,%0"
3029  [(set_attr "length" "4")
3030   (set_attr "type" "fsmadd")])
3031
3032(define_insn "fmssf4"
3033  [(set (match_operand:SF 0 "fpr_operand" "=f")
3034	(fma:SF (match_operand:SF 1 "fpr_operand" "f")
3035		(match_operand:SF 2 "fpr_operand" "f")
3036		(neg:SF (match_operand:SF 3 "fpr_operand" "0"))))]
3037  "TARGET_HARD_FLOAT && TARGET_MULADD"
3038  "fmsubs %1,%2,%0"
3039  [(set_attr "length" "4")
3040   (set_attr "type" "fsmadd")])
3041
3042;; Division
3043(define_insn "divsf3"
3044  [(set (match_operand:SF 0 "fpr_operand" "=f")
3045	(div:SF (match_operand:SF 1 "fpr_operand" "f")
3046		(match_operand:SF 2 "fpr_operand" "f")))]
3047  "TARGET_HARD_FLOAT"
3048  "fdivs %1,%2,%0"
3049  [(set_attr "length" "4")
3050   (set_attr "type" "fsdiv")])
3051
3052;; Negation
3053(define_insn "negsf2"
3054  [(set (match_operand:SF 0 "fpr_operand" "=f")
3055	(neg:SF (match_operand:SF 1 "fpr_operand" "f")))]
3056  "TARGET_HARD_FLOAT"
3057  "fnegs %1,%0"
3058  [(set_attr "length" "4")
3059   (set_attr "type" "fsconv")])
3060
3061;; Absolute value
3062(define_insn "abssf2"
3063  [(set (match_operand:SF 0 "fpr_operand" "=f")
3064	(abs:SF (match_operand:SF 1 "fpr_operand" "f")))]
3065  "TARGET_HARD_FLOAT"
3066  "fabss %1,%0"
3067  [(set_attr "length" "4")
3068   (set_attr "type" "fsconv")])
3069
3070;; Square root
3071(define_insn "sqrtsf2"
3072  [(set (match_operand:SF 0 "fpr_operand" "=f")
3073	(sqrt:SF (match_operand:SF 1 "fpr_operand" "f")))]
3074  "TARGET_HARD_FLOAT"
3075  "fsqrts %1,%0"
3076  [(set_attr "length" "4")
3077   (set_attr "type" "sqrt_single")])
3078
3079
3080;; ::::::::::::::::::::
3081;; ::
3082;; :: 64-bit floating point arithmetic
3083;; ::
3084;; ::::::::::::::::::::
3085
3086;; Addition
3087(define_insn "adddf3"
3088  [(set (match_operand:DF 0 "even_fpr_operand" "=h")
3089	(plus:DF (match_operand:DF 1 "fpr_operand" "%h")
3090		 (match_operand:DF 2 "fpr_operand" "h")))]
3091  "TARGET_HARD_FLOAT && TARGET_DOUBLE"
3092  "faddd %1,%2,%0"
3093  [(set_attr "length" "4")
3094   (set_attr "type" "fdadd")])
3095
3096;; Subtraction
3097(define_insn "subdf3"
3098  [(set (match_operand:DF 0 "even_fpr_operand" "=h")
3099	(minus:DF (match_operand:DF 1 "fpr_operand" "h")
3100		  (match_operand:DF 2 "fpr_operand" "h")))]
3101  "TARGET_HARD_FLOAT && TARGET_DOUBLE"
3102  "fsubd %1,%2,%0"
3103  [(set_attr "length" "4")
3104   (set_attr "type" "fdadd")])
3105
3106;; Multiplication
3107(define_insn "muldf3"
3108  [(set (match_operand:DF 0 "even_fpr_operand" "=h")
3109	(mult:DF (match_operand:DF 1 "fpr_operand" "%h")
3110		 (match_operand:DF 2 "fpr_operand" "h")))]
3111  "TARGET_HARD_FLOAT && TARGET_DOUBLE"
3112  "fmuld %1,%2,%0"
3113  [(set_attr "length" "4")
3114   (set_attr "type" "fdmul")])
3115
3116;; Multiplication with addition/subtraction
3117(define_insn "*muladddf4"
3118  [(set (match_operand:DF 0 "fpr_operand" "=f")
3119	(plus:DF (mult:DF (match_operand:DF 1 "fpr_operand" "%f")
3120			  (match_operand:DF 2 "fpr_operand" "f"))
3121		 (match_operand:DF 3 "fpr_operand" "0")))]
3122  "TARGET_HARD_FLOAT && TARGET_DOUBLE && TARGET_MULADD"
3123  "fmaddd %1,%2,%0"
3124  [(set_attr "length" "4")
3125   (set_attr "type" "fdmadd")])
3126
3127(define_insn "*mulsubdf4"
3128  [(set (match_operand:DF 0 "fpr_operand" "=f")
3129	(minus:DF (mult:DF (match_operand:DF 1 "fpr_operand" "%f")
3130			   (match_operand:DF 2 "fpr_operand" "f"))
3131		  (match_operand:DF 3 "fpr_operand" "0")))]
3132  "TARGET_HARD_FLOAT && TARGET_DOUBLE && TARGET_MULADD"
3133  "fmsubd %1,%2,%0"
3134  [(set_attr "length" "4")
3135   (set_attr "type" "fdmadd")])
3136
3137;; Division
3138(define_insn "divdf3"
3139  [(set (match_operand:DF 0 "even_fpr_operand" "=h")
3140	(div:DF (match_operand:DF 1 "fpr_operand" "h")
3141		(match_operand:DF 2 "fpr_operand" "h")))]
3142  "TARGET_HARD_FLOAT && TARGET_DOUBLE"
3143  "fdivd %1,%2,%0"
3144  [(set_attr "length" "4")
3145   (set_attr "type" "fddiv")])
3146
3147;; Negation
3148(define_insn "negdf2"
3149  [(set (match_operand:DF 0 "even_fpr_operand" "=h")
3150	(neg:DF (match_operand:DF 1 "fpr_operand" "h")))]
3151  "TARGET_HARD_FLOAT && TARGET_DOUBLE"
3152  "fnegd %1,%0"
3153  [(set_attr "length" "4")
3154   (set_attr "type" "fdconv")])
3155
3156;; Absolute value
3157(define_insn "absdf2"
3158  [(set (match_operand:DF 0 "even_fpr_operand" "=h")
3159	(abs:DF (match_operand:DF 1 "fpr_operand" "h")))]
3160  "TARGET_HARD_FLOAT && TARGET_DOUBLE"
3161  "fabsd %1,%0"
3162  [(set_attr "length" "4")
3163   (set_attr "type" "fdconv")])
3164
3165;; Square root
3166(define_insn "sqrtdf2"
3167  [(set (match_operand:DF 0 "even_fpr_operand" "=h")
3168	(sqrt:DF (match_operand:DF 1 "fpr_operand" "h")))]
3169  "TARGET_HARD_FLOAT && TARGET_DOUBLE"
3170  "fsqrtd %1,%0"
3171  [(set_attr "length" "4")
3172   (set_attr "type" "sqrt_double")])
3173
3174
3175;; ::::::::::::::::::::
3176;; ::
3177;; :: 32-bit Integer Shifts and Rotates
3178;; ::
3179;; ::::::::::::::::::::
3180
3181;; Arithmetic Shift Left
3182(define_insn "ashlsi3"
3183  [(set (match_operand:SI 0 "integer_register_operand" "=d,d")
3184	(ashift:SI (match_operand:SI 1 "integer_register_operand" "d,d")
3185		   (match_operand:SI 2 "gpr_or_int12_operand" "d,NOP")))]
3186  ""
3187  "sll%I2 %1,%2,%0"
3188  [(set_attr "length" "4")
3189   (set_attr "type" "int")])
3190
3191;; Arithmetic Shift Right
3192(define_insn "ashrsi3"
3193  [(set (match_operand:SI 0 "integer_register_operand" "=d,d")
3194	(ashiftrt:SI (match_operand:SI 1 "integer_register_operand" "d,d")
3195		     (match_operand:SI 2 "gpr_or_int12_operand" "d,NOP")))]
3196  ""
3197  "sra%I2 %1, %2, %0"
3198  [(set_attr "length" "4")
3199   (set_attr "type" "int")])
3200
3201;; Logical Shift Right
3202(define_insn "lshrsi3"
3203  [(set (match_operand:SI 0 "integer_register_operand" "=d,d")
3204	(lshiftrt:SI (match_operand:SI 1 "integer_register_operand" "d,d")
3205		     (match_operand:SI 2 "gpr_or_int12_operand" "d,NOP")))]
3206  ""
3207  "srl%I2 %1, %2, %0"
3208  [(set_attr "length" "4")
3209   (set_attr "type" "int")])
3210
3211;; Rotate Left
3212;; (define_insn "rotlsi3"
3213;;   [(set (match_operand:SI 0 "register_operand" "=r")
3214;; 	(rotate:SI (match_operand:SI 1 "register_operand" "r")
3215;; 		   (match_operand:SI 2 "nonmemory_operand" "ri")))]
3216;;   ""
3217;;   "rotlsi3 %0,%1,%2"
3218;;   [(set_attr "length" "4")])
3219
3220;; Rotate Right
3221;; (define_insn "rotrsi3"
3222;;   [(set (match_operand:SI 0 "register_operand" "=r")
3223;; 	(rotatert:SI (match_operand:SI 1 "register_operand" "r")
3224;; 		     (match_operand:SI 2 "nonmemory_operand" "ri")))]
3225;;   ""
3226;;   "rotrsi3 %0,%1,%2"
3227;;   [(set_attr "length" "4")])
3228
3229
3230;; ::::::::::::::::::::
3231;; ::
3232;; :: 64-bit Integer Shifts and Rotates
3233;; ::
3234;; ::::::::::::::::::::
3235
3236;; Arithmetic Shift Left
3237;; (define_insn "ashldi3"
3238;;   [(set (match_operand:DI 0 "register_operand" "=r")
3239;; 	(ashift:DI (match_operand:DI 1 "register_operand" "r")
3240;; 		   (match_operand:SI 2 "nonmemory_operand" "ri")))]
3241;;   ""
3242;;   "ashldi3 %0,%1,%2"
3243;;   [(set_attr "length" "4")])
3244
3245;; Arithmetic Shift Right
3246;; (define_insn "ashrdi3"
3247;;   [(set (match_operand:DI 0 "register_operand" "=r")
3248;; 	(ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
3249;; 		     (match_operand:SI 2 "nonmemory_operand" "ri")))]
3250;;   ""
3251;;   "ashrdi3 %0,%1,%2"
3252;;   [(set_attr "length" "4")])
3253
3254;; Logical Shift Right
3255;; (define_insn "lshrdi3"
3256;;   [(set (match_operand:DI 0 "register_operand" "=r")
3257;; 	(lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
3258;; 		     (match_operand:SI 2 "nonmemory_operand" "ri")))]
3259;;   ""
3260;;   "lshrdi3 %0,%1,%2"
3261;;   [(set_attr "length" "4")])
3262
3263;; Rotate Left
3264;; (define_insn "rotldi3"
3265;;   [(set (match_operand:DI 0 "register_operand" "=r")
3266;; 	(rotate:DI (match_operand:DI 1 "register_operand" "r")
3267;; 		   (match_operand:SI 2 "nonmemory_operand" "ri")))]
3268;;   ""
3269;;   "rotldi3 %0,%1,%2"
3270;;   [(set_attr "length" "4")])
3271
3272;; Rotate Right
3273;; (define_insn "rotrdi3"
3274;;   [(set (match_operand:DI 0 "register_operand" "=r")
3275;; 	(rotatert:DI (match_operand:DI 1 "register_operand" "r")
3276;; 		     (match_operand:SI 2 "nonmemory_operand" "ri")))]
3277;;   ""
3278;;   "rotrdi3 %0,%1,%2"
3279;;   [(set_attr "length" "4")])
3280
3281
3282;; ::::::::::::::::::::
3283;; ::
3284;; :: 32-Bit Integer Logical operations
3285;; ::
3286;; ::::::::::::::::::::
3287
3288;; Logical AND, 32-bit integers
3289(define_insn "andsi3_media"
3290  [(set (match_operand:SI 0 "gpr_or_fpr_operand" "=d,f")
3291	(and:SI (match_operand:SI 1 "gpr_or_fpr_operand" "%d,f")
3292		(match_operand:SI 2 "gpr_fpr_or_int12_operand" "dNOP,f")))]
3293  "TARGET_MEDIA"
3294  "@
3295   and%I2 %1, %2, %0
3296   mand %1, %2, %0"
3297  [(set_attr "length" "4")
3298   (set_attr "type" "int,mlogic")])
3299
3300(define_insn "andsi3_nomedia"
3301  [(set (match_operand:SI 0 "integer_register_operand" "=d")
3302	(and:SI (match_operand:SI 1 "integer_register_operand" "%d")
3303		(match_operand:SI 2 "gpr_or_int12_operand" "dNOP")))]
3304  "!TARGET_MEDIA"
3305  "and%I2 %1, %2, %0"
3306  [(set_attr "length" "4")
3307   (set_attr "type" "int")])
3308
3309(define_expand "andsi3"
3310  [(set (match_operand:SI 0 "gpr_or_fpr_operand" "")
3311	(and:SI (match_operand:SI 1 "gpr_or_fpr_operand" "")
3312		(match_operand:SI 2 "gpr_fpr_or_int12_operand" "")))]
3313  ""
3314  "")
3315
3316;; Inclusive OR, 32-bit integers
3317(define_insn "iorsi3_media"
3318  [(set (match_operand:SI 0 "gpr_or_fpr_operand" "=d,f")
3319	(ior:SI (match_operand:SI 1 "gpr_or_fpr_operand" "%d,f")
3320		(match_operand:SI 2 "gpr_fpr_or_int12_operand" "dNOP,f")))]
3321  "TARGET_MEDIA"
3322  "@
3323   or%I2 %1, %2, %0
3324   mor %1, %2, %0"
3325  [(set_attr "length" "4")
3326   (set_attr "type" "int,mlogic")])
3327
3328(define_insn "iorsi3_nomedia"
3329  [(set (match_operand:SI 0 "integer_register_operand" "=d")
3330	(ior:SI (match_operand:SI 1 "integer_register_operand" "%d")
3331		(match_operand:SI 2 "gpr_or_int12_operand" "dNOP")))]
3332  "!TARGET_MEDIA"
3333  "or%I2 %1, %2, %0"
3334  [(set_attr "length" "4")
3335   (set_attr "type" "int")])
3336
3337(define_expand "iorsi3"
3338  [(set (match_operand:SI 0 "gpr_or_fpr_operand" "")
3339	(ior:SI (match_operand:SI 1 "gpr_or_fpr_operand" "")
3340		(match_operand:SI 2 "gpr_fpr_or_int12_operand" "")))]
3341  ""
3342  "")
3343
3344;; Exclusive OR, 32-bit integers
3345(define_insn "xorsi3_media"
3346  [(set (match_operand:SI 0 "gpr_or_fpr_operand" "=d,f")
3347	(xor:SI (match_operand:SI 1 "gpr_or_fpr_operand" "%d,f")
3348		(match_operand:SI 2 "gpr_fpr_or_int12_operand" "dNOP,f")))]
3349  "TARGET_MEDIA"
3350  "@
3351   xor%I2 %1, %2, %0
3352   mxor %1, %2, %0"
3353  [(set_attr "length" "4")
3354   (set_attr "type" "int,mlogic")])
3355
3356(define_insn "xorsi3_nomedia"
3357  [(set (match_operand:SI 0 "integer_register_operand" "=d")
3358	(xor:SI (match_operand:SI 1 "integer_register_operand" "%d")
3359		(match_operand:SI 2 "gpr_or_int12_operand" "dNOP")))]
3360  "!TARGET_MEDIA"
3361  "xor%I2 %1, %2, %0"
3362  [(set_attr "length" "4")
3363   (set_attr "type" "int")])
3364
3365(define_expand "xorsi3"
3366  [(set (match_operand:SI 0 "gpr_or_fpr_operand" "")
3367	(xor:SI (match_operand:SI 1 "gpr_or_fpr_operand" "")
3368		(match_operand:SI 2 "gpr_fpr_or_int12_operand" "")))]
3369  ""
3370  "")
3371
3372;; One's complement, 32-bit integers
3373(define_insn "one_cmplsi2_media"
3374  [(set (match_operand:SI 0 "gpr_or_fpr_operand" "=d,f")
3375	(not:SI (match_operand:SI 1 "gpr_or_fpr_operand" "d,f")))]
3376  "TARGET_MEDIA"
3377  "@
3378   not %1, %0
3379   mnot %1, %0"
3380  [(set_attr "length" "4")
3381   (set_attr "type" "int,mlogic")])
3382
3383(define_insn "one_cmplsi2_nomedia"
3384  [(set (match_operand:SI 0 "integer_register_operand" "=d")
3385	(not:SI (match_operand:SI 1 "integer_register_operand" "d")))]
3386  "!TARGET_MEDIA"
3387  "not %1,%0"
3388  [(set_attr "length" "4")
3389   (set_attr "type" "int")])
3390
3391(define_expand "one_cmplsi2"
3392  [(set (match_operand:SI 0 "gpr_or_fpr_operand" "")
3393	(not:SI (match_operand:SI 1 "gpr_or_fpr_operand" "")))]
3394  ""
3395  "")
3396
3397
3398;; ::::::::::::::::::::
3399;; ::
3400;; :: 64-Bit Integer Logical operations
3401;; ::
3402;; ::::::::::::::::::::
3403
3404;; Logical AND, 64-bit integers
3405;; (define_insn "anddi3"
3406;;   [(set (match_operand:DI 0 "register_operand" "=r")
3407;; 	(and:DI (match_operand:DI 1 "register_operand" "%r")
3408;; 		(match_operand:DI 2 "nonmemory_operand" "ri")))]
3409;;   ""
3410;;   "anddi3 %0,%1,%2"
3411;;   [(set_attr "length" "4")])
3412
3413;; Inclusive OR, 64-bit integers
3414;; (define_insn "iordi3"
3415;;   [(set (match_operand:DI 0 "register_operand" "=r")
3416;; 	(ior:DI (match_operand:DI 1 "register_operand" "%r")
3417;; 		(match_operand:DI 2 "nonmemory_operand" "ri")))]
3418;;   ""
3419;;   "iordi3 %0,%1,%2"
3420;;   [(set_attr "length" "4")])
3421
3422;; Exclusive OR, 64-bit integers
3423;; (define_insn "xordi3"
3424;;   [(set (match_operand:DI 0 "register_operand" "=r")
3425;; 	(xor:DI (match_operand:DI 1 "register_operand" "%r")
3426;; 		(match_operand:DI 2 "nonmemory_operand" "ri")))]
3427;;   ""
3428;;   "xordi3 %0,%1,%2"
3429;;   [(set_attr "length" "4")])
3430
3431;; One's complement, 64-bit integers
3432;; (define_insn "one_cmpldi2"
3433;;   [(set (match_operand:DI 0 "register_operand" "=r")
3434;; 	(not:DI (match_operand:DI 1 "register_operand" "r")))]
3435;;   ""
3436;;   "notdi3 %0,%1"
3437;;   [(set_attr "length" "4")])
3438
3439
3440;; ::::::::::::::::::::
3441;; ::
3442;; :: Combination of integer operation with comparison
3443;; ::
3444;; ::::::::::::::::::::
3445
3446(define_insn "*combo_intop_compare1"
3447  [(set (match_operand:CC_NZ 0 "icc_operand" "=t")
3448	(compare:CC_NZ
3449	 (match_operator:SI 1 "intop_compare_operator"
3450		       [(match_operand:SI 2 "integer_register_operand" "d")
3451			(match_operand:SI 3 "gpr_or_int10_operand" "dJ")])
3452	 (const_int 0)))]
3453  ""
3454  "%O1%I3cc %2, %3, %., %0"
3455  [(set_attr "type" "int")
3456   (set_attr "length" "4")])
3457
3458(define_insn "*combo_intop_compare2"
3459  [(set (match_operand:CC_NZ 0 "icc_operand" "=t")
3460	(compare:CC_NZ
3461	 (match_operator:SI 1 "intop_compare_operator"
3462			[(match_operand:SI 2 "integer_register_operand" "d")
3463			 (match_operand:SI 3 "gpr_or_int10_operand" "dJ")])
3464	 (const_int 0)))
3465   (set (match_operand:SI 4 "integer_register_operand" "=d")
3466	(match_operator:SI 5 "intop_compare_operator"
3467			   [(match_dup 2)
3468			    (match_dup 3)]))]
3469  "GET_CODE (operands[1]) == GET_CODE (operands[5])"
3470  "%O1%I3cc %2, %3, %4, %0"
3471  [(set_attr "type" "int")
3472   (set_attr "length" "4")])
3473
3474;; ::::::::::::::::::::
3475;; ::
3476;; :: Comparisons
3477;; ::
3478;; ::::::::::::::::::::
3479
3480;; The comparisons are generated by the branch and/or scc operations
3481
3482(define_insn "cmpsi_cc"
3483  [(set (match_operand:CC 0 "icc_operand" "=t,t")
3484	(compare:CC (match_operand:SI 1 "integer_register_operand" "d,d")
3485		    (match_operand:SI 2 "gpr_or_int10_operand" "d,J")))]
3486  ""
3487  "cmp%I2 %1,%2,%0"
3488  [(set_attr "length" "4")
3489   (set_attr "type" "int")])
3490
3491(define_insn "*cmpsi_cc_uns"
3492  [(set (match_operand:CC_UNS 0 "icc_operand" "=t,t")
3493	(compare:CC_UNS (match_operand:SI 1 "integer_register_operand" "d,d")
3494			(match_operand:SI 2 "gpr_or_int10_operand" "d,J")))]
3495  ""
3496  "cmp%I2 %1,%2,%0"
3497  [(set_attr "length" "4")
3498   (set_attr "type" "int")])
3499
3500;; The only requirement for a CC_NZmode GPR or memory value is that
3501;; comparing it against zero must set the Z and N flags appropriately.
3502;; The source operand is therefore a valid CC_NZmode value.
3503(define_insn "*cmpsi_cc_nz"
3504  [(set (match_operand:CC_NZ 0 "nonimmediate_operand" "=t,d,m")
3505	(compare:CC_NZ (match_operand:SI 1 "integer_register_operand" "d,d,d")
3506		       (const_int 0)))]
3507  ""
3508  "@
3509   cmpi %1, #0, %0
3510   mov %1, %0
3511   st%I0%U0 %1, %M0"
3512  [(set_attr "length" "4,4,4")
3513   (set_attr "type" "int,int,gstore")])
3514
3515(define_insn "*cmpsf_cc_fp"
3516  [(set (match_operand:CC_FP 0 "fcc_operand" "=u")
3517	(compare:CC_FP (match_operand:SF 1 "fpr_operand" "f")
3518		       (match_operand:SF 2 "fpr_operand" "f")))]
3519  "TARGET_HARD_FLOAT"
3520  "fcmps %1,%2,%0"
3521  [(set_attr "length" "4")
3522   (set_attr "type" "fscmp")])
3523
3524(define_insn "*cmpdf_cc_fp"
3525  [(set (match_operand:CC_FP 0 "fcc_operand" "=u")
3526	(compare:CC_FP (match_operand:DF 1 "even_fpr_operand" "h")
3527		       (match_operand:DF 2 "even_fpr_operand" "h")))]
3528  "TARGET_HARD_FLOAT && TARGET_DOUBLE"
3529  "fcmpd %1,%2,%0"
3530  [(set_attr "length" "4")
3531   (set_attr "type" "fdcmp")])
3532
3533
3534;; ::::::::::::::::::::
3535;; ::
3536;; :: Branches
3537;; ::
3538;; ::::::::::::::::::::
3539
3540;; Define_expands called by the machine independent part of the compiler
3541;; to allocate a new comparison register.
3542
3543(define_expand "cbranchdf4"
3544  [(use (match_operator 0 "ordered_comparison_operator"
3545         [(match_operand:DF 1 "fpr_operand" "")
3546          (match_operand:DF 2 "fpr_operand" "")]))
3547   (use (match_operand 3 ""))]
3548  "TARGET_HARD_FLOAT && TARGET_DOUBLE"
3549  { if (frv_emit_cond_branch (operands)) DONE; gcc_unreachable (); })
3550
3551(define_expand "cbranchsf4"
3552  [(use (match_operator 0 "ordered_comparison_operator"
3553         [(match_operand:SF 1 "fpr_operand" "")
3554          (match_operand:SF 2 "fpr_operand" "")]))
3555   (use (match_operand 3 ""))]
3556  "TARGET_HARD_FLOAT"
3557  { if (frv_emit_cond_branch (operands)) DONE; gcc_unreachable (); })
3558
3559(define_expand "cbranchsi4"
3560  [(use (match_operator 0 "ordered_comparison_operator"
3561         [(match_operand:SI 1 "integer_register_operand" "")
3562          (match_operand:SI 2 "gpr_or_int10_operand" "")]))
3563   (use (match_operand 3 ""))]
3564  ""
3565  { if (frv_emit_cond_branch (operands)) DONE; gcc_unreachable (); })
3566
3567;; Actual branches.  We must allow for the (label_ref) and the (pc) to be
3568;; swapped.  If they are swapped, it reverses the sense of the branch.
3569;;
3570;; Note - unlike the define expands above, these patterns can be amalgamated
3571;; into one pattern for branch-if-true and one for branch-if-false.  This does
3572;; require an operand operator to select the correct branch mnemonic.
3573;;
3574;; If a fixed condition code register is being used, (as opposed to, say,
3575;; using cc0), then the expands could look like this:
3576;;
3577;; (define_insn "*branch_true"
3578;;   [(set (pc)
3579;; 	(if_then_else (match_operator:CC 0 "comparison_operator"
3580;; 					 [(reg:CC <number_of_CC_register>)
3581;; 					  (const_int 0)])
3582;; 		      (label_ref (match_operand 1 "" ""))
3583;; 		      (pc)))]
3584;;   ""
3585;;   "b%B0 %1"
3586;;   [(set_attr "length" "4")]
3587;; )
3588;;
3589;; In the above example the %B is a directive to frv_print_operand()
3590;; to decode and print the correct branch mnemonic.
3591
3592(define_insn "*branch_int_true"
3593  [(set (pc)
3594	(if_then_else (match_operator 0 "integer_relational_operator"
3595				      [(match_operand 1 "icc_operand" "t")
3596				       (const_int 0)])
3597		      (label_ref (match_operand 2 "" ""))
3598		      (pc)))]
3599  ""
3600  "*
3601{
3602  if (get_attr_length (insn) == 4)
3603    return \"b%c0 %1,%#,%l2\";
3604  else
3605    return \"b%C0 %1,%#,1f\;call %l2\\n1:\";
3606}"
3607  [(set (attr "length")
3608	(if_then_else
3609	    (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
3610		 (le (minus (match_dup 2) (pc)) (const_int 32764)))
3611	    (const_int 4)
3612	    (const_int 8)))
3613   (set (attr "far_jump")
3614        (if_then_else
3615	    (eq_attr "length" "4")
3616	    (const_string "no")
3617	    (const_string "yes")))
3618   (set (attr "type")
3619	(if_then_else
3620	    (eq_attr "length" "4")
3621	    (const_string "branch")
3622	    (const_string "multi")))])
3623
3624(define_insn "*branch_int_false"
3625  [(set (pc)
3626	(if_then_else (match_operator 0 "integer_relational_operator"
3627				      [(match_operand 1 "icc_operand" "t")
3628				       (const_int 0)])
3629		      (pc)
3630		      (label_ref (match_operand 2 "" ""))))]
3631  ""
3632  "*
3633{
3634  if (get_attr_length (insn) == 4)
3635    return \"b%C0 %1,%#,%l2\";
3636  else
3637    return \"b%c0 %1,%#,1f\;call %l2\\n1:\";
3638}"
3639  [(set (attr "length")
3640	(if_then_else
3641	    (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
3642		 (le (minus (match_dup 2) (pc)) (const_int 32764)))
3643	    (const_int 4)
3644	    (const_int 8)))
3645   (set (attr "far_jump")
3646        (if_then_else
3647	    (eq_attr "length" "4")
3648	    (const_string "no")
3649	    (const_string "yes")))
3650   (set (attr "type")
3651	(if_then_else
3652	    (eq_attr "length" "4")
3653	    (const_string "branch")
3654	    (const_string "multi")))])
3655
3656(define_insn "*branch_fp_true"
3657  [(set (pc)
3658	(if_then_else (match_operator:CC_FP 0 "float_relational_operator"
3659					    [(match_operand 1 "fcc_operand" "u")
3660					     (const_int 0)])
3661		      (label_ref (match_operand 2 "" ""))
3662		      (pc)))]
3663  ""
3664  "*
3665{
3666  if (get_attr_length (insn) == 4)
3667    return \"fb%f0 %1,%#,%l2\";
3668  else
3669    return \"fb%F0 %1,%#,1f\;call %l2\\n1:\";
3670}"
3671  [(set (attr "length")
3672	(if_then_else
3673	    (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
3674		 (le (minus (match_dup 2) (pc)) (const_int 32764)))
3675	    (const_int 4)
3676	    (const_int 8)))
3677   (set (attr "far_jump")
3678        (if_then_else
3679	    (eq_attr "length" "4")
3680	    (const_string "no")
3681	    (const_string "yes")))
3682   (set (attr "type")
3683	(if_then_else
3684	    (eq_attr "length" "4")
3685	    (const_string "branch")
3686	    (const_string "multi")))])
3687
3688(define_insn "*branch_fp_false"
3689  [(set (pc)
3690	(if_then_else (match_operator:CC_FP 0 "float_relational_operator"
3691					    [(match_operand 1 "fcc_operand" "u")
3692					     (const_int 0)])
3693		      (pc)
3694		      (label_ref (match_operand 2 "" ""))))]
3695  ""
3696  "*
3697{
3698  if (get_attr_length (insn) == 4)
3699    return \"fb%F0 %1,%#,%l2\";
3700  else
3701    return \"fb%f0 %1,%#,1f\;call %l2\\n1:\";
3702}"
3703  [(set (attr "length")
3704	(if_then_else
3705	    (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
3706		 (le (minus (match_dup 2) (pc)) (const_int 32764)))
3707	    (const_int 4)
3708	    (const_int 8)))
3709   (set (attr "far_jump")
3710        (if_then_else
3711	    (eq_attr "length" "4")
3712	    (const_string "no")
3713	    (const_string "yes")))
3714   (set (attr "type")
3715	(if_then_else
3716	    (eq_attr "length" "4")
3717	    (const_string "branch")
3718	    (const_string "multi")))])
3719
3720
3721;; ::::::::::::::::::::
3722;; ::
3723;; :: Set flag operations
3724;; ::
3725;; ::::::::::::::::::::
3726
3727;; Define_expands called by the machine independent part of the compiler
3728;; to allocate a new comparison register
3729
3730(define_expand "cstoredf4"
3731  [(use (match_operator:SI 1 "ordered_comparison_operator"
3732         [(match_operand:DF 2 "fpr_operand")
3733          (match_operand:DF 3 "fpr_operand")]))
3734   (clobber (match_operand:SI 0 "register_operand"))]
3735  "TARGET_HARD_FLOAT && TARGET_DOUBLE"
3736  { if (frv_emit_scc (operands)) DONE; else FAIL; })
3737
3738(define_expand "cstoresf4"
3739  [(use (match_operator:SI 1 "ordered_comparison_operator"
3740         [(match_operand:SF 2 "fpr_operand")
3741          (match_operand:SF 3 "fpr_operand")]))
3742   (clobber (match_operand:SI 0 "register_operand"))]
3743  "TARGET_HARD_FLOAT"
3744  { if (frv_emit_scc (operands)) DONE; else FAIL; })
3745
3746(define_expand "cstoresi4"
3747  [(use (match_operator:SI 1 "ordered_comparison_operator"
3748         [(match_operand:SI 2 "integer_register_operand")
3749          (match_operand:SI 3 "gpr_or_int10_operand")]))
3750   (clobber (match_operand:SI 0 "register_operand"))]
3751  ""
3752  { if (frv_emit_scc (operands)) DONE; else FAIL; })
3753
3754(define_insn "*scc_int"
3755  [(set (match_operand:SI 0 "integer_register_operand" "=d")
3756	(match_operator:SI 1 "integer_relational_operator"
3757			   [(match_operand 2 "icc_operand" "t")
3758			    (const_int 0)]))
3759   (clobber (match_operand:CC_CCR 3 "icr_operand" "=v"))]
3760  ""
3761  "#"
3762  [(set_attr "length" "12")
3763   (set_attr "type" "multi")])
3764
3765(define_insn "*scc_float"
3766  [(set (match_operand:SI 0 "integer_register_operand" "=d")
3767	(match_operator:SI 1 "float_relational_operator"
3768			   [(match_operand:CC_FP 2 "fcc_operand" "u")
3769			    (const_int 0)]))
3770   (clobber (match_operand:CC_CCR 3 "fcr_operand" "=w"))]
3771  ""
3772  "#"
3773  [(set_attr "length" "12")
3774   (set_attr "type" "multi")])
3775
3776;; XXX -- add reload_completed to the splits, because register allocation
3777;; currently isn't ready to see cond_exec packets.
3778(define_split
3779  [(set (match_operand:SI 0 "integer_register_operand" "")
3780	(match_operator:SI 1 "relational_operator"
3781			   [(match_operand 2 "cc_operand" "")
3782			    (const_int 0)]))
3783   (clobber (match_operand 3 "cr_operand" ""))]
3784  "reload_completed"
3785  [(match_dup 4)]
3786  "operands[4] = frv_split_scc (operands[0], operands[1], operands[2],
3787				operands[3], (HOST_WIDE_INT) 1);")
3788
3789(define_insn "*scc_neg1_int"
3790  [(set (match_operand:SI 0 "integer_register_operand" "=d")
3791	(neg:SI (match_operator:SI 1 "integer_relational_operator"
3792				   [(match_operand 2 "icc_operand" "t")
3793				    (const_int 0)])))
3794   (clobber (match_operand:CC_CCR 3 "icr_operand" "=v"))]
3795  ""
3796  "#"
3797  [(set_attr "length" "12")
3798   (set_attr "type" "multi")])
3799
3800(define_insn "*scc_neg1_float"
3801  [(set (match_operand:SI 0 "integer_register_operand" "=d")
3802	(neg:SI (match_operator:SI 1 "float_relational_operator"
3803				   [(match_operand:CC_FP 2 "fcc_operand" "u")
3804				    (const_int 0)])))
3805   (clobber (match_operand:CC_CCR 3 "fcr_operand" "=w"))]
3806  ""
3807  "#"
3808  [(set_attr "length" "12")
3809   (set_attr "type" "multi")])
3810
3811(define_split
3812  [(set (match_operand:SI 0 "integer_register_operand" "")
3813	(neg:SI (match_operator:SI 1 "relational_operator"
3814				   [(match_operand 2 "cc_operand" "")
3815				    (const_int 0)])))
3816   (clobber (match_operand 3 "cr_operand" ""))]
3817  "reload_completed"
3818  [(match_dup 4)]
3819  "operands[4] = frv_split_scc (operands[0], operands[1], operands[2],
3820				operands[3], (HOST_WIDE_INT) -1);")
3821
3822
3823;; ::::::::::::::::::::
3824;; ::
3825;; :: Conditionally executed instructions
3826;; ::
3827;; ::::::::::::::::::::
3828
3829;; Convert ICC/FCC comparison into CCR bits so we can do conditional execution
3830(define_insn "*ck_signed"
3831  [(set (match_operand:CC_CCR 0 "icr_operand" "=v")
3832	(match_operator:CC_CCR 1 "integer_relational_operator"
3833			       [(match_operand 2 "icc_operand" "t")
3834				(const_int 0)]))]
3835  ""
3836  "ck%c1 %2, %0"
3837  [(set_attr "length" "4")
3838   (set_attr "type" "ccr")])
3839
3840(define_insn "*fck_float"
3841  [(set (match_operand:CC_CCR 0 "fcr_operand" "=w")
3842	(match_operator:CC_CCR 1 "float_relational_operator"
3843			       [(match_operand:CC_FP 2 "fcc_operand" "u")
3844				(const_int 0)]))]
3845  "TARGET_HAS_FPRS"
3846  "fck%c1 %2, %0"
3847  [(set_attr "length" "4")
3848   (set_attr "type" "ccr")])
3849
3850;; Conditionally convert ICC/FCC comparison into CCR bits to provide && and ||
3851;; tests in conditional execution
3852(define_insn "cond_exec_ck"
3853  [(set (match_operand:CC_CCR 0 "cr_operand" "=v,w")
3854	(if_then_else:CC_CCR (match_operator 1 "ccr_eqne_operator"
3855					     [(match_operand 2 "cr_operand" "C,C")
3856					      (const_int 0)])
3857			     (match_operator 3 "relational_operator"
3858					     [(match_operand 4 "cc_operand" "t,u")
3859					      (const_int 0)])
3860			     (const_int 0)))]
3861  ""
3862  "@
3863   cck%c3 %4, %0, %2, %e1
3864   cfck%f3 %4, %0, %2, %e1"
3865  [(set_attr "length" "4")
3866   (set_attr "type" "ccr")])
3867
3868;; Conditionally set a register to either 0 or another register
3869(define_insn "*cond_exec_movqi"
3870  [(cond_exec
3871    (match_operator 0 "ccr_eqne_operator"
3872		    [(match_operand 1 "cr_operand" "C,C,C,C,C,C")
3873		     (const_int 0)])
3874    (set (match_operand:QI 2 "condexec_dest_operand" "=d,d,U,?f,?f,?d")
3875	 (match_operand:QI 3 "condexec_source_operand" "dO,U,dO,f,d,f")))]
3876  "register_operand(operands[2], QImode) || reg_or_0_operand (operands[3], QImode)"
3877  "* return output_condmove_single (operands, insn);"
3878  [(set_attr "length" "4")
3879   (set_attr "type" "int,gload,gstore,fsconv,movgf,movfg")])
3880
3881(define_insn "*cond_exec_movhi"
3882  [(cond_exec
3883    (match_operator 0 "ccr_eqne_operator"
3884		    [(match_operand 1 "cr_operand" "C,C,C,C,C,C")
3885		     (const_int 0)])
3886    (set (match_operand:HI 2 "condexec_dest_operand" "=d,d,U,?f,?f,?d")
3887	 (match_operand:HI 3 "condexec_source_operand" "dO,U,dO,f,d,f")))]
3888  "register_operand(operands[2], HImode) || reg_or_0_operand (operands[3], HImode)"
3889  "* return output_condmove_single (operands, insn);"
3890  [(set_attr "length" "4")
3891   (set_attr "type" "int,gload,gstore,fsconv,movgf,movfg")])
3892
3893(define_insn "*cond_exec_movsi"
3894  [(cond_exec
3895    (match_operator 0 "ccr_eqne_operator"
3896		    [(match_operand 1 "cr_operand" "C,C,C,C,C,C,C,C")
3897		     (const_int 0)])
3898    (set (match_operand:SI 2 "condexec_dest_operand" "=d,d,U,?f,?f,?d,?f,?m")
3899	 (match_operand:SI 3 "condexec_source_operand" "dO,U,dO,f,d,f,m,f")))]
3900  "register_operand(operands[2], SImode) || reg_or_0_operand (operands[3], SImode)"
3901  "* return output_condmove_single (operands, insn);"
3902  [(set_attr "length" "4")
3903   (set_attr "type" "int,gload,gstore,fsconv,movgf,movfg,fload,fstore")])
3904
3905
3906(define_insn "*cond_exec_movsf_has_fprs"
3907  [(cond_exec
3908    (match_operator 0 "ccr_eqne_operator"
3909		    [(match_operand 1 "cr_operand" "C,C,C,C,C,C,C,C,C,C")
3910		     (const_int 0)])
3911    (set (match_operand:SF 2 "condexec_dest_operand" "=f,?d,?d,?f,f,f,?d,U,?U,U")
3912	 (match_operand:SF 3 "condexec_source_operand" "f,d,f,d,G,U,U,f,d,G")))]
3913  "TARGET_HAS_FPRS"
3914  "* return output_condmove_single (operands, insn);"
3915  [(set_attr "length" "4")
3916   (set_attr "type" "fsconv,int,movgf,movfg,movgf,fload,gload,fstore,gstore,gstore")])
3917
3918(define_insn "*cond_exec_movsf_no_fprs"
3919  [(cond_exec
3920    (match_operator 0 "ccr_eqne_operator"
3921		    [(match_operand 1 "cr_operand" "C,C,C")
3922		     (const_int 0)])
3923    (set (match_operand:SF 2 "condexec_dest_operand" "=d,d,U")
3924	 (match_operand:SF 3 "condexec_source_operand" "d,U,dG")))]
3925  "! TARGET_HAS_FPRS"
3926  "* return output_condmove_single (operands, insn);"
3927  [(set_attr "length" "4")
3928   (set_attr "type" "int,gload,gstore")])
3929
3930(define_insn "*cond_exec_si_binary1"
3931  [(cond_exec
3932    (match_operator 0 "ccr_eqne_operator"
3933		    [(match_operand 1 "cr_operand" "C")
3934		     (const_int 0)])
3935    (set (match_operand:SI 2 "integer_register_operand" "=d")
3936	 (match_operator:SI 3 "condexec_si_binary_operator"
3937			    [(match_operand:SI 4 "integer_register_operand" "d")
3938			     (match_operand:SI 5 "integer_register_operand" "d")])))]
3939  ""
3940  "*
3941{
3942  switch (GET_CODE (operands[3]))
3943    {
3944      case PLUS:     return \"cadd %4, %z5, %2, %1, %e0\";
3945      case MINUS:    return \"csub %4, %z5, %2, %1, %e0\";
3946      case AND:      return \"cand %4, %z5, %2, %1, %e0\";
3947      case IOR:      return \"cor %4, %z5, %2, %1, %e0\";
3948      case XOR:      return \"cxor %4, %z5, %2, %1, %e0\";
3949      case ASHIFT:   return \"csll %4, %z5, %2, %1, %e0\";
3950      case ASHIFTRT: return \"csra %4, %z5, %2, %1, %e0\";
3951      case LSHIFTRT: return \"csrl %4, %z5, %2, %1, %e0\";
3952      default:       gcc_unreachable ();
3953    }
3954}"
3955  [(set_attr "length" "4")
3956   (set_attr "type" "int")])
3957
3958(define_insn "*cond_exec_si_binary2"
3959  [(cond_exec
3960    (match_operator 0 "ccr_eqne_operator"
3961		    [(match_operand 1 "cr_operand" "C")
3962		     (const_int 0)])
3963    (set (match_operand:SI 2 "fpr_operand" "=f")
3964	 (match_operator:SI 3 "condexec_si_media_operator"
3965			    [(match_operand:SI 4 "fpr_operand" "f")
3966			     (match_operand:SI 5 "fpr_operand" "f")])))]
3967  "TARGET_MEDIA"
3968  "*
3969{
3970  switch (GET_CODE (operands[3]))
3971    {
3972      case AND: return \"cmand %4, %5, %2, %1, %e0\";
3973      case IOR: return \"cmor %4, %5, %2, %1, %e0\";
3974      case XOR: return \"cmxor %4, %5, %2, %1, %e0\";
3975      default:  gcc_unreachable ();
3976    }
3977}"
3978  [(set_attr "length" "4")
3979   (set_attr "type" "mlogic")])
3980
3981;; Note, flow does not (currently) know how to handle an operation that uses
3982;; only part of the hard registers allocated for a multiregister value, such as
3983;; DImode in this case if the user is only interested in the lower 32-bits.  So
3984;; we emit a USE of the entire register after the csmul instruction so it won't
3985;; get confused.  See frv_ifcvt_modify_insn for more details.
3986
3987(define_insn "*cond_exec_si_smul"
3988  [(cond_exec
3989    (match_operator 0 "ccr_eqne_operator"
3990		    [(match_operand 1 "cr_operand" "C")
3991		     (const_int 0)])
3992    (set (match_operand:DI 2 "even_gpr_operand" "=e")
3993	 (mult:DI (sign_extend:DI (match_operand:SI 3 "integer_register_operand" "%d"))
3994		  (sign_extend:DI (match_operand:SI 4 "integer_register_operand" "d")))))]
3995  ""
3996  "csmul %3, %4, %2, %1, %e0"
3997  [(set_attr "length" "4")
3998   (set_attr "type" "mul")])
3999
4000(define_insn "*cond_exec_si_divide"
4001  [(cond_exec
4002    (match_operator 0 "ccr_eqne_operator"
4003		    [(match_operand 1 "cr_operand" "C")
4004		     (const_int 0)])
4005    (set (match_operand:SI 2 "integer_register_operand" "=d")
4006	 (match_operator:SI 3 "condexec_si_divide_operator"
4007			    [(match_operand:SI 4 "integer_register_operand" "d")
4008			     (match_operand:SI 5 "integer_register_operand" "d")])))]
4009  ""
4010  "*
4011{
4012  switch (GET_CODE (operands[3]))
4013    {
4014      case DIV:  return \"csdiv %4, %z5, %2, %1, %e0\";
4015      case UDIV: return \"cudiv %4, %z5, %2, %1, %e0\";
4016      default:   gcc_unreachable ();
4017    }
4018}"
4019  [(set_attr "length" "4")
4020   (set_attr "type" "div")])
4021
4022(define_insn "*cond_exec_si_unary1"
4023  [(cond_exec
4024    (match_operator 0 "ccr_eqne_operator"
4025		    [(match_operand 1 "cr_operand" "C")
4026		     (const_int 0)])
4027    (set (match_operand:SI 2 "integer_register_operand" "=d")
4028	 (match_operator:SI 3 "condexec_si_unary_operator"
4029			    [(match_operand:SI 4 "integer_register_operand" "d")])))]
4030  ""
4031  "*
4032{
4033  switch (GET_CODE (operands[3]))
4034    {
4035      case NOT: return \"cnot %4, %2, %1, %e0\";
4036      case NEG: return \"csub %., %4, %2, %1, %e0\";
4037      default:  gcc_unreachable ();
4038    }
4039}"
4040  [(set_attr "length" "4")
4041   (set_attr "type" "int")])
4042
4043(define_insn "*cond_exec_si_unary2"
4044  [(cond_exec
4045    (match_operator 0 "ccr_eqne_operator"
4046		    [(match_operand 1 "cr_operand" "C")
4047		     (const_int 0)])
4048    (set (match_operand:SI 2 "fpr_operand" "=f")
4049	 (not:SI (match_operand:SI 3 "fpr_operand" "f"))))]
4050  "TARGET_MEDIA"
4051  "cmnot %3, %2, %1, %e0"
4052  [(set_attr "length" "4")
4053   (set_attr "type" "mlogic")])
4054
4055(define_insn "*cond_exec_cmpsi_cc"
4056  [(cond_exec
4057    (match_operator 0 "ccr_eqne_operator"
4058		    [(match_operand 1 "cr_operand" "C")
4059		     (const_int 0)])
4060    (set (match_operand:CC 2 "icc_operand" "=t")
4061	 (compare:CC (match_operand:SI 3 "integer_register_operand" "d")
4062		     (match_operand:SI 4 "reg_or_0_operand" "dO"))))]
4063  "reload_completed
4064   && REGNO (operands[1]) == REGNO (operands[2]) - ICC_FIRST + ICR_FIRST"
4065  "ccmp %3, %z4, %1, %e0"
4066  [(set_attr "length" "4")
4067   (set_attr "type" "int")])
4068
4069(define_insn "*cond_exec_cmpsi_cc_uns"
4070  [(cond_exec
4071    (match_operator 0 "ccr_eqne_operator"
4072		    [(match_operand 1 "cr_operand" "C")
4073		     (const_int 0)])
4074    (set (match_operand:CC_UNS 2 "icc_operand" "=t")
4075	 (compare:CC_UNS (match_operand:SI 3 "integer_register_operand" "d")
4076			 (match_operand:SI 4 "reg_or_0_operand" "dO"))))]
4077  "reload_completed
4078   && REGNO (operands[1]) == REGNO (operands[2]) - ICC_FIRST + ICR_FIRST"
4079  "ccmp %3, %z4, %1, %e0"
4080  [(set_attr "length" "4")
4081   (set_attr "type" "int")])
4082
4083(define_insn "*cond_exec_cmpsi_cc_nz"
4084  [(cond_exec
4085    (match_operator 0 "ccr_eqne_operator"
4086		    [(match_operand 1 "cr_operand" "C")
4087		     (const_int 0)])
4088    (set (match_operand:CC_NZ 2 "icc_operand" "=t")
4089	 (compare:CC_NZ (match_operand:SI 3 "integer_register_operand" "d")
4090			(const_int 0))))]
4091  "reload_completed
4092   && REGNO (operands[1]) == REGNO (operands[2]) - ICC_FIRST + ICR_FIRST"
4093  "ccmp %3, %., %1, %e0"
4094  [(set_attr "length" "4")
4095   (set_attr "type" "int")])
4096
4097(define_insn "*cond_exec_sf_conv"
4098  [(cond_exec
4099    (match_operator 0 "ccr_eqne_operator"
4100		    [(match_operand 1 "cr_operand" "C")
4101		     (const_int 0)])
4102    (set (match_operand:SF 2 "fpr_operand" "=f")
4103	 (match_operator:SF 3 "condexec_sf_conv_operator"
4104			    [(match_operand:SF 4 "fpr_operand" "f")])))]
4105  "TARGET_HARD_FLOAT"
4106  "*
4107{
4108  switch (GET_CODE (operands[3]))
4109    {
4110      case ABS: return \"cfabss %4, %2, %1, %e0\";
4111      case NEG: return \"cfnegs %4, %2, %1, %e0\";
4112      default:  gcc_unreachable ();
4113    }
4114}"
4115  [(set_attr "length" "4")
4116   (set_attr "type" "fsconv")])
4117
4118(define_insn "*cond_exec_sf_add"
4119  [(cond_exec
4120    (match_operator 0 "ccr_eqne_operator"
4121		    [(match_operand 1 "cr_operand" "C")
4122		     (const_int 0)])
4123    (set (match_operand:SF 2 "fpr_operand" "=f")
4124	 (match_operator:SF 3 "condexec_sf_add_operator"
4125			    [(match_operand:SF 4 "fpr_operand" "f")
4126			     (match_operand:SF 5 "fpr_operand" "f")])))]
4127  "TARGET_HARD_FLOAT"
4128  "*
4129{
4130  switch (GET_CODE (operands[3]))
4131    {
4132      case PLUS:  return \"cfadds %4, %5, %2, %1, %e0\";
4133      case MINUS: return \"cfsubs %4, %5, %2, %1, %e0\";
4134      default:    gcc_unreachable ();
4135    }
4136}"
4137  [(set_attr "length" "4")
4138   (set_attr "type" "fsadd")])
4139
4140(define_insn "*cond_exec_sf_mul"
4141  [(cond_exec
4142    (match_operator 0 "ccr_eqne_operator"
4143		    [(match_operand 1 "cr_operand" "C")
4144		     (const_int 0)])
4145    (set (match_operand:SF 2 "fpr_operand" "=f")
4146	 (mult:SF (match_operand:SF 3 "fpr_operand" "f")
4147		  (match_operand:SF 4 "fpr_operand" "f"))))]
4148  "TARGET_HARD_FLOAT"
4149  "cfmuls %3, %4, %2, %1, %e0"
4150  [(set_attr "length" "4")
4151   (set_attr "type" "fsmul")])
4152
4153(define_insn "*cond_exec_sf_div"
4154  [(cond_exec
4155    (match_operator 0 "ccr_eqne_operator"
4156		    [(match_operand 1 "cr_operand" "C")
4157		     (const_int 0)])
4158    (set (match_operand:SF 2 "fpr_operand" "=f")
4159	 (div:SF (match_operand:SF 3 "fpr_operand" "f")
4160		 (match_operand:SF 4 "fpr_operand" "f"))))]
4161  "TARGET_HARD_FLOAT"
4162  "cfdivs %3, %4, %2, %1, %e0"
4163  [(set_attr "length" "4")
4164   (set_attr "type" "fsdiv")])
4165
4166(define_insn "*cond_exec_sf_sqrt"
4167  [(cond_exec
4168    (match_operator 0 "ccr_eqne_operator"
4169		    [(match_operand 1 "cr_operand" "C")
4170		     (const_int 0)])
4171    (set (match_operand:SF 2 "fpr_operand" "=f")
4172	 (sqrt:SF (match_operand:SF 3 "fpr_operand" "f"))))]
4173  "TARGET_HARD_FLOAT"
4174  "cfsqrts %3, %2, %1, %e0"
4175  [(set_attr "length" "4")
4176   (set_attr "type" "fsdiv")])
4177
4178(define_insn "*cond_exec_cmpsi_cc_fp"
4179  [(cond_exec
4180    (match_operator 0 "ccr_eqne_operator"
4181		    [(match_operand 1 "cr_operand" "C")
4182		     (const_int 0)])
4183    (set (match_operand:CC_FP 2 "fcc_operand" "=u")
4184	 (compare:CC_FP (match_operand:SF 3 "fpr_operand" "f")
4185			(match_operand:SF 4 "fpr_operand" "f"))))]
4186  "reload_completed && TARGET_HARD_FLOAT
4187   && REGNO (operands[1]) == REGNO (operands[2]) - FCC_FIRST + FCR_FIRST"
4188  "cfcmps %3, %4, %2, %1, %e0"
4189  [(set_attr "length" "4")
4190   (set_attr "type" "fsconv")])
4191
4192
4193;; ::::::::::::::::::::
4194;; ::
4195;; :: Logical operations on CR registers
4196;; ::
4197;; ::::::::::::::::::::
4198
4199;; We use UNSPEC to encode andcr/iorcr/etc. rather than the normal RTL
4200;; operations, since the RTL operations only have an idea of TRUE and FALSE,
4201;; while the CRs have TRUE, FALSE, and UNDEFINED.
4202
4203(define_expand "andcr"
4204  [(set (match_operand:CC_CCR 0 "cr_operand" "")
4205	(unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "")
4206			(match_operand:CC_CCR 2 "cr_operand" "")
4207			(const_int 0)] UNSPEC_CR_LOGIC))]
4208  ""
4209  "")
4210
4211(define_expand "orcr"
4212  [(set (match_operand:CC_CCR 0 "cr_operand" "")
4213	(unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "")
4214			(match_operand:CC_CCR 2 "cr_operand" "")
4215			(const_int 1)] UNSPEC_CR_LOGIC))]
4216  ""
4217  "")
4218
4219(define_expand "xorcr"
4220  [(set (match_operand:CC_CCR 0 "cr_operand" "")
4221	(unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "")
4222			(match_operand:CC_CCR 2 "cr_operand" "")
4223			(const_int 2)] UNSPEC_CR_LOGIC))]
4224  ""
4225  "")
4226
4227(define_expand "nandcr"
4228  [(set (match_operand:CC_CCR 0 "cr_operand" "")
4229	(unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "")
4230			(match_operand:CC_CCR 2 "cr_operand" "")
4231			(const_int 3)] UNSPEC_CR_LOGIC))]
4232  ""
4233  "")
4234
4235(define_expand "norcr"
4236  [(set (match_operand:CC_CCR 0 "cr_operand" "")
4237	(unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "")
4238			(match_operand:CC_CCR 2 "cr_operand" "")
4239			(const_int 4)] UNSPEC_CR_LOGIC))]
4240  ""
4241  "")
4242
4243(define_expand "andncr"
4244  [(set (match_operand:CC_CCR 0 "cr_operand" "")
4245	(unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "")
4246			(match_operand:CC_CCR 2 "cr_operand" "")
4247			(const_int 5)] UNSPEC_CR_LOGIC))]
4248  ""
4249  "")
4250
4251(define_expand "orncr"
4252  [(set (match_operand:CC_CCR 0 "cr_operand" "")
4253	(unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "")
4254			(match_operand:CC_CCR 2 "cr_operand" "")
4255			(const_int 6)] UNSPEC_CR_LOGIC))]
4256  ""
4257  "")
4258
4259(define_expand "nandncr"
4260  [(set (match_operand:CC_CCR 0 "cr_operand" "")
4261	(unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "")
4262			(match_operand:CC_CCR 2 "cr_operand" "")
4263			(const_int 7)] UNSPEC_CR_LOGIC))]
4264  ""
4265  "")
4266
4267(define_expand "norncr"
4268  [(set (match_operand:CC_CCR 0 "cr_operand" "")
4269	(unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "")
4270			(match_operand:CC_CCR 2 "cr_operand" "")
4271			(const_int 8)] UNSPEC_CR_LOGIC))]
4272  ""
4273  "")
4274
4275(define_expand "notcr"
4276  [(set (match_operand:CC_CCR 0 "cr_operand" "")
4277	(unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "")
4278			(match_dup 1)
4279			(const_int 9)] UNSPEC_CR_LOGIC))]
4280  ""
4281  "")
4282
4283(define_insn "*logical_cr"
4284  [(set (match_operand:CC_CCR 0 "cr_operand" "=C")
4285	(unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "C")
4286			(match_operand:CC_CCR 2 "cr_operand" "C")
4287			(match_operand:SI 3 "const_int_operand" "n")]
4288		       UNSPEC_CR_LOGIC))]
4289  ""
4290  "*
4291{
4292  switch (INTVAL (operands[3]))
4293  {
4294  default: break;
4295  case 0: return \"andcr %1, %2, %0\";
4296  case 1: return \"orcr %1, %2, %0\";
4297  case 2: return \"xorcr %1, %2, %0\";
4298  case 3: return \"nandcr %1, %2, %0\";
4299  case 4: return \"norcr %1, %2, %0\";
4300  case 5: return \"andncr %1, %2, %0\";
4301  case 6: return \"orncr %1, %2, %0\";
4302  case 7: return \"nandncr %1, %2, %0\";
4303  case 8: return \"norncr %1, %2, %0\";
4304  case 9: return \"notcr %1, %0\";
4305  }
4306
4307  fatal_insn (\"logical_cr\", insn);
4308}"
4309  [(set_attr "length" "4")
4310   (set_attr "type" "ccr")])
4311
4312
4313;; ::::::::::::::::::::
4314;; ::
4315;; :: Conditional move instructions
4316;; ::
4317;; ::::::::::::::::::::
4318
4319
4320;; - conditional moves based on floating-point comparisons require
4321;;   TARGET_HARD_FLOAT, because an FPU is required to do the comparison.
4322
4323;; - conditional moves between FPRs based on integer comparisons
4324;;   require TARGET_HAS_FPRS.
4325
4326(define_expand "movqicc"
4327  [(set (match_operand:QI 0 "integer_register_operand" "")
4328	(if_then_else:QI (match_operand 1 "" "")
4329			 (match_operand:QI 2 "gpr_or_int_operand" "")
4330			 (match_operand:QI 3 "gpr_or_int_operand" "")))]
4331  "TARGET_COND_MOVE"
4332  "
4333{
4334  if (!frv_emit_cond_move (operands[0], operands[1], operands[2], operands[3]))
4335    FAIL;
4336
4337  DONE;
4338}")
4339
4340(define_insn "*movqicc_internal1_int"
4341  [(set (match_operand:QI 0 "integer_register_operand" "=d,d,d")
4342	(if_then_else:QI (match_operator 1 "integer_relational_operator"
4343			     [(match_operand 2 "icc_operand" "t,t,t")
4344			      (const_int 0)])
4345			 (match_operand:QI 3 "reg_or_0_operand" "0,dO,dO")
4346			 (match_operand:QI 4 "reg_or_0_operand" "dO,0,dO")))
4347   (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v"))]
4348  ""
4349  "#"
4350  [(set_attr "length" "8,8,12")
4351   (set_attr "type" "multi")])
4352
4353(define_insn "*movqicc_internal1_float"
4354  [(set (match_operand:QI 0 "integer_register_operand" "=d,d,d")
4355	(if_then_else:QI (match_operator:CC_FP 1 "float_relational_operator"
4356			     [(match_operand:CC_FP 2 "fcc_operand" "u,u,u")
4357			      (const_int 0)])
4358			 (match_operand:QI 3 "reg_or_0_operand" "0,dO,dO")
4359			 (match_operand:QI 4 "reg_or_0_operand" "dO,0,dO")))
4360   (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w"))]
4361  "TARGET_HARD_FLOAT"
4362  "#"
4363  [(set_attr "length" "8,8,12")
4364   (set_attr "type" "multi")])
4365
4366(define_insn "*movqicc_internal2_int"
4367  [(set (match_operand:QI 0 "integer_register_operand" "=d,d,d,d,d")
4368	(if_then_else:QI (match_operator 1 "integer_relational_operator"
4369			     [(match_operand 2 "icc_operand" "t,t,t,t,t")
4370			      (const_int 0)])
4371			 (match_operand:QI 3 "const_int_operand" "O,O,L,n,n")
4372			 (match_operand:QI 4 "const_int_operand" "L,n,O,O,n")))
4373   (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v,v,v"))]
4374  "(INTVAL (operands[3]) == 0
4375    || INTVAL (operands[4]) == 0
4376    || (IN_RANGE (INTVAL (operands[3]), -2048, 2047)
4377        && IN_RANGE (INTVAL (operands[4]) - INTVAL (operands[3]), -2048, 2047)))"
4378  "#"
4379  [(set_attr "length" "8,12,8,12,12")
4380   (set_attr "type" "multi")])
4381
4382(define_insn "*movqicc_internal2_float"
4383  [(set (match_operand:QI 0 "integer_register_operand" "=d,d,d,d,d")
4384	(if_then_else:QI (match_operator:CC_FP 1 "float_relational_operator"
4385			     [(match_operand:CC_FP 2 "fcc_operand" "u,u,u,u,u")
4386			      (const_int 0)])
4387			 (match_operand:QI 3 "const_int_operand" "O,O,L,n,n")
4388			 (match_operand:QI 4 "const_int_operand" "L,n,O,O,n")))
4389   (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w,w,w"))]
4390  "TARGET_HARD_FLOAT
4391   && (INTVAL (operands[3]) == 0
4392       || INTVAL (operands[4]) == 0
4393       || (IN_RANGE (INTVAL (operands[3]), -2048, 2047)
4394	   && IN_RANGE (INTVAL (operands[4]) - INTVAL (operands[3]), -2048, 2047)))"
4395  "#"
4396  [(set_attr "length" "8,12,8,12,12")
4397   (set_attr "type" "multi")])
4398
4399(define_split
4400  [(set (match_operand:QI 0 "integer_register_operand" "")
4401	(if_then_else:QI (match_operator 1 "relational_operator"
4402			     [(match_operand 2 "cc_operand" "")
4403			      (const_int 0)])
4404			 (match_operand:QI 3 "gpr_or_int_operand" "")
4405			 (match_operand:QI 4 "gpr_or_int_operand" "")))
4406   (clobber (match_operand:CC_CCR 5 "cr_operand" ""))]
4407  "reload_completed"
4408  [(match_dup 6)]
4409  "operands[6] = frv_split_cond_move (operands);")
4410
4411(define_expand "movhicc"
4412  [(set (match_operand:HI 0 "integer_register_operand" "")
4413	(if_then_else:HI (match_operand 1 "" "")
4414			 (match_operand:HI 2 "gpr_or_int_operand" "")
4415			 (match_operand:HI 3 "gpr_or_int_operand" "")))]
4416  "TARGET_COND_MOVE"
4417  "
4418{
4419  if (!frv_emit_cond_move (operands[0], operands[1], operands[2], operands[3]))
4420    FAIL;
4421
4422  DONE;
4423}")
4424
4425(define_insn "*movhicc_internal1_int"
4426  [(set (match_operand:HI 0 "integer_register_operand" "=d,d,d")
4427	(if_then_else:HI (match_operator 1 "integer_relational_operator"
4428			     [(match_operand 2 "icc_operand" "t,t,t")
4429			      (const_int 0)])
4430			 (match_operand:HI 3 "reg_or_0_operand" "0,dO,dO")
4431			 (match_operand:HI 4 "reg_or_0_operand" "dO,0,dO")))
4432   (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v"))]
4433  ""
4434  "#"
4435  [(set_attr "length" "8,8,12")
4436   (set_attr "type" "multi")])
4437
4438(define_insn "*movhicc_internal1_float"
4439  [(set (match_operand:HI 0 "integer_register_operand" "=d,d,d")
4440	(if_then_else:HI (match_operator:CC_FP 1 "float_relational_operator"
4441			     [(match_operand:CC_FP 2 "fcc_operand" "u,u,u")
4442			      (const_int 0)])
4443			 (match_operand:HI 3 "reg_or_0_operand" "0,dO,dO")
4444			 (match_operand:HI 4 "reg_or_0_operand" "dO,0,dO")))
4445   (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w"))]
4446  "TARGET_HARD_FLOAT"
4447  "#"
4448  [(set_attr "length" "8,8,12")
4449   (set_attr "type" "multi")])
4450
4451(define_insn "*movhicc_internal2_int"
4452  [(set (match_operand:HI 0 "integer_register_operand" "=d,d,d,d,d")
4453	(if_then_else:HI (match_operator 1 "integer_relational_operator"
4454			     [(match_operand 2 "icc_operand" "t,t,t,t,t")
4455			      (const_int 0)])
4456			 (match_operand:HI 3 "const_int_operand" "O,O,L,n,n")
4457			 (match_operand:HI 4 "const_int_operand" "L,n,O,O,n")))
4458   (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v,v,v"))]
4459  "(INTVAL (operands[3]) == 0
4460    || INTVAL (operands[4]) == 0
4461    || (IN_RANGE (INTVAL (operands[3]), -2048, 2047)
4462        && IN_RANGE (INTVAL (operands[4]) - INTVAL (operands[3]), -2048, 2047)))"
4463  "#"
4464  [(set_attr "length" "8,12,8,12,12")
4465   (set_attr "type" "multi")])
4466
4467(define_insn "*movhicc_internal2_float"
4468  [(set (match_operand:HI 0 "integer_register_operand" "=d,d,d,d,d")
4469	(if_then_else:HI (match_operator:CC_FP 1 "float_relational_operator"
4470			     [(match_operand:CC_FP 2 "fcc_operand" "u,u,u,u,u")
4471			      (const_int 0)])
4472			 (match_operand:HI 3 "const_int_operand" "O,O,L,n,n")
4473			 (match_operand:HI 4 "const_int_operand" "L,n,O,O,n")))
4474   (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w,w,w"))]
4475  "TARGET_HARD_FLOAT
4476   && (INTVAL (operands[3]) == 0
4477       || INTVAL (operands[4]) == 0
4478       || (IN_RANGE (INTVAL (operands[3]), -2048, 2047)
4479	   && IN_RANGE (INTVAL (operands[4]) - INTVAL (operands[3]), -2048, 2047)))"
4480  "#"
4481  [(set_attr "length" "8,12,8,12,12")
4482   (set_attr "type" "multi")])
4483
4484(define_split
4485  [(set (match_operand:HI 0 "integer_register_operand" "")
4486	(if_then_else:HI (match_operator 1 "relational_operator"
4487			     [(match_operand 2 "cc_operand" "")
4488			      (const_int 0)])
4489			 (match_operand:HI 3 "gpr_or_int_operand" "")
4490			 (match_operand:HI 4 "gpr_or_int_operand" "")))
4491   (clobber (match_operand:CC_CCR 5 "cr_operand" ""))]
4492  "reload_completed"
4493  [(match_dup 6)]
4494  "operands[6] = frv_split_cond_move (operands);")
4495
4496(define_expand "movsicc"
4497  [(set (match_operand:SI 0 "integer_register_operand" "")
4498	(if_then_else:SI (match_operand 1 "" "")
4499			 (match_operand:SI 2 "gpr_or_int_operand" "")
4500			 (match_operand:SI 3 "gpr_or_int_operand" "")))]
4501  "TARGET_COND_MOVE"
4502  "
4503{
4504  if (!frv_emit_cond_move (operands[0], operands[1], operands[2], operands[3]))
4505    FAIL;
4506
4507  DONE;
4508}")
4509
4510(define_insn "*movsicc_internal1_int"
4511  [(set (match_operand:SI 0 "integer_register_operand" "=d,d,d")
4512	(if_then_else:SI (match_operator 1 "integer_relational_operator"
4513			     [(match_operand 2 "icc_operand" "t,t,t")
4514			      (const_int 0)])
4515			 (match_operand:SI 3 "reg_or_0_operand" "0,dO,dO")
4516			 (match_operand:SI 4 "reg_or_0_operand" "dO,0,dO")))
4517   (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v"))]
4518  ""
4519  "#"
4520  [(set_attr "length" "8,8,12")
4521   (set_attr "type" "multi")])
4522
4523(define_insn "*movsicc_internal1_float"
4524  [(set (match_operand:SI 0 "integer_register_operand" "=d,d,d")
4525	(if_then_else:SI (match_operator:CC_FP 1 "float_relational_operator"
4526			     [(match_operand:CC_FP 2 "fcc_operand" "u,u,u")
4527			      (const_int 0)])
4528			 (match_operand:SI 3 "reg_or_0_operand" "0,dO,dO")
4529			 (match_operand:SI 4 "reg_or_0_operand" "dO,0,dO")))
4530   (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w"))]
4531  "TARGET_HARD_FLOAT"
4532  "#"
4533  [(set_attr "length" "8,8,12")
4534   (set_attr "type" "multi")])
4535
4536(define_insn "*movsicc_internal2_int"
4537  [(set (match_operand:SI 0 "integer_register_operand" "=d,d,d,d,d")
4538	(if_then_else:SI (match_operator 1 "integer_relational_operator"
4539			     [(match_operand 2 "icc_operand" "t,t,t,t,t")
4540			      (const_int 0)])
4541			 (match_operand:SI 3 "const_int_operand" "O,O,L,n,n")
4542			 (match_operand:SI 4 "const_int_operand" "L,n,O,O,n")))
4543   (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v,v,v"))]
4544  "(INTVAL (operands[3]) == 0
4545    || INTVAL (operands[4]) == 0
4546    || (IN_RANGE (INTVAL (operands[3]), -2048, 2047)
4547        && IN_RANGE (INTVAL (operands[4]) - INTVAL (operands[3]), -2048, 2047)))"
4548  "#"
4549  [(set_attr "length" "8,12,8,12,12")
4550   (set_attr "type" "multi")])
4551
4552(define_insn "*movsicc_internal2_float"
4553  [(set (match_operand:SI 0 "integer_register_operand" "=d,d,d,d,d")
4554	(if_then_else:SI (match_operator:CC_FP 1 "float_relational_operator"
4555			     [(match_operand:CC_FP 2 "fcc_operand" "u,u,u,u,u")
4556			      (const_int 0)])
4557			 (match_operand:SI 3 "const_int_operand" "O,O,L,n,n")
4558			 (match_operand:SI 4 "const_int_operand" "L,n,O,O,n")))
4559   (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w,w,w"))]
4560  "TARGET_HARD_FLOAT
4561   && (INTVAL (operands[3]) == 0
4562       || INTVAL (operands[4]) == 0
4563       || (IN_RANGE (INTVAL (operands[3]), -2048, 2047)
4564	   && IN_RANGE (INTVAL (operands[4]) - INTVAL (operands[3]), -2048, 2047)))"
4565  "#"
4566  [(set_attr "length" "8,12,8,12,12")
4567   (set_attr "type" "multi")])
4568
4569(define_split
4570  [(set (match_operand:SI 0 "integer_register_operand" "")
4571	(if_then_else:SI (match_operator 1 "relational_operator"
4572			     [(match_operand 2 "cc_operand" "")
4573			      (const_int 0)])
4574			 (match_operand:SI 3 "gpr_or_int_operand" "")
4575			 (match_operand:SI 4 "gpr_or_int_operand" "")))
4576   (clobber (match_operand:CC_CCR 5 "cr_operand" ""))]
4577  "reload_completed"
4578  [(match_dup 6)]
4579  "operands[6] = frv_split_cond_move (operands);")
4580
4581(define_expand "movsfcc"
4582  [(set (match_operand:SF 0 "register_operand" "")
4583	(if_then_else:SF (match_operand 1 "" "")
4584			 (match_operand:SF 2 "register_operand" "")
4585			 (match_operand:SF 3 "register_operand" "")))]
4586  "TARGET_COND_MOVE"
4587  "
4588{
4589  if (!frv_emit_cond_move (operands[0], operands[1], operands[2], operands[3]))
4590    FAIL;
4591
4592  DONE;
4593}")
4594
4595(define_insn "*movsfcc_has_fprs_int"
4596  [(set (match_operand:SF 0 "register_operand" "=f,f,f,?f,?f,?d")
4597	(if_then_else:SF (match_operator 1 "integer_relational_operator"
4598			     [(match_operand 2 "icc_operand" "t,t,t,t,t,t")
4599			      (const_int 0)])
4600			 (match_operand:SF 3 "register_operand" "0,f,f,f,d,fd")
4601			 (match_operand:SF 4 "register_operand" "f,0,f,d,fd,fd")))
4602   (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v,v,v,v"))]
4603  "TARGET_HAS_FPRS"
4604  "#"
4605  [(set_attr "length" "8,8,12,12,12,12")
4606   (set_attr "type" "multi")])
4607
4608(define_insn "*movsfcc_hardfloat_float"
4609  [(set (match_operand:SF 0 "register_operand" "=f,f,f,?f,?f,?d")
4610	(if_then_else:SF (match_operator:CC_FP 1 "float_relational_operator"
4611			     [(match_operand:CC_FP 2 "fcc_operand" "u,u,u,u,u,u")
4612			      (const_int 0)])
4613			 (match_operand:SF 3 "register_operand" "0,f,f,f,d,fd")
4614			 (match_operand:SF 4 "register_operand" "f,0,f,d,fd,fd")))
4615   (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w,w,w,w"))]
4616  "TARGET_HARD_FLOAT"
4617  "#"
4618  [(set_attr "length" "8,8,12,12,12,12")
4619   (set_attr "type" "multi")])
4620
4621(define_insn "*movsfcc_no_fprs_int"
4622  [(set (match_operand:SF 0 "integer_register_operand" "=d,d,d")
4623	(if_then_else:SF (match_operator 1 "integer_relational_operator"
4624			     [(match_operand 2 "icc_operand" "t,t,t")
4625			      (const_int 0)])
4626			 (match_operand:SF 3 "integer_register_operand" "0,d,d")
4627			 (match_operand:SF 4 "integer_register_operand" "d,0,d")))
4628   (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v"))]
4629  "! TARGET_HAS_FPRS"
4630  "#"
4631  [(set_attr "length" "8,8,12")
4632   (set_attr "type" "multi")])
4633
4634(define_split
4635  [(set (match_operand:SF 0 "register_operand" "")
4636	(if_then_else:SF (match_operator 1 "relational_operator"
4637			     [(match_operand 2 "cc_operand" "")
4638			      (const_int 0)])
4639			 (match_operand:SF 3 "register_operand" "")
4640			 (match_operand:SF 4 "register_operand" "")))
4641   (clobber (match_operand:CC_CCR 5 "cr_operand" ""))]
4642  "reload_completed"
4643  [(match_dup 6)]
4644  "operands[6] = frv_split_cond_move (operands);")
4645
4646
4647;; ::::::::::::::::::::
4648;; ::
4649;; :: Minimum, maximum, and integer absolute value
4650;; ::
4651;; ::::::::::::::::::::
4652
4653;; These 'instructions' are provided to give the compiler a slightly better
4654;; nudge at register allocation, then it would if it constructed the
4655;; instructions from basic building blocks (since it indicates it prefers one
4656;; of the operands to be the same as the destination.  It also helps the
4657;; earlier passes of the compiler, by not breaking things into small basic
4658;; blocks.
4659
4660(define_expand "abssi2"
4661  [(parallel [(set (match_operand:SI 0 "integer_register_operand" "")
4662		   (abs:SI (match_operand:SI 1 "integer_register_operand" "")))
4663	      (clobber (match_dup 2))
4664	      (clobber (match_dup 3))])]
4665  "TARGET_COND_MOVE"
4666  "
4667{
4668  operands[2] = gen_reg_rtx (CCmode);
4669  operands[3] = gen_reg_rtx (CC_CCRmode);
4670}")
4671
4672(define_insn_and_split "*abssi2_internal"
4673  [(set (match_operand:SI 0 "integer_register_operand" "=d,d")
4674	(abs:SI (match_operand:SI 1 "integer_register_operand" "0,d")))
4675   (clobber (match_operand:CC 2 "icc_operand" "=t,t"))
4676   (clobber (match_operand:CC_CCR 3 "icr_operand" "=v,v"))]
4677  "TARGET_COND_MOVE"
4678  "#"
4679  "reload_completed"
4680  [(match_dup 4)]
4681  "operands[4] = frv_split_abs (operands);"
4682  [(set_attr "length" "12,16")
4683   (set_attr "type" "multi")])
4684
4685(define_expand "sminsi3"
4686  [(parallel [(set (match_operand:SI 0 "integer_register_operand" "")
4687		   (smin:SI (match_operand:SI 1 "integer_register_operand" "")
4688			    (match_operand:SI 2 "gpr_or_int10_operand" "")))
4689	      (clobber (match_dup 3))
4690	      (clobber (match_dup 4))])]
4691  "TARGET_COND_MOVE"
4692  "
4693{
4694  operands[3] = gen_reg_rtx (CCmode);
4695  operands[4] = gen_reg_rtx (CC_CCRmode);
4696}")
4697
4698(define_expand "smaxsi3"
4699  [(parallel [(set (match_operand:SI 0 "integer_register_operand" "")
4700		   (smax:SI (match_operand:SI 1 "integer_register_operand" "")
4701			    (match_operand:SI 2 "gpr_or_int10_operand" "")))
4702	      (clobber (match_dup 3))
4703	      (clobber (match_dup 4))])]
4704  "TARGET_COND_MOVE"
4705  "
4706{
4707  operands[3] = gen_reg_rtx (CCmode);
4708  operands[4] = gen_reg_rtx (CC_CCRmode);
4709}")
4710
4711(define_insn_and_split "*minmax_si_signed"
4712  [(set (match_operand:SI 0 "integer_register_operand" "=d,d,&d")
4713	(match_operator:SI 1 "minmax_operator"
4714			   [(match_operand:SI 2 "integer_register_operand" "%0,dO,d")
4715			    (match_operand:SI 3 "gpr_or_int10_operand" "dO,0,dJ")]))
4716   (clobber (match_operand:CC 4 "icc_operand" "=t,t,t"))
4717   (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v"))]
4718  "TARGET_COND_MOVE"
4719  "#"
4720  "reload_completed"
4721  [(match_dup 6)]
4722  "operands[6] = frv_split_minmax (operands);"
4723  [(set_attr "length" "12,12,16")
4724   (set_attr "type" "multi")])
4725
4726(define_expand "uminsi3"
4727  [(parallel [(set (match_operand:SI 0 "integer_register_operand" "")
4728		   (umin:SI (match_operand:SI 1 "integer_register_operand" "")
4729			    (match_operand:SI 2 "gpr_or_int10_operand" "")))
4730	      (clobber (match_dup 3))
4731	      (clobber (match_dup 4))])]
4732  "TARGET_COND_MOVE"
4733  "
4734{
4735  operands[3] = gen_reg_rtx (CC_UNSmode);
4736  operands[4] = gen_reg_rtx (CC_CCRmode);
4737}")
4738
4739(define_expand "umaxsi3"
4740  [(parallel [(set (match_operand:SI 0 "integer_register_operand" "")
4741		   (umax:SI (match_operand:SI 1 "integer_register_operand" "")
4742			    (match_operand:SI 2 "gpr_or_int10_operand" "")))
4743	      (clobber (match_dup 3))
4744	      (clobber (match_dup 4))])]
4745  "TARGET_COND_MOVE"
4746  "
4747{
4748  operands[3] = gen_reg_rtx (CC_UNSmode);
4749  operands[4] = gen_reg_rtx (CC_CCRmode);
4750}")
4751
4752(define_insn_and_split "*minmax_si_unsigned"
4753  [(set (match_operand:SI 0 "integer_register_operand" "=d,d,&d")
4754	(match_operator:SI 1 "minmax_operator"
4755			   [(match_operand:SI 2 "integer_register_operand" "%0,dO,d")
4756			    (match_operand:SI 3 "gpr_or_int10_operand" "dO,0,dJ")]))
4757   (clobber (match_operand:CC_UNS 4 "icc_operand" "=t,t,t"))
4758   (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v"))]
4759  "TARGET_COND_MOVE"
4760  "#"
4761  "reload_completed"
4762  [(match_dup 6)]
4763  "operands[6] = frv_split_minmax (operands);"
4764  [(set_attr "length" "12,12,16")
4765   (set_attr "type" "multi")])
4766
4767(define_expand "sminsf3"
4768  [(parallel [(set (match_operand:SF 0 "fpr_operand" "")
4769		   (smin:SF (match_operand:SF 1 "fpr_operand" "")
4770			    (match_operand:SF 2 "fpr_operand" "")))
4771	      (clobber (match_dup 3))
4772	      (clobber (match_dup 4))])]
4773  "TARGET_COND_MOVE && TARGET_HARD_FLOAT"
4774  "
4775{
4776  operands[3] = gen_reg_rtx (CC_FPmode);
4777  operands[4] = gen_reg_rtx (CC_CCRmode);
4778}")
4779
4780(define_expand "smaxsf3"
4781  [(parallel [(set (match_operand:SF 0 "fpr_operand" "")
4782		   (smax:SF (match_operand:SF 1 "fpr_operand" "")
4783			    (match_operand:SF 2 "fpr_operand" "")))
4784	      (clobber (match_dup 3))
4785	      (clobber (match_dup 4))])]
4786  "TARGET_COND_MOVE && TARGET_HARD_FLOAT"
4787  "
4788{
4789  operands[3] = gen_reg_rtx (CC_FPmode);
4790  operands[4] = gen_reg_rtx (CC_CCRmode);
4791}")
4792
4793(define_insn_and_split "*minmax_sf"
4794  [(set (match_operand:SF 0 "fpr_operand" "=f,f,f")
4795	(match_operator:SF 1 "minmax_operator"
4796			   [(match_operand:SF 2 "fpr_operand" "%0,f,f")
4797			    (match_operand:SF 3 "fpr_operand" "f,0,f")]))
4798   (clobber (match_operand:CC_FP 4 "fcc_operand" "=u,u,u"))
4799   (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w"))]
4800  "TARGET_COND_MOVE && TARGET_HARD_FLOAT"
4801  "#"
4802  "reload_completed"
4803  [(match_dup 6)]
4804  "operands[6] = frv_split_minmax (operands);"
4805  [(set_attr "length" "12,12,16")
4806   (set_attr "type" "multi")])
4807
4808(define_expand "smindf3"
4809  [(parallel [(set (match_operand:DF 0 "fpr_operand" "")
4810		   (smin:DF (match_operand:DF 1 "fpr_operand" "")
4811			    (match_operand:DF 2 "fpr_operand" "")))
4812	      (clobber (match_dup 3))
4813	      (clobber (match_dup 4))])]
4814  "TARGET_COND_MOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE"
4815  "
4816{
4817  operands[3] = gen_reg_rtx (CC_FPmode);
4818  operands[4] = gen_reg_rtx (CC_CCRmode);
4819}")
4820
4821(define_expand "smaxdf3"
4822  [(parallel [(set (match_operand:DF 0 "fpr_operand" "")
4823		   (smax:DF (match_operand:DF 1 "fpr_operand" "")
4824			    (match_operand:DF 2 "fpr_operand" "")))
4825	      (clobber (match_dup 3))
4826	      (clobber (match_dup 4))])]
4827  "TARGET_COND_MOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE"
4828  "
4829{
4830  operands[3] = gen_reg_rtx (CC_FPmode);
4831  operands[4] = gen_reg_rtx (CC_CCRmode);
4832}")
4833
4834(define_insn_and_split "*minmax_df"
4835  [(set (match_operand:DF 0 "fpr_operand" "=f,f,f")
4836	(match_operator:DF 1 "minmax_operator"
4837			   [(match_operand:DF 2 "fpr_operand" "%0,f,f")
4838			    (match_operand:DF 3 "fpr_operand" "f,0,f")]))
4839   (clobber (match_operand:CC_FP 4 "fcc_operand" "=u,u,u"))
4840   (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w"))]
4841  "TARGET_COND_MOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE"
4842  "#"
4843  "reload_completed"
4844  [(match_dup 6)]
4845  "operands[6] = frv_split_minmax (operands);"
4846  [(set_attr "length" "12,12,16")
4847   (set_attr "type" "multi")])
4848
4849
4850;; ::::::::::::::::::::
4851;; ::
4852;; :: Call and branch instructions
4853;; ::
4854;; ::::::::::::::::::::
4855
4856;; Subroutine call instruction returning no value.  Operand 0 is the function
4857;; to call; operand 1 is the number of bytes of arguments pushed (in mode
4858;; `SImode', except it is normally a `const_int'); operand 2 is the number of
4859;; registers used as operands.
4860
4861;; On most machines, operand 2 is not actually stored into the RTL pattern.  It
4862;; is supplied for the sake of some RISC machines which need to put this
4863;; information into the assembler code; they can put it in the RTL instead of
4864;; operand 1.
4865
4866(define_expand "call"
4867  [(use (match_operand:QI 0 "" ""))
4868   (use (match_operand 1 "" ""))
4869   (use (match_operand 2 "" ""))
4870   (use (match_operand 3 "" ""))]
4871  ""
4872  "
4873{
4874  rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
4875  rtx addr;
4876
4877  gcc_assert (GET_CODE (operands[0]) == MEM);
4878
4879  addr = XEXP (operands[0], 0);
4880  if (! call_operand (addr, Pmode))
4881    addr = force_reg (Pmode, addr);
4882
4883  if (! operands[2])
4884    operands[2] = const0_rtx;
4885
4886  if (TARGET_FDPIC)
4887    frv_expand_fdpic_call (operands, false, false);
4888  else
4889    emit_call_insn (gen_call_internal (addr, operands[1], operands[2], lr));
4890
4891  DONE;
4892}")
4893
4894(define_insn "call_internal"
4895  [(call (mem:QI (match_operand:SI 0 "call_operand" "S,dNOP"))
4896	 (match_operand 1 "" ""))
4897   (use (match_operand 2 "" ""))
4898   (clobber (match_operand:SI 3 "lr_operand" "=l,l"))]
4899  "! TARGET_FDPIC"
4900  "@
4901   call %0
4902   call%i0l %M0"
4903  [(set_attr "length" "4")
4904   (set_attr "type" "call,jumpl")])
4905
4906;; The odd use of GR0 within the UNSPEC below prevents cseing or
4907;; hoisting function descriptor loads out of loops.  This is almost
4908;; never desirable, since if we preserve the function descriptor in a
4909;; pair of registers, it takes two insns to move it to gr14/gr15, and
4910;; if it's in the stack, we just waste space with the store, since
4911;; we'll have to load back from memory anyway.  And, in the worst
4912;; case, we may end up reusing a function descriptor still pointing at
4913;; a PLT entry, instead of to the resolved function, which means going
4914;; through the resolver for every call that uses the outdated value.
4915;; Bad!
4916
4917;; The explicit MEM inside the SPEC prevents the compiler from moving
4918;; the load before a branch after a NULL test, or before a store that
4919;; initializes a function descriptor.
4920
4921(define_insn "movdi_ldd"
4922  [(set (match_operand:DI 0 "fdpic_fptr_operand" "=e")
4923	(unspec:DI [(mem:DI (match_operand:SI 1 "ldd_address_operand" "p"))
4924		    (reg:SI 0)] UNSPEC_LDD))]
4925  ""
4926  "ldd%I1 %M1, %0"
4927  [(set_attr "length" "4")
4928   (set_attr "type" "gload")])
4929
4930(define_insn "call_fdpicdi"
4931  [(call (mem:QI (match_operand:DI 0 "fdpic_fptr_operand" "W"))
4932	 (match_operand 1 "" ""))
4933   (clobber (match_operand:SI 2 "lr_operand" "=l"))]
4934  "TARGET_FDPIC"
4935  "call%i0l %M0"
4936  [(set_attr "length" "4")
4937   (set_attr "type" "jumpl")])
4938
4939(define_insn "call_fdpicsi"
4940  [(call (mem:QI (match_operand:SI 0 "call_operand" "S,dNOP"))
4941	 (match_operand 1 "" ""))
4942   (use (match_operand 2 "" ""))
4943   (use (match_operand:SI 3 "fdpic_operand" "Z,Z"))
4944   (clobber (match_operand:SI 4 "lr_operand" "=l,l"))]
4945  "TARGET_FDPIC"
4946  "@
4947   call %0
4948   call%i0l %M0"
4949  [(set_attr "length" "4")
4950   (set_attr "type" "call,jumpl")])
4951
4952(define_expand "sibcall"
4953  [(use (match_operand:QI 0 "" ""))
4954   (use (match_operand 1 "" ""))
4955   (use (match_operand 2 "" ""))
4956   (use (match_operand 3 "" ""))]
4957  ""
4958  "
4959{
4960  rtx addr;
4961
4962  gcc_assert (GET_CODE (operands[0]) == MEM);
4963
4964  addr = XEXP (operands[0], 0);
4965  if (! sibcall_operand (addr, Pmode))
4966    addr = force_reg (Pmode, addr);
4967
4968  if (! operands[2])
4969    operands[2] = const0_rtx;
4970
4971  if (TARGET_FDPIC)
4972    frv_expand_fdpic_call (operands, false, true);
4973  else
4974    emit_call_insn (gen_sibcall_internal (addr, operands[1], operands[2]));
4975
4976  DONE;
4977}")
4978
4979;; It might seem that these sibcall patterns are missing references to
4980;; LR, but they're not necessary because sibcall_epilogue will make
4981;; sure LR is restored, and having LR here will set
4982;; regs_ever_used[REG_LR], forcing it to be saved on the stack, and
4983;; then restored in sibcalls and regular return code paths, even if
4984;; the function becomes a leaf function after tail-call elimination.
4985
4986;; We must not use a call-saved register here.  `W' limits ourselves
4987;; to gr14 or gr15, but since we're almost running out of constraint
4988;; letters, and most other call-clobbered registers are often used for
4989;; argument-passing, this will do.
4990(define_insn "sibcall_internal"
4991  [(call (mem:QI (match_operand:SI 0 "sibcall_operand" "WNOP"))
4992	 (match_operand 1 "" ""))
4993   (use (match_operand 2 "" ""))
4994   (return)]
4995  "! TARGET_FDPIC"
4996  "jmp%i0l %M0"
4997  [(set_attr "length" "4")
4998   (set_attr "type" "jumpl")])
4999
5000(define_insn "sibcall_fdpicdi"
5001  [(call (mem:QI (match_operand:DI 0 "fdpic_fptr_operand" "W"))
5002	 (match_operand 1 "" ""))
5003   (return)]
5004  "TARGET_FDPIC"
5005  "jmp%i0l %M0"
5006  [(set_attr "length" "4")
5007   (set_attr "type" "jumpl")])
5008
5009
5010;; Subroutine call instruction returning a value.  Operand 0 is the hard
5011;; register in which the value is returned.  There are three more operands, the
5012;; same as the three operands of the `call' instruction (but with numbers
5013;; increased by one).
5014
5015;; Subroutines that return `BLKmode' objects use the `call' insn.
5016
5017(define_expand "call_value"
5018  [(use (match_operand 0 "" ""))
5019   (use (match_operand:QI 1 "" ""))
5020   (use (match_operand 2 "" ""))
5021   (use (match_operand 3 "" ""))
5022   (use (match_operand 4 "" ""))]
5023  ""
5024  "
5025{
5026  rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
5027  rtx addr;
5028
5029  gcc_assert (GET_CODE (operands[1]) == MEM);
5030
5031  addr = XEXP (operands[1], 0);
5032  if (! call_operand (addr, Pmode))
5033    addr = force_reg (Pmode, addr);
5034
5035  if (! operands[3])
5036    operands[3] = const0_rtx;
5037
5038  if (TARGET_FDPIC)
5039    frv_expand_fdpic_call (operands, true, false);
5040  else
5041    emit_call_insn (gen_call_value_internal (operands[0], addr, operands[2],
5042					     operands[3], lr));
5043
5044  DONE;
5045}")
5046
5047(define_insn "call_value_internal"
5048  [(set (match_operand 0 "register_operand" "=d,d")
5049	(call (mem:QI (match_operand:SI 1 "call_operand" "S,dNOP"))
5050		      (match_operand 2 "" "")))
5051   (use (match_operand 3 "" ""))
5052   (clobber (match_operand:SI 4 "lr_operand" "=l,l"))]
5053  "! TARGET_FDPIC"
5054  "@
5055   call %1
5056   call%i1l %M1"
5057  [(set_attr "length" "4")
5058   (set_attr "type" "call,jumpl")])
5059
5060(define_insn "call_value_fdpicdi"
5061  [(set (match_operand 0 "register_operand" "=d")
5062	(call (mem:QI (match_operand:DI 1 "fdpic_fptr_operand" "W"))
5063	      (match_operand 2 "" "")))
5064   (clobber (match_operand:SI 3 "lr_operand" "=l"))]
5065  "TARGET_FDPIC"
5066  "call%i1l %M1"
5067  [(set_attr "length" "4")
5068   (set_attr "type" "jumpl")])
5069
5070(define_insn "call_value_fdpicsi"
5071  [(set (match_operand 0 "register_operand" "=d,d")
5072	(call (mem:QI (match_operand:SI 1 "call_operand" "S,dNOP"))
5073		      (match_operand 2 "" "")))
5074   (use (match_operand 3 "" ""))
5075   (use (match_operand:SI 4 "fdpic_operand" "Z,Z"))
5076   (clobber (match_operand:SI 5 "lr_operand" "=l,l"))]
5077  "TARGET_FDPIC"
5078  "@
5079   call %1
5080   call%i1l %M1"
5081  [(set_attr "length" "4")
5082   (set_attr "type" "call,jumpl")])
5083
5084(define_expand "sibcall_value"
5085  [(use (match_operand 0 "" ""))
5086   (use (match_operand:QI 1 "" ""))
5087   (use (match_operand 2 "" ""))
5088   (use (match_operand 3 "" ""))
5089   (use (match_operand 4 "" ""))]
5090  ""
5091  "
5092{
5093  rtx addr;
5094
5095  gcc_assert (GET_CODE (operands[1]) == MEM);
5096
5097  addr = XEXP (operands[1], 0);
5098  if (! sibcall_operand (addr, Pmode))
5099    addr = force_reg (Pmode, addr);
5100
5101  if (! operands[3])
5102    operands[3] = const0_rtx;
5103
5104  if (TARGET_FDPIC)
5105    frv_expand_fdpic_call (operands, true, true);
5106  else
5107    emit_call_insn (gen_sibcall_value_internal (operands[0], addr, operands[2],
5108						operands[3]));
5109  DONE;
5110}")
5111
5112(define_insn "sibcall_value_internal"
5113  [(set (match_operand 0 "register_operand" "=d")
5114	(call (mem:QI (match_operand:SI 1 "sibcall_operand" "WNOP"))
5115		      (match_operand 2 "" "")))
5116   (use (match_operand 3 "" ""))
5117   (return)]
5118  "! TARGET_FDPIC"
5119  "jmp%i1l %M1"
5120  [(set_attr "length" "4")
5121   (set_attr "type" "jumpl")])
5122
5123(define_insn "sibcall_value_fdpicdi"
5124  [(set (match_operand 0 "register_operand" "=d")
5125	(call (mem:QI (match_operand:DI 1 "fdpic_fptr_operand" "W"))
5126	      (match_operand 2 "" "")))
5127   (return)]
5128  "TARGET_FDPIC"
5129  "jmp%i1l %M1"
5130  [(set_attr "length" "4")
5131   (set_attr "type" "jumpl")])
5132
5133;; return instruction generated instead of jmp to epilog
5134(define_expand "return"
5135  [(parallel [(return)
5136	      (use (match_dup 0))
5137	      (use (const_int 1))])]
5138  "direct_return_p ()"
5139  "
5140{
5141  operands[0] = gen_rtx_REG (Pmode, LR_REGNO);
5142}")
5143
5144;; return instruction generated by the epilogue
5145(define_expand "epilogue_return"
5146  [(parallel [(return)
5147	      (use (match_operand:SI 0 "register_operand" ""))
5148	      (use (const_int 0))])]
5149  ""
5150  "")
5151
5152(define_insn "*return_internal"
5153  [(return)
5154   (use (match_operand:SI 0 "register_operand" "l,d"))
5155   (use (match_operand:SI 1 "immediate_operand" "n,n"))]
5156  ""
5157  "@
5158    ret
5159    jmpl @(%0,%.)"
5160  [(set_attr "length" "4")
5161   (set_attr "type" "jump,jumpl")])
5162
5163(define_insn "*return_true"
5164  [(set (pc)
5165	(if_then_else (match_operator 0 "integer_relational_operator"
5166				      [(match_operand 1 "icc_operand" "t")
5167				       (const_int 0)])
5168		      (return)
5169		      (pc)))]
5170  "direct_return_p ()"
5171  "b%c0lr %1,%#"
5172  [(set_attr "length" "4")
5173   (set_attr "type" "jump")])
5174
5175(define_insn "*return_false"
5176  [(set (pc)
5177	(if_then_else (match_operator 0 "integer_relational_operator"
5178				      [(match_operand 1 "icc_operand" "t")
5179				       (const_int 0)])
5180		      (pc)
5181		      (return)))]
5182  "direct_return_p ()"
5183  "b%C0lr %1,%#"
5184  [(set_attr "length" "4")
5185   (set_attr "type" "jump")])
5186
5187;; A version of addsi3 for deallocating stack space at the end of the
5188;; epilogue.  The addition is done in parallel with an (unspec_volatile),
5189;; which represents the clobbering of the deallocated space.
5190(define_insn "stack_adjust"
5191  [(set (match_operand:SI 0 "register_operand" "=d")
5192        (plus:SI (match_operand:SI 1 "register_operand" "d")
5193		 (match_operand:SI 2 "general_operand" "dNOP")))
5194   (unspec_volatile [(const_int 0)] UNSPEC_STACK_ADJUST)]
5195  ""
5196  "add%I2 %1,%2,%0"
5197  [(set_attr "length" "4")
5198   (set_attr "type" "int")])
5199
5200;; Normal unconditional jump
5201
5202;; Use the "call" instruction for long branches, but prefer to use "bra" for
5203;; short ones since it does not force us to save the link register.
5204
5205;; This define_insn uses the branch-shortening code to decide which
5206;; instruction it emits.  Since the main branch-shortening interface is
5207;; through get_attr_length(), the two alternatives must be given different
5208;; lengths.  Here we pretend that the far jump is 8 rather than 4 bytes
5209;; long, though both alternatives are really the same size.
5210(define_insn "jump"
5211  [(set (pc) (label_ref (match_operand 0 "" "")))]
5212  ""
5213  "*
5214{
5215  if (get_attr_length (insn) == 4)
5216    return \"bra %l0\";
5217  else
5218    return \"call %l0\";
5219}"
5220  [(set (attr "length")
5221        (if_then_else
5222	    (and (ge (minus (match_dup 0) (pc)) (const_int -32768))
5223		 (le (minus (match_dup 0) (pc)) (const_int 32764)))
5224	    (const_int 4)
5225	    (const_int 8)))
5226   (set (attr "far_jump")
5227        (if_then_else
5228	    (eq_attr "length" "4")
5229	    (const_string "no")
5230	    (const_string "yes")))
5231   (set (attr "type")
5232	(if_then_else
5233	    (eq_attr "length" "4")
5234	    (const_string "jump")
5235	    (const_string "call")))])
5236
5237;; Indirect jump through a register
5238(define_insn "indirect_jump"
5239  [(set (pc) (match_operand:SI 0 "register_operand" "d,l"))]
5240  ""
5241  "@
5242   jmpl @(%0,%.)
5243   bralr"
5244  [(set_attr "length" "4")
5245   (set_attr "type" "jumpl,branch")])
5246
5247;; Instruction to jump to a variable address.  This is a low-level capability
5248;; which can be used to implement a dispatch table when there is no `casesi'
5249;; pattern.  Either the 'casesi' pattern or the 'tablejump' pattern, or both,
5250;; MUST be present in this file.
5251
5252;; This pattern requires two operands: the address or offset, and a label which
5253;; should immediately precede the jump table.  If the macro
5254;; `CASE_VECTOR_PC_RELATIVE' is defined then the first operand is an offset
5255;; which counts from the address of the table; otherwise, it is an absolute
5256;; address to jump to.  In either case, the first operand has mode `Pmode'.
5257
5258;; The `tablejump' insn is always the last insn before the jump table it uses.
5259;; Its assembler code normally has no need to use the second operand, but you
5260;; should incorporate it in the RTL pattern so that the jump optimizer will not
5261;; delete the table as unreachable code.
5262
5263(define_expand "tablejump"
5264  [(parallel [(set (pc) (match_operand:SI 0 "address_operand" "p"))
5265	      (use (label_ref (match_operand 1 "" "")))])]
5266  "!flag_pic"
5267  "")
5268
5269(define_insn "tablejump_insn"
5270  [(set (pc) (match_operand:SI 0 "address_operand" "p"))
5271   (use (label_ref (match_operand 1 "" "")))]
5272  ""
5273  "jmp%I0l %M0"
5274  [(set_attr "length" "4")
5275   (set_attr "type" "jumpl")])
5276
5277;; Implement switch statements when generating PIC code.  Switches are
5278;; implemented by `tablejump' when not using -fpic.
5279
5280;; Emit code here to do the range checking and make the index zero based.
5281;; operand 0 is the index
5282;; operand 1 is the lower bound
5283;; operand 2 is the range of indices (highest - lowest + 1)
5284;; operand 3 is the label that precedes the table itself
5285;; operand 4 is the fall through label
5286
5287(define_expand "casesi"
5288  [(use (match_operand:SI 0 "integer_register_operand" ""))
5289   (use (match_operand:SI 1 "const_int_operand" ""))
5290   (use (match_operand:SI 2 "const_int_operand" ""))
5291   (use (match_operand 3 "" ""))
5292   (use (match_operand 4 "" ""))]
5293  "flag_pic"
5294  "
5295{
5296  rtx indx;
5297  rtx scale;
5298  rtx low = operands[1];
5299  rtx range = operands[2];
5300  rtx table = operands[3];
5301  rtx treg;
5302  rtx fail = operands[4];
5303  rtx mem;
5304  rtx reg2;
5305  rtx reg3;
5306
5307  gcc_assert (GET_CODE (operands[1]) == CONST_INT);
5308
5309  gcc_assert (GET_CODE (operands[2]) == CONST_INT);
5310
5311  /* If we can't generate an immediate instruction, promote to register.  */
5312  if (! IN_RANGE (INTVAL (range), -2048, 2047))
5313    range = force_reg (SImode, range);
5314
5315  /* If low bound is 0, we don't have to subtract it.  */
5316  if (INTVAL (operands[1]) == 0)
5317    indx = operands[0];
5318  else
5319    {
5320      indx = gen_reg_rtx (SImode);
5321      if (IN_RANGE (INTVAL (low), -2047, 2048))
5322	emit_insn (gen_addsi3 (indx, operands[0], GEN_INT (- INTVAL (low))));
5323      else
5324	emit_insn (gen_subsi3 (indx, operands[0], force_reg (SImode, low)));
5325    }
5326
5327  /* Do an unsigned comparison (in the proper mode) between the index
5328     expression and the value which represents the length of the range.
5329     Since we just finished subtracting the lower bound of the range
5330     from the index expression, this comparison allows us to simultaneously
5331     check that the original index expression value is both greater than
5332     or equal to the minimum value of the range and less than or equal to
5333     the maximum value of the range.  */
5334
5335  emit_cmp_and_jump_insns (indx, range, GTU, NULL_RTX, SImode, 1, fail);
5336
5337  /* Move the table address to a register.  */
5338  treg = gen_reg_rtx (Pmode);
5339  emit_insn (gen_movsi (treg, gen_rtx_LABEL_REF (VOIDmode, table)));
5340
5341  /* Scale index-low by wordsize.  */
5342  scale = gen_reg_rtx (SImode);
5343  emit_insn (gen_ashlsi3 (scale, indx, const2_rtx));
5344
5345  /* Load the address, add the start of the table back in,
5346     and jump to it.  */
5347  mem = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, scale, treg));
5348  reg2 = gen_reg_rtx (SImode);
5349  reg3 = gen_reg_rtx (SImode);
5350  emit_insn (gen_movsi (reg2, mem));
5351  emit_insn (gen_addsi3 (reg3, reg2, treg));
5352  emit_jump_insn (gen_tablejump_insn (reg3, table));
5353  DONE;
5354}")
5355
5356
5357;; ::::::::::::::::::::
5358;; ::
5359;; :: Prologue and Epilogue instructions
5360;; ::
5361;; ::::::::::::::::::::
5362
5363;; Called after register allocation to add any instructions needed for the
5364;; prologue.  Using a prologue insn is favored compared to putting all of the
5365;; instructions in the FUNCTION_PROLOGUE macro, since it allows the scheduler
5366;; to intermix instructions with the saves of the caller saved registers.  In
5367;; some cases, it might be necessary to emit a barrier instruction as the last
5368;; insn to prevent such scheduling.
5369(define_expand "prologue"
5370  [(const_int 1)]
5371  ""
5372  "
5373{
5374  frv_expand_prologue ();
5375  DONE;
5376}")
5377
5378;; Called after register allocation to add any instructions needed for the
5379;; epilogue.  Using an epilogue insn is favored compared to putting all of the
5380;; instructions in the FUNCTION_EPILOGUE macro, since it allows the scheduler
5381;; to intermix instructions with the restores of the caller saved registers.
5382;; In some cases, it might be necessary to emit a barrier instruction as the
5383;; first insn to prevent such scheduling.
5384(define_expand "epilogue"
5385  [(const_int 2)]
5386  ""
5387  "
5388{
5389  frv_expand_epilogue (true);
5390  DONE;
5391}")
5392
5393;; This pattern, if defined, emits RTL for exit from a function without the final
5394;; branch back to the calling function.  This pattern will be emitted before any
5395;; sibling call (aka tail call) sites.
5396;;
5397;; The sibcall_epilogue pattern must not clobber any arguments used for
5398;; parameter passing or any stack slots for arguments passed to the current
5399;; function.
5400(define_expand "sibcall_epilogue"
5401  [(const_int 3)]
5402  ""
5403  "
5404{
5405  frv_expand_epilogue (false);
5406  DONE;
5407}")
5408
5409;; Set up the pic register to hold the address of the pic table
5410(define_insn "pic_prologue"
5411  [(set (match_operand:SI 0 "integer_register_operand" "=d")
5412        (unspec_volatile:SI [(const_int 0)] UNSPEC_PIC_PROLOGUE))
5413   (clobber (match_operand:SI 1 "lr_operand" "=l"))
5414   (clobber (match_operand:SI 2 "integer_register_operand" "=d"))]
5415  ""
5416  "*
5417{
5418  static int frv_pic_labelno = 0;
5419
5420  operands[3] = GEN_INT (frv_pic_labelno++);
5421  return \"call %P3\\n%P3:\;movsg %1, %0\;sethi #gprelhi(%P3), %2\;setlo #gprello(%P3), %2\;sub %0,%2,%0\";
5422}"
5423  [(set_attr "length" "16")
5424   (set_attr "type" "multi")])
5425
5426;; ::::::::::::::::::::
5427;; ::
5428;; :: Miscellaneous instructions
5429;; ::
5430;; ::::::::::::::::::::
5431
5432;; No operation, needed in case the user uses -g but not -O.
5433(define_insn "nop"
5434  [(const_int 0)]
5435  ""
5436  "nop"
5437  [(set_attr "length" "4")
5438   (set_attr "type" "int")])
5439
5440(define_insn "fnop"
5441  [(const_int 1)]
5442  ""
5443  "fnop"
5444  [(set_attr "length" "4")
5445   (set_attr "type" "fnop")])
5446
5447(define_insn "mnop"
5448  [(const_int 2)]
5449  ""
5450  "mnop"
5451  [(set_attr "length" "4")
5452   (set_attr "type" "mnop")])
5453
5454;; Pseudo instruction that prevents the scheduler from moving code above this
5455;; point.  Note, type unknown is used to make sure the VLIW instructions are
5456;; not continued past this point.
5457(define_insn "blockage"
5458  [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
5459  ""
5460  "# blockage"
5461  [(set_attr "length" "0")
5462   (set_attr "type" "unknown")])
5463
5464;; ::::::::::::::::::::
5465;; ::
5466;; :: Media instructions
5467;; ::
5468;; ::::::::::::::::::::
5469
5470;; Unimplemented instructions:
5471;;   - MCMPSH, MCMPUH
5472
5473(define_constants
5474  [(UNSPEC_MLOGIC		100)
5475   (UNSPEC_MNOT			101)
5476   (UNSPEC_MAVEH		102)
5477   (UNSPEC_MSATH		103)
5478   (UNSPEC_MADDH		104)
5479   (UNSPEC_MQADDH		105)
5480   (UNSPEC_MPACKH		106)
5481   (UNSPEC_MUNPACKH		107)
5482   (UNSPEC_MDPACKH		108)
5483   (UNSPEC_MBTOH		109)
5484   (UNSPEC_MHTOB		110)
5485   (UNSPEC_MROT			111)
5486   (UNSPEC_MSHIFT		112)
5487   (UNSPEC_MEXPDHW		113)
5488   (UNSPEC_MEXPDHD		114)
5489   (UNSPEC_MWCUT		115)
5490   (UNSPEC_MMULH		116)
5491   (UNSPEC_MMULXH		117)
5492   (UNSPEC_MMACH		118)
5493   (UNSPEC_MMRDH		119)
5494   (UNSPEC_MQMULH		120)
5495   (UNSPEC_MQMULXH		121)
5496   (UNSPEC_MQMACH		122)
5497   (UNSPEC_MCPX			123)
5498   (UNSPEC_MQCPX		124)
5499   (UNSPEC_MCUT			125)
5500   (UNSPEC_MRDACC		126)
5501   (UNSPEC_MRDACCG		127)
5502   (UNSPEC_MWTACC		128)
5503   (UNSPEC_MWTACCG		129)
5504   (UNSPEC_MTRAP		130)
5505   (UNSPEC_MCLRACC		131)
5506   (UNSPEC_MCLRACCA		132)
5507   (UNSPEC_MCOP1		133)
5508   (UNSPEC_MCOP2		134)
5509   (UNSPEC_MDUNPACKH		135)
5510   (UNSPEC_MDUNPACKH_INTERNAL	136)
5511   (UNSPEC_MBTOHE		137)
5512   (UNSPEC_MBTOHE_INTERNAL	138)
5513   (UNSPEC_MBTOHE		137)
5514   (UNSPEC_MBTOHE_INTERNAL	138)
5515   (UNSPEC_MQMACH2		139)
5516   (UNSPEC_MADDACC		140)
5517   (UNSPEC_MDADDACC		141)
5518   (UNSPEC_MABSHS		142)
5519   (UNSPEC_MDROTLI		143)
5520   (UNSPEC_MCPLHI		144)
5521   (UNSPEC_MCPLI		145)
5522   (UNSPEC_MDCUTSSI		146)
5523   (UNSPEC_MQSATHS		147)
5524   (UNSPEC_MHSETLOS		148)
5525   (UNSPEC_MHSETLOH		149)
5526   (UNSPEC_MHSETHIS		150)
5527   (UNSPEC_MHSETHIH		151)
5528   (UNSPEC_MHDSETS		152)
5529   (UNSPEC_MHDSETH		153)
5530   (UNSPEC_MQLCLRHS		154)
5531   (UNSPEC_MQLMTHS		155)
5532   (UNSPEC_MQSLLHI		156)
5533   (UNSPEC_MQSRAHI		157)
5534   (UNSPEC_MASACCS		158)
5535   (UNSPEC_MDASACCS		159)
5536])
5537
5538;; Logic operations: type "mlogic"
5539
5540(define_expand "mand"
5541  [(set (match_operand:SI 0 "fpr_operand" "")
5542        (unspec:SI [(match_operand:SI 1 "fpr_operand" "")
5543		    (match_operand:SI 2 "fpr_operand" "")
5544		    (match_dup 3)]
5545		   UNSPEC_MLOGIC))]
5546  "TARGET_MEDIA"
5547  "operands[3] = GEN_INT (FRV_BUILTIN_MAND);")
5548
5549(define_expand "mor"
5550  [(set (match_operand:SI 0 "fpr_operand" "")
5551        (unspec:SI [(match_operand:SI 1 "fpr_operand" "")
5552		    (match_operand:SI 2 "fpr_operand" "")
5553		    (match_dup 3)]
5554		   UNSPEC_MLOGIC))]
5555  "TARGET_MEDIA"
5556  "operands[3] = GEN_INT (FRV_BUILTIN_MOR);")
5557
5558(define_expand "mxor"
5559  [(set (match_operand:SI 0 "fpr_operand" "")
5560        (unspec:SI [(match_operand:SI 1 "fpr_operand" "")
5561		    (match_operand:SI 2 "fpr_operand" "")
5562		    (match_dup 3)]
5563		   UNSPEC_MLOGIC))]
5564  "TARGET_MEDIA"
5565  "operands[3] = GEN_INT (FRV_BUILTIN_MXOR);")
5566
5567(define_insn "*mlogic"
5568  [(set (match_operand:SI 0 "fpr_operand" "=f")
5569        (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
5570		    (match_operand:SI 2 "fpr_operand" "f")
5571		    (match_operand:SI 3 "const_int_operand" "n")]
5572		   UNSPEC_MLOGIC))]
5573  "TARGET_MEDIA"
5574  "*
5575{
5576  switch (INTVAL (operands[3]))
5577  {
5578  default:		 break;
5579  case FRV_BUILTIN_MAND: return \"mand %1, %2, %0\";
5580  case FRV_BUILTIN_MOR:  return \"mor %1, %2, %0\";
5581  case FRV_BUILTIN_MXOR: return \"mxor %1, %2, %0\";
5582  }
5583
5584  fatal_insn (\"Bad media insn, mlogic\", insn);
5585}"
5586  [(set_attr "length" "4")
5587   (set_attr "type" "mlogic")])
5588
5589(define_insn "*cond_exec_mlogic"
5590  [(cond_exec
5591    (match_operator 0 "ccr_eqne_operator"
5592		    [(match_operand 1 "cr_operand" "C")
5593		     (const_int 0)])
5594    (set (match_operand:SI 2 "fpr_operand" "=f")
5595         (unspec:SI [(match_operand:SI 3 "fpr_operand" "f")
5596		     (match_operand:SI 4 "fpr_operand" "f")
5597		     (match_operand:SI 5 "const_int_operand" "n")]
5598		    UNSPEC_MLOGIC)))]
5599  "TARGET_MEDIA"
5600  "*
5601{
5602  switch (INTVAL (operands[5]))
5603  {
5604  default:		    break;
5605  case FRV_BUILTIN_MAND: return \"cmand %3, %4, %2, %1, %e0\";
5606  case FRV_BUILTIN_MOR:  return \"cmor %3, %4, %2, %1, %e0\";
5607  case FRV_BUILTIN_MXOR: return \"cmxor %3, %4, %2, %1, %e0\";
5608  }
5609
5610  fatal_insn (\"Bad media insn, cond_exec_mlogic\", insn);
5611}"
5612  [(set_attr "length" "4")
5613   (set_attr "type" "mlogic")])
5614
5615;; Logical not: type "mlogic"
5616
5617(define_insn "mnot"
5618  [(set (match_operand:SI 0 "fpr_operand" "=f")
5619        (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")] UNSPEC_MNOT))]
5620  "TARGET_MEDIA"
5621  "mnot %1, %0"
5622  [(set_attr "length" "4")
5623   (set_attr "type" "mlogic")])
5624
5625(define_insn "*cond_exec_mnot"
5626  [(cond_exec
5627    (match_operator 0 "ccr_eqne_operator"
5628		    [(match_operand 1 "cr_operand" "C")
5629		     (const_int 0)])
5630    (set (match_operand:SI 2 "fpr_operand" "=f")
5631         (unspec:SI [(match_operand:SI 3 "fpr_operand" "f")] UNSPEC_MNOT)))]
5632  "TARGET_MEDIA"
5633  "cmnot %3, %2, %1, %e0"
5634  [(set_attr "length" "4")
5635   (set_attr "type" "mlogic")])
5636
5637;; Dual average (halfword): type "maveh"
5638
5639(define_insn "maveh"
5640  [(set (match_operand:SI 0 "fpr_operand" "=f")
5641        (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
5642                    (match_operand:SI 2 "fpr_operand" "f")]
5643		   UNSPEC_MAVEH))]
5644  "TARGET_MEDIA"
5645  "maveh %1, %2, %0"
5646  [(set_attr "length" "4")
5647   (set_attr "type" "maveh")])
5648
5649;; Dual saturation (halfword): type "msath"
5650
5651(define_expand "msaths"
5652  [(set (match_operand:SI 0 "fpr_operand" "=f")
5653        (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
5654                    (match_operand:SI 2 "fpr_operand" "f")
5655		    (match_dup 3)]
5656                   UNSPEC_MSATH))]
5657  "TARGET_MEDIA"
5658  "operands[3] = GEN_INT (FRV_BUILTIN_MSATHS);")
5659
5660(define_expand "msathu"
5661  [(set (match_operand:SI 0 "fpr_operand" "=f")
5662        (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
5663                    (match_operand:SI 2 "fpr_operand" "f")
5664		    (match_dup 3)]
5665                   UNSPEC_MSATH))]
5666  "TARGET_MEDIA"
5667  "operands[3] = GEN_INT (FRV_BUILTIN_MSATHU);")
5668
5669(define_insn "*msath"
5670  [(set (match_operand:SI 0 "fpr_operand" "=f")
5671        (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
5672                    (match_operand:SI 2 "fpr_operand" "f")
5673		    (match_operand:SI 3 "const_int_operand" "n")]
5674		   UNSPEC_MSATH))]
5675  "TARGET_MEDIA"
5676  "*
5677{
5678  switch (INTVAL (operands[3]))
5679  {
5680  default:		    break;
5681  case FRV_BUILTIN_MSATHS:  return \"msaths %1, %2, %0\";
5682  case FRV_BUILTIN_MSATHU:  return \"msathu %1, %2, %0\";
5683  }
5684
5685  fatal_insn (\"Bad media insn, msath\", insn);
5686}"
5687  [(set_attr "length" "4")
5688   (set_attr "type" "msath")])
5689
5690;; Dual addition/subtraction with saturation (halfword): type "maddh"
5691
5692(define_expand "maddhss"
5693  [(set (match_operand:SI 0 "fpr_operand" "=f")
5694        (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
5695                    (match_operand:SI 2 "fpr_operand" "f")
5696		    (match_dup 3)]
5697		   UNSPEC_MADDH))]
5698  "TARGET_MEDIA"
5699  "operands[3] = GEN_INT (FRV_BUILTIN_MADDHSS);")
5700
5701(define_expand "maddhus"
5702  [(set (match_operand:SI 0 "fpr_operand" "=f")
5703        (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
5704                    (match_operand:SI 2 "fpr_operand" "f")
5705		    (match_dup 3)]
5706                   UNSPEC_MADDH))]
5707  "TARGET_MEDIA"
5708  "operands[3] = GEN_INT (FRV_BUILTIN_MADDHUS);")
5709
5710(define_expand "msubhss"
5711  [(set (match_operand:SI 0 "fpr_operand" "=f")
5712        (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
5713                    (match_operand:SI 2 "fpr_operand" "f")
5714		    (match_dup 3)]
5715                   UNSPEC_MADDH))]
5716  "TARGET_MEDIA"
5717  "operands[3] = GEN_INT (FRV_BUILTIN_MSUBHSS);")
5718
5719(define_expand "msubhus"
5720  [(set (match_operand:SI 0 "fpr_operand" "=f")
5721        (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
5722                    (match_operand:SI 2 "fpr_operand" "f")
5723		    (match_dup 3)]
5724                   UNSPEC_MADDH))]
5725  "TARGET_MEDIA"
5726  "operands[3] = GEN_INT (FRV_BUILTIN_MSUBHUS);")
5727
5728(define_insn "*maddh"
5729  [(set (match_operand:SI 0 "fpr_operand" "=f")
5730        (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
5731                    (match_operand:SI 2 "fpr_operand" "f")
5732		    (match_operand:SI 3 "const_int_operand" "n")]
5733		   UNSPEC_MADDH))]
5734  "TARGET_MEDIA"
5735  "*
5736{
5737  switch (INTVAL (operands[3]))
5738  {
5739  default:		    break;
5740  case FRV_BUILTIN_MADDHSS: return \"maddhss %1, %2, %0\";
5741  case FRV_BUILTIN_MADDHUS: return \"maddhus %1, %2, %0\";
5742  case FRV_BUILTIN_MSUBHSS: return \"msubhss %1, %2, %0\";
5743  case FRV_BUILTIN_MSUBHUS: return \"msubhus %1, %2, %0\";
5744  }
5745
5746  fatal_insn (\"Bad media insn, maddh\", insn);
5747}"
5748  [(set_attr "length" "4")
5749   (set_attr "type" "maddh")])
5750
5751(define_insn "*cond_exec_maddh"
5752  [(cond_exec
5753    (match_operator 0 "ccr_eqne_operator"
5754		    [(match_operand 1 "cr_operand" "C")
5755		     (const_int 0)])
5756    (set (match_operand:SI 2 "fpr_operand" "=f")
5757	 (unspec:SI [(match_operand:SI 3 "fpr_operand" "f")
5758		     (match_operand:SI 4 "fpr_operand" "f")
5759		     (match_operand:SI 5 "const_int_operand" "n")]
5760		    UNSPEC_MADDH)))]
5761  "TARGET_MEDIA"
5762  "*
5763{
5764  switch (INTVAL (operands[5]))
5765  {
5766  default:		    break;
5767  case FRV_BUILTIN_MADDHSS: return \"cmaddhss %3, %4, %2, %1, %e0\";
5768  case FRV_BUILTIN_MADDHUS: return \"cmaddhus %3, %4, %2, %1, %e0\";
5769  case FRV_BUILTIN_MSUBHSS: return \"cmsubhss %3, %4, %2, %1, %e0\";
5770  case FRV_BUILTIN_MSUBHUS: return \"cmsubhus %3, %4, %2, %1, %e0\";
5771  }
5772
5773  fatal_insn (\"Bad media insn, cond_exec_maddh\", insn);
5774}"
5775  [(set_attr "length" "4")
5776   (set_attr "type" "maddh")])
5777
5778;; Quad addition/subtraction with saturation (halfword): type "mqaddh"
5779
5780(define_expand "mqaddhss"
5781  [(set (match_operand:DI 0 "even_fpr_operand" "=h")
5782        (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
5783                    (match_operand:DI 2 "even_fpr_operand" "h")
5784		    (match_dup 3)]
5785		   UNSPEC_MQADDH))]
5786  "TARGET_MEDIA"
5787  "operands[3] = GEN_INT (FRV_BUILTIN_MQADDHSS);")
5788
5789(define_expand "mqaddhus"
5790  [(set (match_operand:DI 0 "even_fpr_operand" "=h")
5791        (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
5792                    (match_operand:DI 2 "even_fpr_operand" "h")
5793		    (match_dup 3)]
5794		   UNSPEC_MQADDH))]
5795  "TARGET_MEDIA"
5796  "operands[3] = GEN_INT (FRV_BUILTIN_MQADDHUS);")
5797
5798(define_expand "mqsubhss"
5799  [(set (match_operand:DI 0 "even_fpr_operand" "=h")
5800        (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
5801                    (match_operand:DI 2 "even_fpr_operand" "h")
5802		    (match_dup 3)]
5803		   UNSPEC_MQADDH))]
5804  "TARGET_MEDIA"
5805  "operands[3] = GEN_INT (FRV_BUILTIN_MQSUBHSS);")
5806
5807(define_expand "mqsubhus"
5808  [(set (match_operand:DI 0 "even_fpr_operand" "=h")
5809        (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
5810                    (match_operand:DI 2 "even_fpr_operand" "h")
5811		    (match_dup 3)]
5812		   UNSPEC_MQADDH))]
5813  "TARGET_MEDIA"
5814  "operands[3] = GEN_INT (FRV_BUILTIN_MQSUBHUS);")
5815
5816(define_insn "*mqaddh"
5817  [(set (match_operand:DI 0 "even_fpr_operand" "=h")
5818        (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
5819                    (match_operand:DI 2 "even_fpr_operand" "h")
5820		    (match_operand:SI 3 "const_int_operand" "n")]
5821		   UNSPEC_MQADDH))]
5822  "TARGET_MEDIA"
5823  "*
5824{
5825  switch (INTVAL (operands[3]))
5826  {
5827  default:		     break;
5828  case FRV_BUILTIN_MQADDHSS: return \"mqaddhss %1, %2, %0\";
5829  case FRV_BUILTIN_MQADDHUS: return \"mqaddhus %1, %2, %0\";
5830  case FRV_BUILTIN_MQSUBHSS: return \"mqsubhss %1, %2, %0\";
5831  case FRV_BUILTIN_MQSUBHUS: return \"mqsubhus %1, %2, %0\";
5832  }
5833
5834  fatal_insn (\"Bad media insn, mqaddh\", insn);
5835}"
5836  [(set_attr "length" "4")
5837   (set_attr "type" "mqaddh")])
5838
5839(define_insn "*cond_exec_mqaddh"
5840  [(cond_exec
5841    (match_operator 0 "ccr_eqne_operator"
5842		    [(match_operand 1 "cr_operand" "C")
5843		     (const_int 0)])
5844    (set (match_operand:DI 2 "even_fpr_operand" "=h")
5845         (unspec:DI [(match_operand:DI 3 "even_fpr_operand" "h")
5846                     (match_operand:DI 4 "even_fpr_operand" "h")
5847		     (match_operand:SI 5 "const_int_operand" "n")]
5848		    UNSPEC_MQADDH)))]
5849  "TARGET_MEDIA"
5850  "*
5851{
5852  switch (INTVAL (operands[5]))
5853  {
5854  default:		     break;
5855  case FRV_BUILTIN_MQADDHSS: return \"cmqaddhss %3, %4, %2, %1, %e0\";
5856  case FRV_BUILTIN_MQADDHUS: return \"cmqaddhus %3, %4, %2, %1, %e0\";
5857  case FRV_BUILTIN_MQSUBHSS: return \"cmqsubhss %3, %4, %2, %1, %e0\";
5858  case FRV_BUILTIN_MQSUBHUS: return \"cmqsubhus %3, %4, %2, %1, %e0\";
5859  }
5860
5861  fatal_insn (\"Bad media insn, cond_exec_mqaddh\", insn);
5862}"
5863  [(set_attr "length" "4")
5864   (set_attr "type" "mqaddh")])
5865
5866;; Pack halfword: type "mpackh"
5867
5868(define_insn "mpackh"
5869  [(set (match_operand:SI 0 "fpr_operand" "=f")
5870        (unspec:SI [(match_operand:HI 1 "fpr_operand" "f")
5871                    (match_operand:HI 2 "fpr_operand" "f")]
5872		   UNSPEC_MPACKH))]
5873  "TARGET_MEDIA"
5874  "mpackh %1, %2, %0"
5875  [(set_attr "length" "4")
5876   (set_attr "type" "mpackh")])
5877
5878;; Unpack halfword: type "mpackh"
5879
5880(define_insn "munpackh"
5881  [(set (match_operand:DI 0 "even_fpr_operand" "=h")
5882        (unspec:DI [(match_operand:SI 1 "fpr_operand" "f")]
5883		   UNSPEC_MUNPACKH))]
5884  "TARGET_MEDIA"
5885  "munpackh %1, %0"
5886  [(set_attr "length" "4")
5887   (set_attr "type" "munpackh")])
5888
5889;; Dual pack halfword: type "mdpackh"
5890
5891(define_insn "mdpackh"
5892    [(set (match_operand:DI 0 "even_fpr_operand" "=h")
5893	  (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
5894		      (match_operand:DI 2 "even_fpr_operand" "h")]
5895		     UNSPEC_MDPACKH))]
5896  "TARGET_MEDIA"
5897  "mdpackh %1, %2, %0"
5898  [(set_attr "length" "4")
5899   (set_attr "type" "mdpackh")])
5900
5901;; Byte-halfword conversion: type "mbhconv"
5902
5903(define_insn "mbtoh"
5904  [(set (match_operand:DI 0 "even_fpr_operand" "=h")
5905        (unspec:DI [(match_operand:SI 1 "fpr_operand" "f")]
5906		   UNSPEC_MBTOH))]
5907  "TARGET_MEDIA"
5908  "mbtoh %1, %0"
5909  [(set_attr "length" "4")
5910   (set_attr "type" "mbhconv")])
5911
5912(define_insn "*cond_exec_mbtoh"
5913  [(cond_exec
5914    (match_operator 0 "ccr_eqne_operator"
5915		    [(match_operand 1 "cr_operand" "C")
5916		     (const_int 0)])
5917    (set (match_operand:DI 2 "even_fpr_operand" "=h")
5918	 (unspec:DI [(match_operand:SI 3 "fpr_operand" "f")]
5919		    UNSPEC_MBTOH)))]
5920  "TARGET_MEDIA"
5921  "cmbtoh %3, %2, %1, %e0"
5922  [(set_attr "length" "4")
5923   (set_attr "type" "mbhconv")])
5924
5925(define_insn "mhtob"
5926  [(set (match_operand:SI 0 "fpr_operand" "=f")
5927        (unspec:SI [(match_operand:DI 1 "even_fpr_operand" "h")]
5928		   UNSPEC_MHTOB))]
5929  "TARGET_MEDIA"
5930  "mhtob %1, %0"
5931  [(set_attr "length" "4")
5932   (set_attr "type" "mbhconv")])
5933
5934(define_insn "*cond_exec_mhtob"
5935  [(cond_exec
5936    (match_operator 0 "ccr_eqne_operator"
5937		    [(match_operand 1 "cr_operand" "C")
5938		     (const_int 0)])
5939    (set (match_operand:SI 2 "fpr_operand" "=f")
5940	 (unspec:SI [(match_operand:DI 3 "even_fpr_operand" "h")]
5941		    UNSPEC_MHTOB)))]
5942  "TARGET_MEDIA"
5943  "cmhtob %3, %2, %1, %e0"
5944  [(set_attr "length" "4")
5945   (set_attr "type" "mbhconv")])
5946
5947;; Rotate: type "mrot"
5948
5949(define_expand "mrotli"
5950  [(set (match_operand:SI 0 "fpr_operand" "")
5951        (unspec:SI [(match_operand:SI 1 "fpr_operand" "")
5952                    (match_operand:SI 2 "uint5_operand" "")
5953		    (match_dup 3)]
5954		   UNSPEC_MROT))]
5955  "TARGET_MEDIA"
5956  "operands[3] = GEN_INT (FRV_BUILTIN_MROTLI);")
5957
5958(define_expand "mrotri"
5959  [(set (match_operand:SI 0 "fpr_operand" "")
5960        (unspec:SI [(match_operand:SI 1 "fpr_operand" "")
5961                    (match_operand:SI 2 "uint5_operand" "")
5962		    (match_dup 3)]
5963		   UNSPEC_MROT))]
5964  "TARGET_MEDIA"
5965  "operands[3] = GEN_INT (FRV_BUILTIN_MROTRI);")
5966
5967(define_insn "*mrot"
5968  [(set (match_operand:SI 0 "fpr_operand" "=f")
5969        (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
5970                    (match_operand:SI 2 "uint5_operand" "I")
5971		    (match_operand:SI 3 "const_int_operand" "n")]
5972		   UNSPEC_MROT))]
5973  "TARGET_MEDIA"
5974  "*
5975{
5976  switch (INTVAL (operands[3]))
5977  {
5978  default:		   break;
5979  case FRV_BUILTIN_MROTLI: return \"mrotli %1, %2, %0\";
5980  case FRV_BUILTIN_MROTRI: return \"mrotri %1, %2, %0\";
5981  }
5982
5983  fatal_insn (\"Bad media insn, mrot\", insn);
5984}"
5985  [(set_attr "length" "4")
5986   (set_attr "type" "mrot")])
5987
5988;; Dual shift halfword: type "msh"
5989
5990(define_expand "msllhi"
5991  [(set (match_operand:SI 0 "fpr_operand" "")
5992        (unspec:SI [(match_operand:SI 1 "fpr_operand" "")
5993                    (match_operand:SI 2 "uint4_operand" "")
5994		    (match_dup 3)]
5995		   UNSPEC_MSHIFT))]
5996  "TARGET_MEDIA"
5997  "operands[3] = GEN_INT (FRV_BUILTIN_MSLLHI);")
5998
5999(define_expand "msrlhi"
6000  [(set (match_operand:SI 0 "fpr_operand" "")
6001        (unspec:SI [(match_operand:SI 1 "fpr_operand" "")
6002                    (match_operand:SI 2 "uint4_operand" "")
6003		    (match_dup 3)]
6004		   UNSPEC_MSHIFT))]
6005  "TARGET_MEDIA"
6006  "operands[3] = GEN_INT (FRV_BUILTIN_MSRLHI);")
6007
6008(define_expand "msrahi"
6009  [(set (match_operand:SI 0 "fpr_operand" "")
6010        (unspec:SI [(match_operand:SI 1 "fpr_operand" "")
6011                    (match_operand:SI 2 "uint4_operand" "")
6012		    (match_dup 3)]
6013		   UNSPEC_MSHIFT))]
6014  "TARGET_MEDIA"
6015  "operands[3] = GEN_INT (FRV_BUILTIN_MSRAHI);")
6016
6017(define_insn "*mshift"
6018  [(set (match_operand:SI 0 "fpr_operand" "=f")
6019        (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
6020                    (match_operand:SI 2 "uint4_operand" "I")
6021		    (match_operand:SI 3 "const_int_operand" "n")]
6022		   UNSPEC_MSHIFT))]
6023  "TARGET_MEDIA"
6024  "*
6025{
6026  switch (INTVAL (operands[3]))
6027  {
6028  default:		   break;
6029  case FRV_BUILTIN_MSLLHI: return \"msllhi %1, %2, %0\";
6030  case FRV_BUILTIN_MSRLHI: return \"msrlhi %1, %2, %0\";
6031  case FRV_BUILTIN_MSRAHI: return \"msrahi %1, %2, %0\";
6032  }
6033
6034  fatal_insn (\"Bad media insn, mshift\", insn);
6035}"
6036  [(set_attr "length" "4")
6037   (set_attr "type" "mshift")])
6038
6039;; Expand halfword to word: type "mexpdhw"
6040
6041(define_insn "mexpdhw"
6042  [(set (match_operand:SI 0 "fpr_operand" "=f")
6043        (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
6044                    (match_operand:SI 2 "uint1_operand" "I")]
6045		   UNSPEC_MEXPDHW))]
6046  "TARGET_MEDIA"
6047  "mexpdhw %1, %2, %0"
6048  [(set_attr "length" "4")
6049   (set_attr "type" "mexpdhw")])
6050
6051(define_insn "*cond_exec_mexpdhw"
6052  [(cond_exec
6053    (match_operator 0 "ccr_eqne_operator"
6054		    [(match_operand 1 "cr_operand" "C")
6055		     (const_int 0)])
6056    (set (match_operand:SI 2 "fpr_operand" "=f")
6057	 (unspec:SI [(match_operand:SI 3 "fpr_operand" "f")
6058		     (match_operand:SI 4 "uint1_operand" "I")]
6059		    UNSPEC_MEXPDHW)))]
6060  "TARGET_MEDIA"
6061  "cmexpdhw %3, %4, %2, %1, %e0"
6062  [(set_attr "length" "4")
6063   (set_attr "type" "mexpdhw")])
6064
6065;; Expand halfword to double: type "mexpdhd"
6066
6067(define_insn "mexpdhd"
6068  [(set (match_operand:DI 0 "even_fpr_operand" "=h")
6069        (unspec:DI [(match_operand:SI 1 "fpr_operand" "f")
6070                    (match_operand:SI 2 "uint1_operand" "I")]
6071		   UNSPEC_MEXPDHD))]
6072  "TARGET_MEDIA"
6073  "mexpdhd %1, %2, %0"
6074  [(set_attr "length" "4")
6075   (set_attr "type" "mexpdhd")])
6076
6077(define_insn "*cond_exec_mexpdhd"
6078  [(cond_exec
6079    (match_operator 0 "ccr_eqne_operator"
6080		    [(match_operand 1 "cr_operand" "C")
6081		     (const_int 0)])
6082    (set (match_operand:DI 2 "even_fpr_operand" "=h")
6083	 (unspec:DI [(match_operand:SI 3 "fpr_operand" "f")
6084		     (match_operand:SI 4 "uint1_operand" "I")]
6085		    UNSPEC_MEXPDHD)))]
6086  "TARGET_MEDIA"
6087  "cmexpdhd %3, %4, %2, %1, %e0"
6088  [(set_attr "length" "4")
6089   (set_attr "type" "mexpdhd")])
6090
6091;; FR cut: type "mwcut"
6092
6093(define_insn "mwcut"
6094  [(set (match_operand:SI 0 "fpr_operand" "=f")
6095        (unspec:SI [(match_operand:DI 1 "fpr_operand" "f")
6096                    (match_operand:SI 2 "fpr_or_int6_operand" "fI")]
6097		   UNSPEC_MWCUT))]
6098  "TARGET_MEDIA"
6099  "mwcut%i2 %1, %2, %0"
6100  [(set_attr "length" "4")
6101   (set_attr "type" "mwcut")])
6102
6103;; Dual multiplication (halfword): type "mmulh"
6104
6105(define_expand "mmulhs"
6106  [(parallel [(set (match_operand:DI 0 "even_acc_operand" "=b")
6107		   (unspec:DI [(match_operand:SI 1 "fpr_operand" "f")
6108			       (match_operand:SI 2 "fpr_operand" "f")
6109			       (match_dup 4)]
6110			      UNSPEC_MMULH))
6111	      (set (match_operand:HI 3 "accg_operand" "=B")
6112		   (unspec:HI [(const_int 0)] UNSPEC_MMULH))])]
6113  "TARGET_MEDIA"
6114  "operands[4] = GEN_INT (FRV_BUILTIN_MMULHS);")
6115
6116(define_expand "mmulhu"
6117  [(parallel [(set (match_operand:DI 0 "even_acc_operand" "=b")
6118		   (unspec:DI [(match_operand:SI 1 "fpr_operand" "f")
6119			       (match_operand:SI 2 "fpr_operand" "f")
6120			       (match_dup 4)]
6121			      UNSPEC_MMULH))
6122	      (set (match_operand:HI 3 "accg_operand" "=B")
6123		   (unspec:HI [(const_int 0)] UNSPEC_MMULH))])]
6124  "TARGET_MEDIA"
6125  "operands[4] = GEN_INT (FRV_BUILTIN_MMULHU);")
6126
6127(define_insn "*mmulh"
6128  [(set (match_operand:DI 0 "even_acc_operand" "=b")
6129        (unspec:DI [(match_operand:SI 1 "fpr_operand" "f")
6130                    (match_operand:SI 2 "fpr_operand" "f")
6131		    (match_operand:SI 3 "const_int_operand" "n")]
6132		   UNSPEC_MMULH))
6133   (set (match_operand:HI 4 "accg_operand" "=B")
6134	(unspec:HI [(const_int 0)] UNSPEC_MMULH))]
6135  "TARGET_MEDIA"
6136  "*
6137{
6138  switch (INTVAL (operands[3]))
6139  {
6140  default:		    break;
6141  case FRV_BUILTIN_MMULHS:  return \"mmulhs %1, %2, %0\";
6142  case FRV_BUILTIN_MMULHU:  return \"mmulhu %1, %2, %0\";
6143  }
6144
6145  fatal_insn (\"Bad media insn, mmulh\", insn);
6146}"
6147  [(set_attr "length" "4")
6148   (set_attr "type" "mmulh")])
6149
6150(define_insn "*cond_exec_mmulh"
6151  [(cond_exec
6152    (match_operator 0 "ccr_eqne_operator"
6153		    [(match_operand 1 "cr_operand" "C")
6154		     (const_int 0)])
6155    (parallel [(set (match_operand:DI 2 "even_acc_operand" "=b")
6156		    (unspec:DI [(match_operand:SI 3 "fpr_operand" "f")
6157				(match_operand:SI 4 "fpr_operand" "f")
6158				(match_operand:SI 5 "const_int_operand" "n")]
6159			       UNSPEC_MMULH))
6160	       (set (match_operand:HI 6 "accg_operand" "=B")
6161		    (unspec:HI [(const_int 0)] UNSPEC_MMULH))]))]
6162  "TARGET_MEDIA"
6163  "*
6164{
6165  switch (INTVAL (operands[5]))
6166  {
6167  default:		    break;
6168  case FRV_BUILTIN_MMULHS:  return \"cmmulhs %3, %4, %2, %1, %e0\";
6169  case FRV_BUILTIN_MMULHU:  return \"cmmulhu %3, %4, %2, %1, %e0\";
6170  }
6171
6172  fatal_insn (\"Bad media insn, cond_exec_mmulh\", insn);
6173}"
6174  [(set_attr "length" "4")
6175   (set_attr "type" "mmulh")])
6176
6177;; Dual cross multiplication (halfword): type "mmulxh"
6178
6179(define_expand "mmulxhs"
6180  [(parallel [(set (match_operand:DI 0 "even_acc_operand" "=b")
6181		   (unspec:DI [(match_operand:SI 1 "fpr_operand" "f")
6182			       (match_operand:SI 2 "fpr_operand" "f")
6183			       (match_dup 4)]
6184			      UNSPEC_MMULXH))
6185	      (set (match_operand:HI 3 "accg_operand" "=B")
6186		   (unspec:HI [(const_int 0)] UNSPEC_MMULXH))])]
6187  "TARGET_MEDIA"
6188  "operands[4] = GEN_INT (FRV_BUILTIN_MMULXHS);")
6189
6190(define_expand "mmulxhu"
6191  [(parallel [(set (match_operand:DI 0 "even_acc_operand" "=b")
6192		   (unspec:DI [(match_operand:SI 1 "fpr_operand" "f")
6193			       (match_operand:SI 2 "fpr_operand" "f")
6194			       (match_dup 4)]
6195			      UNSPEC_MMULXH))
6196	      (set (match_operand:HI 3 "accg_operand" "=B")
6197		   (unspec:HI [(const_int 0)] UNSPEC_MMULXH))])]
6198  "TARGET_MEDIA"
6199  "operands[4] = GEN_INT (FRV_BUILTIN_MMULXHU);")
6200
6201(define_insn "*mmulxh"
6202  [(set (match_operand:DI 0 "even_acc_operand" "=b")
6203        (unspec:DI [(match_operand:SI 1 "fpr_operand" "f")
6204                    (match_operand:SI 2 "fpr_operand" "f")
6205		    (match_operand:SI 3 "const_int_operand" "n")]
6206		   UNSPEC_MMULXH))
6207   (set (match_operand:HI 4 "accg_operand" "=B")
6208	(unspec:HI [(const_int 0)] UNSPEC_MMULXH))]
6209  "TARGET_MEDIA"
6210  "*
6211{
6212  switch (INTVAL (operands[3]))
6213  {
6214  default:		    break;
6215  case FRV_BUILTIN_MMULXHS: return \"mmulxhs %1, %2, %0\";
6216  case FRV_BUILTIN_MMULXHU: return \"mmulxhu %1, %2, %0\";
6217  }
6218
6219  fatal_insn (\"Bad media insn, mmulxh\", insn);
6220}"
6221  [(set_attr "length" "4")
6222   (set_attr "type" "mmulxh")])
6223
6224;; Dual product-sum (halfword): type "mmach"
6225
6226(define_expand "mmachs"
6227  [(parallel [(set (match_operand:DI 0 "even_acc_operand" "+b")
6228		   (unspec:DI [(match_dup 0)
6229			       (match_operand:SI 1 "fpr_operand" "f")
6230			       (match_operand:SI 2 "fpr_operand" "f")
6231			       (match_operand:HI 3 "accg_operand" "+B")
6232			       (match_dup 4)]
6233			      UNSPEC_MMACH))
6234	      (set (match_dup 3)
6235		   (unspec:HI [(const_int 0)] UNSPEC_MMACH))])]
6236  "TARGET_MEDIA"
6237  "operands[4] = GEN_INT (FRV_BUILTIN_MMACHS);")
6238
6239(define_expand "mmachu"
6240  [(parallel [(set (match_operand:DI 0 "even_acc_operand" "+b")
6241		   (unspec:DI [(match_dup 0)
6242			       (match_operand:SI 1 "fpr_operand" "f")
6243			       (match_operand:SI 2 "fpr_operand" "f")
6244			       (match_operand:HI 3 "accg_operand" "+B")
6245			       (match_dup 4)]
6246			      UNSPEC_MMACH))
6247	      (set (match_dup 3)
6248		   (unspec:HI [(const_int 0)] UNSPEC_MMACH))])]
6249  "TARGET_MEDIA"
6250  "operands[4] = GEN_INT (FRV_BUILTIN_MMACHU);")
6251
6252(define_insn "*mmach"
6253  [(set (match_operand:DI 0 "even_acc_operand" "+b")
6254        (unspec:DI [(match_dup 0)
6255		    (match_operand:SI 1 "fpr_operand" "f")
6256                    (match_operand:SI 2 "fpr_operand" "f")
6257		    (match_operand:HI 3 "accg_operand" "+B")
6258		    (match_operand:SI 4 "const_int_operand" "n")]
6259		   UNSPEC_MMACH))
6260   (set (match_dup 3) (unspec:HI [(const_int 0)] UNSPEC_MMACH))]
6261  "TARGET_MEDIA"
6262  "*
6263{
6264  switch (INTVAL (operands[4]))
6265  {
6266  default:		   break;
6267  case FRV_BUILTIN_MMACHS: return \"mmachs %1, %2, %0\";
6268  case FRV_BUILTIN_MMACHU: return \"mmachu %1, %2, %0\";
6269  }
6270
6271  fatal_insn (\"Bad media insn, mmach\", insn);
6272}"
6273  [(set_attr "length" "4")
6274   (set_attr "type" "mmach")])
6275
6276(define_insn "*cond_exec_mmach"
6277  [(cond_exec
6278    (match_operator 0 "ccr_eqne_operator"
6279		    [(match_operand 1 "cr_operand" "C")
6280		     (const_int 0)])
6281    (parallel [(set (match_operand:DI 2 "even_acc_operand" "+b")
6282		    (unspec:DI [(match_dup 2)
6283				(match_operand:SI 3 "fpr_operand" "f")
6284				(match_operand:SI 4 "fpr_operand" "f")
6285				(match_operand:HI 5 "accg_operand" "+B")
6286				(match_operand:SI 6 "const_int_operand" "n")]
6287			       UNSPEC_MMACH))
6288	       (set (match_dup 5)
6289		    (unspec:HI [(const_int 0)] UNSPEC_MMACH))]))]
6290  "TARGET_MEDIA"
6291  "*
6292{
6293  switch (INTVAL (operands[6]))
6294  {
6295  default:		   break;
6296  case FRV_BUILTIN_MMACHS: return \"cmmachs %3, %4, %2, %1, %e0\";
6297  case FRV_BUILTIN_MMACHU: return \"cmmachu %3, %4, %2, %1, %e0\";
6298  }
6299
6300  fatal_insn (\"Bad media insn, cond_exec_mmach\", insn);
6301}"
6302  [(set_attr "length" "4")
6303   (set_attr "type" "mmach")])
6304
6305;; Dual product-difference: type "mmrdh"
6306
6307(define_expand "mmrdhs"
6308  [(parallel [(set (match_operand:DI 0 "even_acc_operand" "+b")
6309		   (unspec:DI [(match_dup 0)
6310			       (match_operand:SI 1 "fpr_operand" "f")
6311			       (match_operand:SI 2 "fpr_operand" "f")
6312			       (match_operand:HI 3 "accg_operand" "+B")
6313			       (match_dup 4)]
6314			      UNSPEC_MMRDH))
6315	      (set (match_dup 3)
6316		   (unspec:HI [(const_int 0)] UNSPEC_MMRDH))])]
6317  "TARGET_MEDIA"
6318  "operands[4] = GEN_INT (FRV_BUILTIN_MMRDHS);")
6319
6320(define_expand "mmrdhu"
6321  [(parallel [(set (match_operand:DI 0 "even_acc_operand" "+b")
6322		   (unspec:DI [(match_dup 0)
6323			       (match_operand:SI 1 "fpr_operand" "f")
6324			       (match_operand:SI 2 "fpr_operand" "f")
6325			       (match_operand:HI 3 "accg_operand" "+B")
6326			       (match_dup 4)]
6327			      UNSPEC_MMRDH))
6328	      (set (match_dup 3)
6329		   (unspec:HI [(const_int 0)] UNSPEC_MMRDH))])]
6330  "TARGET_MEDIA"
6331  "operands[4] = GEN_INT (FRV_BUILTIN_MMRDHU);")
6332
6333(define_insn "*mmrdh"
6334  [(set (match_operand:DI 0 "even_acc_operand" "+b")
6335        (unspec:DI [(match_dup 0)
6336		    (match_operand:SI 1 "fpr_operand" "f")
6337                    (match_operand:SI 2 "fpr_operand" "f")
6338		    (match_operand:HI 3 "accg_operand" "+B")
6339		    (match_operand:SI 4 "const_int_operand" "n")]
6340		   UNSPEC_MMRDH))
6341   (set (match_dup 3)
6342	(unspec:HI [(const_int 0)] UNSPEC_MMRDH))]
6343  "TARGET_MEDIA"
6344  "*
6345{
6346  switch (INTVAL (operands[4]))
6347  {
6348  default:		   break;
6349  case FRV_BUILTIN_MMRDHS: return \"mmrdhs %1, %2, %0\";
6350  case FRV_BUILTIN_MMRDHU: return \"mmrdhu %1, %2, %0\";
6351  }
6352
6353  fatal_insn (\"Bad media insn, mrdh\", insn);
6354}"
6355  [(set_attr "length" "4")
6356   (set_attr "type" "mmrdh")])
6357
6358;; Quad multiply (halfword): type "mqmulh"
6359
6360(define_expand "mqmulhs"
6361  [(parallel [(set (match_operand:V4SI 0 "quad_acc_operand" "=A")
6362		   (unspec:V4SI [(match_operand:DI 1 "even_fpr_operand" "h")
6363				 (match_operand:DI 2 "even_fpr_operand" "h")
6364				 (match_dup 4)]
6365				UNSPEC_MQMULH))
6366	      (set (match_operand:V4QI 3 "accg_operand" "=B")
6367		   (unspec:V4QI [(const_int 0)] UNSPEC_MQMULH))])]
6368  "TARGET_MEDIA"
6369  "operands[4] = GEN_INT (FRV_BUILTIN_MQMULHS);")
6370
6371(define_expand "mqmulhu"
6372  [(parallel [(set (match_operand:V4SI 0 "quad_acc_operand" "=A")
6373		   (unspec:V4SI [(match_operand:DI 1 "even_fpr_operand" "h")
6374				 (match_operand:DI 2 "even_fpr_operand" "h")
6375				 (match_dup 4)]
6376				UNSPEC_MQMULH))
6377	      (set (match_operand:V4QI 3 "accg_operand" "=B")
6378		   (unspec:V4QI [(const_int 0)] UNSPEC_MQMULH))])]
6379  "TARGET_MEDIA"
6380  "operands[4] = GEN_INT (FRV_BUILTIN_MQMULHU);")
6381
6382(define_insn "*mqmulh"
6383  [(set (match_operand:V4SI 0 "quad_acc_operand" "=A")
6384        (unspec:V4SI [(match_operand:DI 1 "even_fpr_operand" "h")
6385		      (match_operand:DI 2 "even_fpr_operand" "h")
6386		      (match_operand:SI 3 "const_int_operand" "n")]
6387		     UNSPEC_MQMULH))
6388   (set (match_operand:V4QI 4 "accg_operand" "=B")
6389	(unspec:V4QI [(const_int 0)] UNSPEC_MQMULH))]
6390  "TARGET_MEDIA"
6391  "*
6392{
6393  switch (INTVAL (operands[3]))
6394  {
6395  default:		     break;
6396  case FRV_BUILTIN_MQMULHS:  return \"mqmulhs %1, %2, %0\";
6397  case FRV_BUILTIN_MQMULHU:  return \"mqmulhu %1, %2, %0\";
6398  }
6399
6400  fatal_insn (\"Bad media insn, mqmulh\", insn);
6401}"
6402  [(set_attr "length" "4")
6403   (set_attr "type" "mqmulh")])
6404
6405(define_insn "*cond_exec_mqmulh"
6406  [(cond_exec
6407    (match_operator 0 "ccr_eqne_operator"
6408		    [(match_operand 1 "cr_operand" "C")
6409		     (const_int 0)])
6410    (parallel [(set (match_operand:V4SI 2 "quad_acc_operand" "=A")
6411		    (unspec:V4SI [(match_operand:DI 3 "even_fpr_operand" "h")
6412				  (match_operand:DI 4 "even_fpr_operand" "h")
6413				  (match_operand:SI 5 "const_int_operand" "n")]
6414				 UNSPEC_MQMULH))
6415	       (set (match_operand:V4QI 6 "accg_operand" "=B")
6416		    (unspec:V4QI [(const_int 0)] UNSPEC_MQMULH))]))]
6417  "TARGET_MEDIA"
6418  "*
6419{
6420  switch (INTVAL (operands[5]))
6421  {
6422  default:		     break;
6423  case FRV_BUILTIN_MQMULHS:  return \"cmqmulhs %3, %4, %2, %1, %e0\";
6424  case FRV_BUILTIN_MQMULHU:  return \"cmqmulhu %3, %4, %2, %1, %e0\";
6425  }
6426
6427  fatal_insn (\"Bad media insn, cond_exec_mqmulh\", insn);
6428}"
6429  [(set_attr "length" "4")
6430   (set_attr "type" "mqmulh")])
6431
6432;; Quad cross multiply (halfword): type "mqmulxh"
6433
6434(define_expand "mqmulxhs"
6435  [(parallel [(set (match_operand:V4SI 0 "quad_acc_operand" "=A")
6436		   (unspec:V4SI [(match_operand:DI 1 "even_fpr_operand" "h")
6437				 (match_operand:DI 2 "even_fpr_operand" "h")
6438				 (match_dup 4)]
6439				UNSPEC_MQMULXH))
6440	      (set (match_operand:V4QI 3 "accg_operand" "=B")
6441		   (unspec:V4QI [(const_int 0)] UNSPEC_MQMULXH))])]
6442  "TARGET_MEDIA"
6443  "operands[4] = GEN_INT (FRV_BUILTIN_MQMULXHS);")
6444
6445(define_expand "mqmulxhu"
6446  [(parallel [(set (match_operand:V4SI 0 "quad_acc_operand" "=A")
6447		   (unspec:V4SI [(match_operand:DI 1 "even_fpr_operand" "h")
6448				 (match_operand:DI 2 "even_fpr_operand" "h")
6449				 (match_dup 4)]
6450				UNSPEC_MQMULXH))
6451	      (set (match_operand:V4QI 3 "accg_operand" "=B")
6452		   (unspec:V4QI [(const_int 0)] UNSPEC_MQMULXH))])]
6453  "TARGET_MEDIA"
6454  "operands[4] = GEN_INT (FRV_BUILTIN_MQMULXHU);")
6455
6456(define_insn "*mqmulxh"
6457  [(set (match_operand:V4SI 0 "quad_acc_operand" "=A")
6458        (unspec:V4SI [(match_operand:DI 1 "even_fpr_operand" "h")
6459		      (match_operand:DI 2 "even_fpr_operand" "h")
6460		      (match_operand:SI 3 "const_int_operand" "n")]
6461		     UNSPEC_MQMULXH))
6462   (set (match_operand:V4QI 4 "accg_operand" "=B")
6463	(unspec:V4QI [(const_int 0)] UNSPEC_MQMULXH))]
6464  "TARGET_MEDIA"
6465  "*
6466{
6467  switch (INTVAL (operands[3]))
6468  {
6469  default:		     break;
6470  case FRV_BUILTIN_MQMULXHS: return \"mqmulxhs %1, %2, %0\";
6471  case FRV_BUILTIN_MQMULXHU: return \"mqmulxhu %1, %2, %0\";
6472  }
6473
6474  fatal_insn (\"Bad media insn, mqmulxh\", insn);
6475}"
6476  [(set_attr "length" "4")
6477   (set_attr "type" "mqmulxh")])
6478
6479;; Quad product-sum (halfword): type "mqmach"
6480
6481(define_expand "mqmachs"
6482  [(parallel [(set (match_operand:V4SI 0 "even_acc_operand" "+A")
6483		   (unspec:V4SI [(match_dup 0)
6484				 (match_operand:DI 1 "even_fpr_operand" "h")
6485				 (match_operand:DI 2 "even_fpr_operand" "h")
6486				 (match_operand:V4QI 3 "accg_operand" "+B")
6487				 (match_dup 4)]
6488				UNSPEC_MQMACH))
6489	      (set (match_dup 3)
6490		   (unspec:V4QI [(const_int 0)] UNSPEC_MQMACH))])]
6491  "TARGET_MEDIA"
6492  "operands[4] = GEN_INT (FRV_BUILTIN_MQMACHS);")
6493
6494(define_expand "mqmachu"
6495  [(parallel [(set (match_operand:V4SI 0 "even_acc_operand" "+A")
6496		   (unspec:V4SI [(match_dup 0)
6497				 (match_operand:DI 1 "even_fpr_operand" "h")
6498				 (match_operand:DI 2 "even_fpr_operand" "h")
6499				 (match_operand:V4QI 3 "accg_operand" "+B")
6500				 (match_dup 4)]
6501				UNSPEC_MQMACH))
6502	      (set (match_dup 3)
6503		   (unspec:V4QI [(const_int 0)] UNSPEC_MQMACH))])]
6504  "TARGET_MEDIA"
6505  "operands[4] = GEN_INT (FRV_BUILTIN_MQMACHU);")
6506
6507(define_insn "*mqmach"
6508  [(set (match_operand:V4SI 0 "even_acc_operand" "+A")
6509        (unspec:V4SI [(match_dup 0)
6510		      (match_operand:DI 1 "even_fpr_operand" "h")
6511		      (match_operand:DI 2 "even_fpr_operand" "h")
6512		      (match_operand:V4QI 3 "accg_operand" "+B")
6513		      (match_operand:SI 4 "const_int_operand" "n")]
6514		     UNSPEC_MQMACH))
6515   (set (match_dup 3)
6516	(unspec:V4QI [(const_int 0)] UNSPEC_MQMACH))]
6517  "TARGET_MEDIA"
6518  "*
6519{
6520  switch (INTVAL (operands[4]))
6521  {
6522  default:		    break;
6523  case FRV_BUILTIN_MQMACHS: return \"mqmachs %1, %2, %0\";
6524  case FRV_BUILTIN_MQMACHU: return \"mqmachu %1, %2, %0\";
6525  }
6526
6527  fatal_insn (\"Bad media insn, mqmach\", insn);
6528}"
6529  [(set_attr "length" "4")
6530   (set_attr "type" "mqmach")])
6531
6532(define_insn "*cond_exec_mqmach"
6533  [(cond_exec
6534    (match_operator 0 "ccr_eqne_operator"
6535		    [(match_operand 1 "cr_operand" "C")
6536		     (const_int 0)])
6537    (parallel [(set (match_operand:V4SI 2 "even_acc_operand" "+A")
6538		    (unspec:V4SI [(match_dup 2)
6539				  (match_operand:DI 3 "even_fpr_operand" "h")
6540				  (match_operand:DI 4 "even_fpr_operand" "h")
6541				  (match_operand:V4QI 5 "accg_operand" "+B")
6542				  (match_operand:SI 6 "const_int_operand" "n")]
6543				 UNSPEC_MQMACH))
6544	       (set (match_dup 5)
6545		    (unspec:V4QI [(const_int 0)] UNSPEC_MQMACH))]))]
6546  "TARGET_MEDIA"
6547  "*
6548{
6549  switch (INTVAL (operands[6]))
6550  {
6551  default:		    break;
6552  case FRV_BUILTIN_MQMACHS: return \"cmqmachs %3, %4, %2, %1, %e0\";
6553  case FRV_BUILTIN_MQMACHU: return \"cmqmachu %3, %4, %2, %1, %e0\";
6554  }
6555
6556  fatal_insn (\"Bad media insn, cond_exec_mqmach\", insn);
6557}"
6558  [(set_attr "length" "4")
6559   (set_attr "type" "mqmach")])
6560
6561;; Dual complex number product-sum (halfword)
6562
6563(define_expand "mcpxrs"
6564  [(parallel [(set (match_operand:SI 0 "acc_operand" "=a")
6565		   (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
6566			       (match_operand:SI 2 "fpr_operand" "f")
6567			       (match_dup 4)]
6568			      UNSPEC_MCPX))
6569	      (set (match_operand:QI 3 "accg_operand" "=B")
6570		   (unspec:QI [(const_int 0)] UNSPEC_MCPX))])]
6571  "TARGET_MEDIA"
6572  "operands[4] = GEN_INT (FRV_BUILTIN_MCPXRS);")
6573
6574(define_expand "mcpxru"
6575  [(parallel [(set (match_operand:SI 0 "acc_operand" "=a")
6576		   (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
6577			       (match_operand:SI 2 "fpr_operand" "f")
6578			       (match_dup 4)]
6579			      UNSPEC_MCPX))
6580	      (set (match_operand:QI 3 "accg_operand" "=B")
6581		   (unspec:QI [(const_int 0)] UNSPEC_MCPX))])]
6582  "TARGET_MEDIA"
6583  "operands[4] = GEN_INT (FRV_BUILTIN_MCPXRU);")
6584
6585(define_expand "mcpxis"
6586  [(parallel [(set (match_operand:SI 0 "acc_operand" "=a")
6587		   (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
6588			       (match_operand:SI 2 "fpr_operand" "f")
6589			       (match_dup 4)]
6590			      UNSPEC_MCPX))
6591	      (set (match_operand:QI 3 "accg_operand" "=B")
6592		   (unspec:QI [(const_int 0)] UNSPEC_MCPX))])]
6593  "TARGET_MEDIA"
6594  "operands[4] = GEN_INT (FRV_BUILTIN_MCPXIS);")
6595
6596(define_expand "mcpxiu"
6597  [(parallel [(set (match_operand:SI 0 "acc_operand" "=a")
6598		   (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
6599			       (match_operand:SI 2 "fpr_operand" "f")
6600			       (match_dup 4)]
6601			      UNSPEC_MCPX))
6602	      (set (match_operand:QI 3 "accg_operand" "=B")
6603		   (unspec:QI [(const_int 0)] UNSPEC_MCPX))])]
6604  "TARGET_MEDIA"
6605  "operands[4] = GEN_INT (FRV_BUILTIN_MCPXIU);")
6606
6607(define_insn "*mcpx"
6608  [(parallel [(set (match_operand:SI 0 "acc_operand" "=a")
6609		   (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
6610			       (match_operand:SI 2 "fpr_operand" "f")
6611			       (match_operand:SI 3 "const_int_operand" "n")]
6612			      UNSPEC_MCPX))
6613	      (set (match_operand:QI 4 "accg_operand" "=B")
6614		   (unspec:QI [(const_int 0)] UNSPEC_MCPX))])]
6615  "TARGET_MEDIA"
6616  "*
6617{
6618  switch (INTVAL (operands[3]))
6619  {
6620  default:		   break;
6621  case FRV_BUILTIN_MCPXRS: return \"mcpxrs %1, %2, %0\";
6622  case FRV_BUILTIN_MCPXRU: return \"mcpxru %1, %2, %0\";
6623  case FRV_BUILTIN_MCPXIS: return \"mcpxis %1, %2, %0\";
6624  case FRV_BUILTIN_MCPXIU: return \"mcpxiu %1, %2, %0\";
6625  }
6626
6627  fatal_insn (\"Bad media insn, mcpx\", insn);
6628}"
6629  [(set_attr "length" "4")
6630   (set_attr "type" "mcpx")])
6631
6632(define_insn "*cond_exec_mcpx"
6633  [(cond_exec
6634    (match_operator 0 "ccr_eqne_operator"
6635		    [(match_operand 1 "cr_operand" "C")
6636		     (const_int 0)])
6637    (parallel [(set (match_operand:SI 2 "acc_operand" "=a")
6638		    (unspec:SI [(match_operand:SI 3 "fpr_operand" "f")
6639				(match_operand:SI 4 "fpr_operand" "f")
6640				(match_operand:SI 5 "const_int_operand" "n")]
6641			       UNSPEC_MCPX))
6642	       (set (match_operand:QI 6 "accg_operand" "=B")
6643		    (unspec:QI [(const_int 0)] UNSPEC_MCPX))]))]
6644  "TARGET_MEDIA"
6645  "*
6646{
6647  switch (INTVAL (operands[5]))
6648  {
6649  default:		   break;
6650  case FRV_BUILTIN_MCPXRS: return \"cmcpxrs %3, %4, %2, %1, %e0\";
6651  case FRV_BUILTIN_MCPXRU: return \"cmcpxru %3, %4, %2, %1, %e0\";
6652  case FRV_BUILTIN_MCPXIS: return \"cmcpxis %3, %4, %2, %1, %e0\";
6653  case FRV_BUILTIN_MCPXIU: return \"cmcpxiu %3, %4, %2, %1, %e0\";
6654  }
6655
6656  fatal_insn (\"Bad media insn, cond_exec_mcpx\", insn);
6657}"
6658  [(set_attr "length" "4")
6659   (set_attr "type" "mcpx")])
6660
6661;; Quad complex number product-sum (halfword): type "mqcpx"
6662
6663(define_expand "mqcpxrs"
6664  [(parallel [(set (match_operand:DI 0 "even_acc_operand" "=b")
6665		   (unspec:DI [(match_operand:DI 1 "fpr_operand" "f")
6666			       (match_operand:DI 2 "fpr_operand" "f")
6667			       (match_dup 4)]
6668			      UNSPEC_MQCPX))
6669	      (set (match_operand:HI 3 "accg_operand" "=B")
6670		   (unspec:HI [(const_int 0)] UNSPEC_MQCPX))])]
6671  "TARGET_MEDIA"
6672  "operands[4] = GEN_INT (FRV_BUILTIN_MQCPXRS);")
6673
6674(define_expand "mqcpxru"
6675  [(parallel [(set (match_operand:DI 0 "even_acc_operand" "=b")
6676		   (unspec:DI [(match_operand:DI 1 "fpr_operand" "f")
6677			       (match_operand:DI 2 "fpr_operand" "f")
6678			       (match_dup 4)]
6679			      UNSPEC_MQCPX))
6680	      (set (match_operand:HI 3 "accg_operand" "=B")
6681		   (unspec:HI [(const_int 0)] UNSPEC_MQCPX))])]
6682  "TARGET_MEDIA"
6683  "operands[4] = GEN_INT (FRV_BUILTIN_MQCPXRU);")
6684
6685(define_expand "mqcpxis"
6686  [(parallel [(set (match_operand:DI 0 "even_acc_operand" "=b")
6687		   (unspec:DI [(match_operand:DI 1 "fpr_operand" "f")
6688			       (match_operand:DI 2 "fpr_operand" "f")
6689			       (match_dup 4)]
6690			      UNSPEC_MQCPX))
6691	      (set (match_operand:HI 3 "accg_operand" "=B")
6692		   (unspec:HI [(const_int 0)] UNSPEC_MQCPX))])]
6693  "TARGET_MEDIA"
6694  "operands[4] = GEN_INT (FRV_BUILTIN_MQCPXIS);")
6695
6696(define_expand "mqcpxiu"
6697  [(parallel [(set (match_operand:DI 0 "even_acc_operand" "=b")
6698		   (unspec:DI [(match_operand:DI 1 "fpr_operand" "f")
6699			       (match_operand:DI 2 "fpr_operand" "f")
6700			       (match_dup 4)]
6701			      UNSPEC_MQCPX))
6702	      (set (match_operand:HI 3 "accg_operand" "=B")
6703		   (unspec:HI [(const_int 0)] UNSPEC_MQCPX))])]
6704  "TARGET_MEDIA"
6705  "operands[4] = GEN_INT (FRV_BUILTIN_MQCPXIU);")
6706
6707(define_insn "*mqcpx"
6708  [(set (match_operand:DI 0 "even_acc_operand" "=b")
6709        (unspec:DI [(match_operand:DI 1 "fpr_operand" "f")
6710                    (match_operand:DI 2 "fpr_operand" "f")
6711		    (match_operand:SI 3 "const_int_operand" "n")]
6712		   UNSPEC_MQCPX))
6713   (set (match_operand:HI 4 "accg_operand" "=B")
6714	(unspec:HI [(const_int 0)] UNSPEC_MQCPX))]
6715  "TARGET_MEDIA"
6716  "*
6717{
6718  switch (INTVAL (operands[3]))
6719  {
6720  default:		    break;
6721  case FRV_BUILTIN_MQCPXRS: return \"mqcpxrs %1, %2, %0\";
6722  case FRV_BUILTIN_MQCPXRU: return \"mqcpxru %1, %2, %0\";
6723  case FRV_BUILTIN_MQCPXIS: return \"mqcpxis %1, %2, %0\";
6724  case FRV_BUILTIN_MQCPXIU: return \"mqcpxiu %1, %2, %0\";
6725  }
6726
6727  fatal_insn (\"Bad media insn, mqcpx\", insn);
6728}"
6729  [(set_attr "length" "4")
6730   (set_attr "type" "mqcpx")])
6731
6732;; Cut: type "mcut"
6733
6734(define_expand "mcut"
6735  [(set (match_operand:SI 0 "fpr_operand" "=f")
6736        (unspec:SI [(match_operand:SI 1 "acc_operand" "a")
6737                    (match_operand:SI 2 "fpr_or_int6_operand" "fI")
6738		    (match_operand:QI 3 "accg_operand" "B")
6739		    (match_dup 4)]
6740		   UNSPEC_MCUT))]
6741  "TARGET_MEDIA"
6742  "operands[4] = GEN_INT (FRV_BUILTIN_MCUT);")
6743
6744(define_expand "mcutss"
6745  [(set (match_operand:SI 0 "fpr_operand" "=f")
6746        (unspec:SI [(match_operand:SI 1 "acc_operand" "a")
6747                    (match_operand:SI 2 "fpr_or_int6_operand" "fI")
6748		    (match_operand:QI 3 "accg_operand" "B")
6749		    (match_dup 4)]
6750		   UNSPEC_MCUT))]
6751  "TARGET_MEDIA"
6752  "operands[4] = GEN_INT (FRV_BUILTIN_MCUTSS);")
6753
6754(define_insn "*mcut"
6755  [(set (match_operand:SI 0 "fpr_operand" "=f")
6756        (unspec:SI [(match_operand:SI 1 "acc_operand" "a")
6757                    (match_operand:SI 2 "fpr_or_int6_operand" "fI")
6758		    (match_operand:QI 3 "accg_operand" "B")
6759		    (match_operand:SI 4 "const_int_operand" "n")]
6760		   UNSPEC_MCUT))]
6761  "TARGET_MEDIA"
6762  "*
6763{
6764  switch (INTVAL (operands[4]))
6765  {
6766  default:		   break;
6767  case FRV_BUILTIN_MCUT:   return \"mcut%i2 %1, %2, %0\";
6768  case FRV_BUILTIN_MCUTSS: return \"mcutss%i2 %1, %2, %0\";
6769  }
6770
6771  fatal_insn (\"Bad media insn, mcut\", insn);
6772}"
6773  [(set_attr "length" "4")
6774   (set_attr "type" "mcut")])
6775
6776;; Accumulator read: type "mrdacc"
6777
6778(define_insn "mrdacc"
6779  [(set (match_operand:SI 0 "fpr_operand" "=f")
6780	(unspec:SI [(match_operand:SI 1 "acc_operand" "a")] UNSPEC_MRDACC))]
6781  "TARGET_MEDIA"
6782  "mrdacc %1, %0"
6783  [(set_attr "length" "4")
6784   (set_attr "type" "mrdacc")])
6785
6786(define_insn "mrdaccg"
6787  [(set (match_operand:SI 0 "fpr_operand" "=f")
6788	(unspec:SI [(match_operand:QI 1 "accg_operand" "B")] UNSPEC_MRDACCG))]
6789  "TARGET_MEDIA"
6790  "mrdaccg %1, %0"
6791  [(set_attr "length" "4")
6792   (set_attr "type" "mrdacc")])
6793
6794;; Accumulator write: type "mwtacc"
6795
6796(define_insn "mwtacc"
6797  [(set (match_operand:SI 0 "acc_operand" "=a")
6798	(unspec:SI [(match_operand:SI 1 "fpr_operand" "f")] UNSPEC_MWTACC))]
6799  "TARGET_MEDIA"
6800  "mwtacc %1, %0"
6801  [(set_attr "length" "4")
6802   (set_attr "type" "mwtacc")])
6803
6804(define_insn "mwtaccg"
6805  [(set (match_operand:QI 0 "accg_operand" "=B")
6806	(unspec:QI [(match_operand:SI 1 "fpr_operand" "f")] UNSPEC_MWTACCG))]
6807  "TARGET_MEDIA"
6808  "mwtaccg %1, %0"
6809  [(set_attr "length" "4")
6810   (set_attr "type" "mwtacc")])
6811
6812;; Trap: This one executes on the control unit, not the media units.
6813
6814(define_insn "mtrap"
6815  [(unspec_volatile [(const_int 0)] UNSPEC_MTRAP)]
6816  "TARGET_MEDIA"
6817  "mtrap"
6818  [(set_attr "length" "4")
6819   (set_attr "type" "trap")])
6820
6821;; Clear single accumulator: type "mclracc"
6822
6823(define_insn "mclracc_internal"
6824  [(set (match_operand:SI 0 "acc_operand" "=a")
6825	(unspec:SI [(const_int 0)] UNSPEC_MCLRACC))
6826   (set (match_operand:QI 1 "accg_operand" "=B")
6827	(unspec:QI [(const_int 0)] UNSPEC_MCLRACC))]
6828  "TARGET_MEDIA"
6829  "mclracc %0,#0"
6830  [(set_attr "length" "4")
6831   (set_attr "type" "mclracc")])
6832
6833(define_expand "mclracc"
6834  [(parallel [(set (match_operand:SI 0 "acc_operand" "=a")
6835		   (unspec:SI [(const_int 0)] UNSPEC_MCLRACC))
6836	      (set (match_dup 1)
6837		   (unspec:QI [(const_int 0)] UNSPEC_MCLRACC))])]
6838  "TARGET_MEDIA"
6839  "
6840{
6841  if (GET_CODE (operands[0]) != REG || !ACC_P (REGNO (operands[0])))
6842    FAIL;
6843
6844  operands[1] = frv_matching_accg_for_acc (operands[0]);
6845}")
6846
6847;; Clear all accumulators: type "mclracca"
6848
6849(define_insn "mclracca8_internal"
6850  [(set (match_operand:V4SI 0 "quad_acc_operand" "=b")
6851	(unspec:V4SI [(const_int 0)] UNSPEC_MCLRACCA))
6852   (set (match_operand:V4SI 1 "quad_acc_operand" "=b")
6853	(unspec:V4SI [(const_int 0)] UNSPEC_MCLRACCA))
6854   (set (match_operand:V4QI 2 "accg_operand" "=B")
6855	(unspec:V4QI [(const_int 0)] UNSPEC_MCLRACCA))
6856   (set (match_operand:V4QI 3 "accg_operand" "=B")
6857	(unspec:V4QI [(const_int 0)] UNSPEC_MCLRACCA))]
6858  "TARGET_MEDIA && TARGET_ACC_8"
6859  "mclracc acc0,#1"
6860  [(set_attr "length" "4")
6861   (set_attr "type" "mclracca")])
6862
6863(define_insn "mclracca4_internal"
6864  [(set (match_operand:V4SI 0 "quad_acc_operand" "=b")
6865	(unspec:V4SI [(const_int 0)] UNSPEC_MCLRACCA))
6866   (set (match_operand:V4QI 1 "accg_operand" "=B")
6867	(unspec:V4QI [(const_int 0)] UNSPEC_MCLRACCA))]
6868  "TARGET_MEDIA && TARGET_ACC_4"
6869  "mclracc acc0,#1"
6870  [(set_attr "length" "4")
6871   (set_attr "type" "mclracca")])
6872
6873(define_expand "mclracca8"
6874  [(parallel [(set (match_dup 0) (unspec:V4SI [(const_int 0)] UNSPEC_MCLRACCA))
6875	      (set (match_dup 1) (unspec:V4SI [(const_int 0)] UNSPEC_MCLRACCA))
6876	      (set (match_dup 2) (unspec:V4QI [(const_int 0)] UNSPEC_MCLRACCA))
6877	      (set (match_dup 3) (unspec:V4QI [(const_int 0)] UNSPEC_MCLRACCA))])]
6878  "TARGET_MEDIA && TARGET_ACC_8"
6879  "
6880{
6881  operands[0] = gen_rtx_REG (V4SImode, ACC_FIRST);
6882  operands[1] = gen_rtx_REG (V4SImode, ACC_FIRST + (~3 & ACC_MASK));
6883  operands[2] = gen_rtx_REG (V4QImode, ACCG_FIRST);
6884  operands[3] = gen_rtx_REG (V4QImode, ACCG_FIRST + (~3 & ACC_MASK));
6885}")
6886
6887(define_expand "mclracca4"
6888  [(parallel [(set (match_dup 0) (unspec:V4SI [(const_int 0)] UNSPEC_MCLRACCA))
6889	      (set (match_dup 1) (unspec:V4QI [(const_int 0)] UNSPEC_MCLRACCA))])]
6890  "TARGET_MEDIA && TARGET_ACC_4"
6891  "
6892{
6893  operands[0] = gen_rtx_REG (V4SImode, ACC_FIRST);
6894  operands[1] = gen_rtx_REG (V4QImode, ACCG_FIRST);
6895}")
6896
6897(define_insn "mcop1"
6898  [(set (match_operand:SI 0 "fpr_operand" "=f")
6899        (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
6900                    (match_operand:SI 2 "fpr_operand" "f")] UNSPEC_MCOP1))]
6901  "TARGET_MEDIA_REV1"
6902  "mcop1 %1, %2, %0"
6903  [(set_attr "length" "4")
6904;; What is the class of the insn ???
6905   (set_attr "type" "multi")])
6906
6907(define_insn "mcop2"
6908  [(set (match_operand:SI 0 "fpr_operand" "=f")
6909        (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
6910                    (match_operand:SI 2 "fpr_operand" "f")] UNSPEC_MCOP2))]
6911  "TARGET_MEDIA_REV1"
6912  "mcop2 %1, %2, %0"
6913  [(set_attr "length" "4")
6914;; What is the class of the insn ???
6915   (set_attr "type" "multi")])
6916
6917(define_insn "*mdunpackh_internal"
6918  [(set (match_operand:V4SI 0 "quad_fpr_operand" "=x")
6919        (unspec:V4SI [(match_operand:DI 1 "even_fpr_operand" "h")]
6920		     UNSPEC_MDUNPACKH_INTERNAL))]
6921  "TARGET_MEDIA_REV1"
6922  "mdunpackh %1, %0"
6923  [(set_attr "length" "4")
6924   (set_attr "type" "mdunpackh")])
6925
6926(define_insn_and_split "mdunpackh"
6927  [(set (match_operand:V4SI 0 "memory_operand" "=o")
6928        (unspec:V4SI [(match_operand:DI 1 "even_fpr_operand" "h")]
6929		     UNSPEC_MDUNPACKH))
6930   (clobber (match_scratch:V4SI 2 "=x"))]
6931  "TARGET_MEDIA_REV1"
6932  "#"
6933  "reload_completed"
6934  [(set (match_dup 2)
6935	(unspec:V4SI [(match_dup 1)] UNSPEC_MDUNPACKH_INTERNAL))
6936   (set (match_dup 3)
6937	(match_dup 4))
6938   (set (match_dup 5)
6939	(match_dup 6))]
6940  "
6941{
6942  operands[3] = change_address (operands[0], DImode, NULL_RTX);
6943  operands[4] = gen_rtx_REG (DImode, REGNO (operands[2]));
6944  operands[5] = frv_index_memory (operands[0], DImode, 1);
6945  operands[6] = gen_rtx_REG (DImode, REGNO (operands[2])+2);
6946}"
6947  [(set_attr "length" "20")
6948   (set_attr "type" "multi")])
6949
6950(define_insn "*mbtohe_internal"
6951  [(set (match_operand:V4SI 0 "quad_fpr_operand" "=x")
6952        (unspec:V4SI [(match_operand:SI 1 "fpr_operand" "f")]
6953		     UNSPEC_MBTOHE_INTERNAL))]
6954  "TARGET_MEDIA_REV1"
6955  "mbtohe %1, %0"
6956  [(set_attr "length" "4")
6957   (set_attr "type" "mbhconve")])
6958
6959(define_insn_and_split "mbtohe"
6960  [(set (match_operand:V4SI 0 "memory_operand" "=o")
6961        (unspec:V4SI [(match_operand:SI 1 "fpr_operand" "f")]
6962		     UNSPEC_MBTOHE))
6963   (clobber (match_scratch:V4SI 2 "=x"))]
6964  "TARGET_MEDIA_REV1"
6965  "#"
6966  "reload_completed"
6967  [(set (match_dup 2)
6968	(unspec:V4SI [(match_dup 1)] UNSPEC_MBTOHE_INTERNAL))
6969   (set (match_dup 3)
6970	(match_dup 4))
6971   (set (match_dup 5)
6972	(match_dup 6))]
6973  "
6974{
6975  operands[3] = change_address (operands[0], DImode, NULL_RTX);
6976  operands[4] = gen_rtx_REG (DImode, REGNO (operands[2]));
6977  operands[5] = frv_index_memory (operands[0], DImode, 1);
6978  operands[6] = gen_rtx_REG (DImode, REGNO (operands[2])+2);
6979}"
6980  [(set_attr "length" "20")
6981   (set_attr "type" "multi")])
6982
6983;; Quad product-sum (halfword) instructions only found on the FR400.
6984;; type "mqmach"
6985
6986(define_expand "mqxmachs"
6987  [(parallel [(set (match_operand:V4SI 0 "quad_acc_operand" "")
6988	           (unspec:V4SI [(match_dup 0)
6989		   	         (match_operand:DI 1 "even_fpr_operand" "")
6990			         (match_operand:DI 2 "even_fpr_operand" "")
6991				 (match_operand:V4QI 3 "accg_operand" "")
6992				 (match_dup 4)]
6993				UNSPEC_MQMACH2))
6994		(set (match_dup 3)
6995		     (unspec:V4QI [(const_int 0)] UNSPEC_MQMACH2))])]
6996  "TARGET_MEDIA_REV2"
6997  "operands[4] = GEN_INT (FRV_BUILTIN_MQXMACHS);")
6998
6999(define_expand "mqxmacxhs"
7000  [(parallel [(set (match_operand:V4SI 0 "quad_acc_operand" "")
7001		   (unspec:V4SI [(match_dup 0)
7002				 (match_operand:DI 1 "even_fpr_operand" "")
7003				 (match_operand:DI 2 "even_fpr_operand" "")
7004				 (match_operand:V4QI 3 "accg_operand" "")
7005				 (match_dup 4)]
7006				UNSPEC_MQMACH2))
7007	      (set (match_dup 3)
7008		   (unspec:V4QI [(const_int 0)] UNSPEC_MQMACH2))])]
7009  "TARGET_MEDIA_REV2"
7010  "operands[4] = GEN_INT (FRV_BUILTIN_MQXMACXHS);")
7011
7012(define_expand "mqmacxhs"
7013  [(parallel [(set (match_operand:V4SI 0 "quad_acc_operand" "")
7014		   (unspec:V4SI [(match_dup 0)
7015				 (match_operand:DI 1 "even_fpr_operand" "")
7016				 (match_operand:DI 2 "even_fpr_operand" "")
7017				 (match_operand:V4QI 3 "accg_operand" "")
7018				 (match_dup 4)]
7019				UNSPEC_MQMACH2))
7020	      (set (match_dup 3)
7021		   (unspec:V4QI [(const_int 0)] UNSPEC_MQMACH2))])]
7022  "TARGET_MEDIA_REV2"
7023  "operands[4] = GEN_INT (FRV_BUILTIN_MQMACXHS);")
7024
7025(define_insn "*mqmach2"
7026  [(set (match_operand:V4SI 0 "quad_acc_operand" "+A")
7027        (unspec:V4SI [(match_dup 0)
7028		      (match_operand:DI 1 "even_fpr_operand" "h")
7029		      (match_operand:DI 2 "even_fpr_operand" "h")
7030		      (match_operand:V4QI 3 "accg_operand" "+B")
7031		      (match_operand:SI 4 "const_int_operand" "n")]
7032		     UNSPEC_MQMACH2))
7033   (set (match_dup 3)
7034	(unspec:V4QI [(const_int 0)] UNSPEC_MQMACH2))]
7035  "TARGET_MEDIA_REV2"
7036  "*
7037{
7038  switch (INTVAL (operands[4]))
7039  {
7040  default:		      break;
7041  case FRV_BUILTIN_MQXMACHS:  return \"mqxmachs %1, %2, %0\";
7042  case FRV_BUILTIN_MQXMACXHS: return \"mqxmacxhs %1, %2, %0\";
7043  case FRV_BUILTIN_MQMACXHS:  return \"mqmacxhs %1, %2, %0\";
7044  }
7045
7046  fatal_insn (\"Bad media insn, mqmach2\", insn);
7047}"
7048  [(set_attr "length" "4")
7049   (set_attr "type" "mqmach")])
7050
7051;; Accumulator addition/subtraction: type "maddacc"
7052
7053(define_expand "maddaccs"
7054  [(parallel [(set (match_operand:SI 0 "acc_operand" "")
7055		   (unspec:SI [(match_operand:DI 1 "even_acc_operand" "")]
7056			      UNSPEC_MADDACC))
7057	      (set (match_operand:QI 2 "accg_operand" "")
7058		   (unspec:QI [(match_operand:HI 3 "accg_operand" "")
7059			       (match_dup 4)]
7060			      UNSPEC_MADDACC))])]
7061  "TARGET_MEDIA_REV2"
7062  "operands[4] = GEN_INT (FRV_BUILTIN_MADDACCS);")
7063
7064(define_expand "msubaccs"
7065  [(parallel [(set (match_operand:SI 0 "acc_operand" "")
7066		   (unspec:SI [(match_operand:DI 1 "even_acc_operand" "")]
7067			      UNSPEC_MADDACC))
7068	      (set (match_operand:QI 2 "accg_operand" "")
7069		   (unspec:QI [(match_operand:HI 3 "accg_operand" "")
7070			       (match_dup 4)]
7071			      UNSPEC_MADDACC))])]
7072  "TARGET_MEDIA_REV2"
7073  "operands[4] = GEN_INT (FRV_BUILTIN_MSUBACCS);")
7074
7075(define_insn "masaccs"
7076  [(set (match_operand:DI 0 "even_acc_operand" "=b")
7077	(unspec:DI [(match_operand:DI 1 "even_acc_operand" "b")]
7078		   UNSPEC_MASACCS))
7079   (set (match_operand:HI 2 "accg_operand" "=B")
7080	(unspec:HI [(match_operand:HI 3 "accg_operand" "B")]
7081		   UNSPEC_MASACCS))]
7082  "TARGET_MEDIA_REV2"
7083  "masaccs %1, %0"
7084  [(set_attr "length" "4")
7085   (set_attr "type" "maddacc")])
7086
7087(define_insn "*maddacc"
7088  [(set (match_operand:SI 0 "acc_operand" "=a")
7089	(unspec:SI [(match_operand:DI 1 "even_acc_operand" "b")]
7090		   UNSPEC_MADDACC))
7091   (set (match_operand:QI 2 "accg_operand" "=B")
7092	(unspec:QI [(match_operand:HI 3 "accg_operand" "B")
7093		    (match_operand:SI 4 "const_int_operand" "n")]
7094		   UNSPEC_MADDACC))]
7095  "TARGET_MEDIA_REV2"
7096  "*
7097{
7098  switch (INTVAL (operands[4]))
7099  {
7100  default:		     break;
7101  case FRV_BUILTIN_MADDACCS: return \"maddaccs %1, %0\";
7102  case FRV_BUILTIN_MSUBACCS: return \"msubaccs %1, %0\";
7103  }
7104
7105  fatal_insn (\"Bad media insn, maddacc\", insn);
7106}"
7107  [(set_attr "length" "4")
7108   (set_attr "type" "maddacc")])
7109
7110;; Dual accumulator addition/subtraction: type "mdaddacc"
7111
7112(define_expand "mdaddaccs"
7113  [(parallel [(set (match_operand:DI 0 "even_acc_operand" "")
7114		   (unspec:DI [(match_operand:V4SI 1 "quad_acc_operand" "")]
7115			      UNSPEC_MDADDACC))
7116	      (set (match_operand:HI 2 "accg_operand" "")
7117		   (unspec:HI [(match_operand:V4QI 3 "accg_operand" "")
7118			       (match_dup 4)]
7119			      UNSPEC_MDADDACC))])]
7120  "TARGET_MEDIA_REV2"
7121  "operands[4] = GEN_INT (FRV_BUILTIN_MDADDACCS);")
7122
7123(define_expand "mdsubaccs"
7124  [(parallel [(set (match_operand:DI 0 "even_acc_operand" "")
7125		   (unspec:DI [(match_operand:V4SI 1 "quad_acc_operand" "")]
7126			      UNSPEC_MDADDACC))
7127	      (set (match_operand:HI 2 "accg_operand" "")
7128	      	   (unspec:HI [(match_operand:V4QI 3 "accg_operand" "")
7129			       (match_dup 4)]
7130			      UNSPEC_MDADDACC))])]
7131  "TARGET_MEDIA_REV2"
7132  "operands[4] = GEN_INT (FRV_BUILTIN_MDSUBACCS);")
7133
7134(define_insn "mdasaccs"
7135  [(set (match_operand:V4SI 0 "quad_acc_operand" "=A")
7136	(unspec:V4SI [(match_operand:V4SI 1 "quad_acc_operand" "A")]
7137		     UNSPEC_MDASACCS))
7138   (set (match_operand:V4QI 2 "accg_operand" "=B")
7139	(unspec:V4QI [(match_operand:V4QI 3 "accg_operand" "B")]
7140		     UNSPEC_MDASACCS))]
7141  "TARGET_MEDIA_REV2"
7142  "mdasaccs %1, %0"
7143  [(set_attr "length" "4")
7144   (set_attr "type" "mdaddacc")])
7145
7146(define_insn "*mdaddacc"
7147  [(set (match_operand:DI 0 "even_acc_operand" "=b")
7148	(unspec:DI [(match_operand:V4SI 1 "quad_acc_operand" "A")]
7149		   UNSPEC_MDADDACC))
7150   (set (match_operand:HI 2 "accg_operand" "=B")
7151	(unspec:HI [(match_operand:V4QI 3 "accg_operand" "B")
7152		    (match_operand:SI 4 "const_int_operand" "n")]
7153		   UNSPEC_MDADDACC))]
7154  "TARGET_MEDIA_REV2"
7155  "*
7156{
7157  switch (INTVAL (operands[4]))
7158  {
7159  default:		      break;
7160  case FRV_BUILTIN_MDADDACCS: return \"mdaddaccs %1, %0\";
7161  case FRV_BUILTIN_MDSUBACCS: return \"mdsubaccs %1, %0\";
7162  }
7163
7164  fatal_insn (\"Bad media insn, mdaddacc\", insn);
7165}"
7166  [(set_attr "length" "4")
7167   (set_attr "type" "mdaddacc")])
7168
7169;; Dual absolute (halfword): type "mabsh"
7170
7171(define_insn "mabshs"
7172  [(set (match_operand:SI 0 "fpr_operand" "=f")
7173        (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")] UNSPEC_MABSHS))]
7174  "TARGET_MEDIA_REV2"
7175  "mabshs %1, %0"
7176  [(set_attr "length" "4")
7177   (set_attr "type" "mabsh")])
7178
7179;; Dual rotate: type "mdrot"
7180
7181(define_insn "mdrotli"
7182  [(set (match_operand:DI 0 "even_fpr_operand" "=h")
7183        (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
7184		    (match_operand:SI 2 "uint5_operand" "I")]
7185		   UNSPEC_MDROTLI))]
7186  "TARGET_MEDIA_REV2"
7187  "mdrotli %1, %2, %0"
7188  [(set_attr "length" "4")
7189   (set_attr "type" "mdrot")])
7190
7191;; Dual coupling (concatenation): type "mcpl"
7192
7193(define_insn "mcplhi"
7194  [(set (match_operand:SI 0 "fpr_operand" "=f")
7195        (unspec:SI [(match_operand:DI 1 "fpr_operand" "h")
7196		    (match_operand:SI 2 "uint4_operand" "I")]
7197		   UNSPEC_MCPLHI))]
7198  "TARGET_MEDIA_REV2"
7199  "mcplhi %1, %2, %0"
7200  [(set_attr "length" "4")
7201   (set_attr "type" "mcpl")])
7202
7203(define_insn "mcpli"
7204  [(set (match_operand:SI 0 "fpr_operand" "=f")
7205        (unspec:SI [(match_operand:DI 1 "fpr_operand" "h")
7206		    (match_operand:SI 2 "uint5_operand" "I")]
7207		   UNSPEC_MCPLI))]
7208  "TARGET_MEDIA_REV2"
7209  "mcpli %1, %2, %0"
7210  [(set_attr "length" "4")
7211   (set_attr "type" "mcpl")])
7212
7213;; Dual cut: type "mdcut"
7214
7215(define_insn "mdcutssi"
7216  [(set (match_operand:DI 0 "even_fpr_operand" "=h")
7217        (unspec:DI [(match_operand:DI 1 "even_acc_operand" "b")
7218		    (match_operand:SI 2 "int6_operand" "I")
7219		    (match_operand:HI 3 "accg_operand" "B")]
7220		   UNSPEC_MDCUTSSI))]
7221  "TARGET_MEDIA_REV2"
7222  "mdcutssi %1, %2, %0"
7223  [(set_attr "length" "4")
7224   (set_attr "type" "mdcut")])
7225
7226;; Quad saturate (halfword): type "mqsath"
7227
7228(define_insn "mqsaths"
7229  [(set (match_operand:DI 0 "even_fpr_operand" "=h")
7230        (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
7231		    (match_operand:DI 2 "even_fpr_operand" "h")]
7232		   UNSPEC_MQSATHS))]
7233  "TARGET_MEDIA_REV2"
7234  "mqsaths %1, %2, %0"
7235  [(set_attr "length" "4")
7236   (set_attr "type" "mqsath")])
7237
7238;; Quad limit instructions: type "mqlimh"
7239
7240(define_insn "mqlclrhs"
7241  [(set (match_operand:DI 0 "even_fpr_operand" "=h")
7242        (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
7243		    (match_operand:DI 2 "even_fpr_operand" "h")]
7244		   UNSPEC_MQLCLRHS))]
7245  "TARGET_MEDIA_FR450"
7246  "mqlclrhs %1, %2, %0"
7247  [(set_attr "length" "4")
7248   (set_attr "type" "mqlimh")])
7249
7250(define_insn "mqlmths"
7251  [(set (match_operand:DI 0 "even_fpr_operand" "=h")
7252        (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
7253		    (match_operand:DI 2 "even_fpr_operand" "h")]
7254		   UNSPEC_MQLMTHS))]
7255  "TARGET_MEDIA_FR450"
7256  "mqlmths %1, %2, %0"
7257  [(set_attr "length" "4")
7258   (set_attr "type" "mqlimh")])
7259
7260(define_insn "mqsllhi"
7261  [(set (match_operand:DI 0 "even_fpr_operand" "=h")
7262        (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
7263		    (match_operand:SI 2 "int6_operand" "I")]
7264		   UNSPEC_MQSLLHI))]
7265  "TARGET_MEDIA_FR450"
7266  "mqsllhi %1, %2, %0"
7267  [(set_attr "length" "4")
7268   (set_attr "type" "mqshift")])
7269
7270(define_insn "mqsrahi"
7271  [(set (match_operand:DI 0 "even_fpr_operand" "=h")
7272        (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
7273		    (match_operand:SI 2 "int6_operand" "I")]
7274		   UNSPEC_MQSRAHI))]
7275  "TARGET_MEDIA_FR450"
7276  "mqsrahi %1, %2, %0"
7277  [(set_attr "length" "4")
7278   (set_attr "type" "mqshift")])
7279
7280;; Set hi/lo instructions: type "mset"
7281
7282(define_insn "mhsetlos"
7283  [(set (match_operand:SI 0 "fpr_operand" "=f")
7284	(unspec:SI [(match_operand:SI 1 "fpr_operand" "0")
7285		    (match_operand:SI 2 "int12_operand" "NOP")]
7286		   UNSPEC_MHSETLOS))]
7287  "TARGET_MEDIA_REV2"
7288  "mhsetlos %2, %0"
7289  [(set_attr "length" "4")
7290   (set_attr "type" "mset")])
7291
7292(define_insn "mhsetloh"
7293  [(set (match_operand:SI 0 "fpr_operand" "=f")
7294	(unspec:SI [(match_operand:SI 1 "fpr_operand" "0")
7295		    (match_operand:SI 2 "int5_operand" "I")]
7296		   UNSPEC_MHSETLOH))]
7297  "TARGET_MEDIA_REV2"
7298  "mhsetloh %2, %0"
7299  [(set_attr "length" "4")
7300   (set_attr "type" "mset")])
7301
7302(define_insn "mhsethis"
7303  [(set (match_operand:SI 0 "fpr_operand" "=f")
7304	(unspec:SI [(match_operand:SI 1 "fpr_operand" "0")
7305		    (match_operand:SI 2 "int12_operand" "NOP")]
7306		   UNSPEC_MHSETHIS))]
7307  "TARGET_MEDIA_REV2"
7308  "mhsethis %2, %0"
7309  [(set_attr "length" "4")
7310   (set_attr "type" "mset")])
7311
7312(define_insn "mhsethih"
7313  [(set (match_operand:SI 0 "fpr_operand" "=f")
7314	(unspec:SI [(match_operand:SI 1 "fpr_operand" "0")
7315		    (match_operand:SI 2 "int5_operand" "I")]
7316		   UNSPEC_MHSETHIH))]
7317  "TARGET_MEDIA_REV2"
7318  "mhsethih %2, %0"
7319  [(set_attr "length" "4")
7320   (set_attr "type" "mset")])
7321
7322(define_insn "mhdsets"
7323  [(set (match_operand:SI 0 "fpr_operand" "=f")
7324	(unspec:SI [(match_operand:SI 1 "int12_operand" "NOP")]
7325		   UNSPEC_MHDSETS))]
7326  "TARGET_MEDIA_REV2"
7327  "mhdsets %1, %0"
7328  [(set_attr "length" "4")
7329   (set_attr "type" "mset")])
7330
7331(define_insn "mhdseth"
7332  [(set (match_operand:SI 0 "fpr_operand" "=f")
7333	(unspec:SI [(match_operand:SI 1 "fpr_operand" "0")
7334		    (match_operand:SI 2 "int5_operand" "I")]
7335		   UNSPEC_MHDSETH))]
7336  "TARGET_MEDIA_REV2"
7337  "mhdseth %2, %0"
7338  [(set_attr "length" "4")
7339   (set_attr "type" "mset")])
7340
7341;;-----------------------------------------------------------------------------
7342
7343(define_expand "symGOT2reg"
7344  [(match_operand:SI 0 "" "")
7345   (match_operand:SI 1 "" "")
7346   (match_operand:SI 2 "" "")
7347   (match_operand:SI 3 "" "")]
7348  ""
7349  "
7350{
7351  rtx_insn *insn = emit_insn (gen_symGOT2reg_i (operands[0], operands[1],
7352						operands[2], operands[3]));
7353
7354  MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
7355
7356  set_unique_reg_note (insn, REG_EQUAL, operands[1]);
7357
7358  DONE;
7359}")
7360
7361(define_expand "symGOT2reg_i"
7362  [(set (match_operand:SI 0 "" "")
7363	(mem:SI (plus:SI (match_operand:SI 2 "" "")
7364			 (const:SI (unspec:SI [(match_operand:SI 1 "" "")
7365					       (match_operand:SI 3 "" "")]
7366					      UNSPEC_GOT)))))]
7367  ""
7368  "")
7369
7370(define_expand "symGOT2reg_hilo"
7371  [(set (match_dup 6)
7372	(high:SI (const:SI (unspec:SI [(match_operand:SI 1 "" "")
7373				       (match_dup 4)] UNSPEC_GOT))))
7374   (set (match_dup 5)
7375	(lo_sum:SI (match_dup 6)
7376		   (const:SI (unspec:SI [(match_dup 1)
7377					 (match_operand:SI 3 "" "")]
7378					UNSPEC_GOT))))
7379   (set (match_operand:SI 0 "" "")
7380	(mem:SI (plus:SI (match_dup 5)
7381			 (match_operand:SI 2 "" ""))))
7382   ]
7383  ""
7384  "
7385{
7386  if (!can_create_pseudo_p ())
7387    operands[6] = operands[5] = operands[0];
7388  else
7389    {
7390      operands[6] = gen_reg_rtx (SImode);
7391      operands[5] = gen_reg_rtx (SImode);
7392    }
7393
7394  operands[4] = GEN_INT (INTVAL (operands[3]) + 1);
7395  operands[3] = GEN_INT (INTVAL (operands[3]) + 2);
7396}")
7397
7398(define_expand "symGOTOFF2reg_hilo"
7399  [(set (match_dup 6)
7400	(high:SI (const:SI (unspec:SI [(match_operand:SI 1 "" "")
7401				       (match_dup 4)] UNSPEC_GOT))))
7402   (set (match_dup 5)
7403	(lo_sum:SI (match_dup 6)
7404		   (const:SI (unspec:SI [(match_dup 1)
7405					 (match_operand:SI 3 "" "")]
7406					UNSPEC_GOT))))
7407   (set (match_operand:SI 0 "" "")
7408	(plus:SI (match_dup 5)
7409		 (match_operand:SI 2 "" "")))
7410   ]
7411  ""
7412  "
7413{
7414  if (!can_create_pseudo_p ())
7415    operands[6] = operands[5] = operands[0];
7416  else
7417    {
7418      operands[6] = gen_reg_rtx (SImode);
7419      operands[5] = gen_reg_rtx (SImode);
7420    }
7421
7422  operands[4] = GEN_INT (INTVAL (operands[3]) + 1);
7423  operands[3] = GEN_INT (INTVAL (operands[3]) + 2);
7424}")
7425
7426(define_expand "symGOTOFF2reg"
7427  [(match_operand:SI 0 "" "")
7428   (match_operand:SI 1 "" "")
7429   (match_operand:SI 2 "" "")
7430   (match_operand:SI 3 "" "")]
7431  ""
7432  "
7433{
7434  rtx_insn *insn = emit_insn (gen_symGOTOFF2reg_i (operands[0], operands[1],
7435						   operands[2], operands[3]));
7436
7437  set_unique_reg_note (insn, REG_EQUAL, operands[1]);
7438
7439  DONE;
7440}")
7441
7442(define_expand "symGOTOFF2reg_i"
7443  [(set (match_operand:SI 0 "" "")
7444	(plus:SI (match_operand:SI 2 "" "")
7445		 (const:SI
7446		  (unspec:SI [(match_operand:SI 1 "" "")
7447			     (match_operand:SI 3 "" "")]
7448			     UNSPEC_GOT))))]
7449  ""
7450  "")
7451
7452(define_expand "symGPREL2reg"
7453  [(match_operand:SI 0 "" "")
7454   (match_operand:SI 1 "" "")
7455   (match_operand:SI 2 "" "")
7456   (match_operand:SI 3 "" "")
7457   (match_dup 4)]
7458  ""
7459  "
7460{
7461  if (!can_create_pseudo_p ())
7462    operands[4] = operands[0];
7463  else
7464    operands[4] = gen_reg_rtx (SImode);
7465
7466  emit_insn (frv_gen_GPsym2reg (operands[4], operands[2]));
7467
7468  rtx_insn *insn = emit_insn (gen_symGOTOFF2reg_i (operands[0], operands[1],
7469						   operands[4], operands[3]));
7470
7471  set_unique_reg_note (insn, REG_EQUAL, operands[1]);
7472
7473  DONE;
7474}")
7475
7476(define_expand "symGPREL2reg_hilo"
7477  [(match_operand:SI 0 "" "")
7478   (match_operand:SI 1 "" "")
7479   (match_operand:SI 2 "" "")
7480   (match_operand:SI 3 "" "")
7481   (match_dup 4)]
7482  ""
7483  "
7484{
7485  if (!can_create_pseudo_p ())
7486    {
7487      emit_insn (gen_symGOT2reg (operands[0], operands[1], operands[2],
7488				 GEN_INT (R_FRV_GOT12)));
7489      DONE;
7490    }
7491
7492  operands[4] = gen_reg_rtx (SImode);
7493
7494  emit_insn (frv_gen_GPsym2reg (operands[4], operands[2]));
7495
7496  rtx_insn *insn = emit_insn (gen_symGOTOFF2reg_hilo (operands[0], operands[1],
7497						      operands[4], operands[3]));
7498
7499  set_unique_reg_note (insn, REG_EQUAL, operands[1]);
7500
7501  DONE;
7502}")
7503
7504(define_constants
7505  [
7506   (UNSPEC_SMUL			154)
7507   (UNSPEC_UMUL			155)
7508   (UNSPEC_SMU			156)
7509   (UNSPEC_ADDSS		157)
7510   (UNSPEC_SUBSS		158)
7511   (UNSPEC_SLASS		159)
7512   (UNSPEC_SCAN			160)
7513   (UNSPEC_INTSS                161)
7514   (UNSPEC_SCUTSS		162)
7515   (UNSPEC_PREFETCH0		163)
7516   (UNSPEC_PREFETCH		164)
7517   (UNSPEC_IACCreadll		165)
7518   (UNSPEC_IACCreadl		166)
7519   (UNSPEC_IACCsetll		167)
7520   (UNSPEC_IACCsetl		168)
7521   (UNSPEC_SMASS		169)
7522   (UNSPEC_SMSSS		170)
7523   (UNSPEC_IMUL			171)
7524
7525   (IACC0_REG			171)
7526])
7527
7528(define_insn "smul"
7529  [(set (match_operand:DI 0 "integer_register_operand" "=d")
7530        (unspec:DI [(match_operand:SI 1 "integer_register_operand" "d")
7531		    (match_operand:SI 2 "integer_register_operand" "d")]
7532		   UNSPEC_SMUL))]
7533  ""
7534  "smul %1, %2, %0"
7535  [(set_attr "length" "4")
7536   (set_attr "type" "mul")])
7537
7538(define_insn "umul"
7539  [(set (match_operand:DI 0 "integer_register_operand" "=d")
7540        (unspec:DI [(match_operand:SI 1 "integer_register_operand" "d")
7541		    (match_operand:SI 2 "integer_register_operand" "d")]
7542		   UNSPEC_UMUL))]
7543  ""
7544  "umul %1, %2, %0"
7545  [(set_attr "length" "4")
7546   (set_attr "type" "mul")])
7547
7548(define_insn "smass"
7549  [(set (reg:DI IACC0_REG)
7550	(unspec:DI [(match_operand:SI 0 "integer_register_operand" "d")
7551		    (match_operand:SI 1 "integer_register_operand" "d")
7552		    (reg:DI IACC0_REG)]
7553		   UNSPEC_SMASS))]
7554  "TARGET_FR405_BUILTINS"
7555  "smass %1, %0"
7556  [(set_attr "length" "4")
7557   (set_attr "type" "macc")])
7558
7559(define_insn "smsss"
7560  [(set (reg:DI IACC0_REG)
7561	(unspec:DI [(match_operand:SI 0 "integer_register_operand" "d")
7562		    (match_operand:SI 1 "integer_register_operand" "d")
7563		    (reg:DI IACC0_REG)]
7564		   UNSPEC_SMSSS))]
7565  "TARGET_FR405_BUILTINS"
7566  "smsss %1, %0"
7567  [(set_attr "length" "4")
7568   (set_attr "type" "macc")])
7569
7570(define_insn "smu"
7571  [(set (reg:DI IACC0_REG)
7572	(unspec:DI [(match_operand:SI 0 "integer_register_operand" "d")
7573		    (match_operand:SI 1 "integer_register_operand" "d")]
7574		   UNSPEC_SMU))]
7575  "TARGET_FR405_BUILTINS"
7576  "smu %1, %0"
7577  [(set_attr "length" "4")
7578   (set_attr "type" "macc")])
7579
7580(define_insn "addss"
7581  [(set (match_operand:SI 0 "integer_register_operand" "=d")
7582        (unspec:SI [(match_operand:SI 1 "integer_register_operand" "d")
7583		    (match_operand:SI 2 "integer_register_operand" "d")]
7584		   UNSPEC_ADDSS))]
7585  "TARGET_FR405_BUILTINS"
7586  "addss %1, %2, %0"
7587  [(set_attr "length" "4")
7588   (set_attr "type" "int")])
7589
7590(define_insn "subss"
7591  [(set (match_operand:SI 0 "integer_register_operand" "=d")
7592        (unspec:SI [(match_operand:SI 1 "integer_register_operand" "d")
7593		    (match_operand:SI 2 "integer_register_operand" "d")]
7594		   UNSPEC_SUBSS))]
7595  "TARGET_FR405_BUILTINS"
7596  "subss %1, %2, %0"
7597  [(set_attr "length" "4")
7598   (set_attr "type" "int")])
7599
7600(define_insn "slass"
7601  [(set (match_operand:SI 0 "integer_register_operand" "=d")
7602        (unspec:SI [(match_operand:SI 1 "integer_register_operand" "d")
7603		    (match_operand:SI 2 "integer_register_operand" "d")]
7604		   UNSPEC_SLASS))]
7605  "TARGET_FR405_BUILTINS"
7606  "slass %1, %2, %0"
7607  [(set_attr "length" "4")
7608   (set_attr "type" "int")])
7609
7610(define_insn "scan"
7611  [(set (match_operand:SI 0 "integer_register_operand" "=d")
7612        (unspec:SI [(match_operand:SI 1 "integer_register_operand" "d")
7613		    (match_operand:SI 2 "integer_register_operand" "d")]
7614		   UNSPEC_SCAN))]
7615  ""
7616  "scan %1, %2, %0"
7617  [(set_attr "length" "4")
7618   (set_attr "type" "scan")])
7619
7620(define_insn "scutss"
7621  [(set (match_operand:SI 0 "integer_register_operand" "=d")
7622	(unspec:SI [(match_operand:SI 1 "integer_register_operand" "d")
7623		    (reg:DI IACC0_REG)]
7624		   UNSPEC_SCUTSS))]
7625  "TARGET_FR405_BUILTINS"
7626  "scutss %1,%0"
7627  [(set_attr "length" "4")
7628   (set_attr "type" "cut")])
7629
7630(define_insn "frv_prefetch0"
7631  [(prefetch (unspec:SI [(match_operand:SI 0 "register_operand" "r")]
7632			UNSPEC_PREFETCH0)
7633	     (const_int 0)
7634	     (const_int 0))]
7635  ""
7636  "dcpl %0, gr0, #0"
7637  [(set_attr "length" "4")])
7638
7639(define_insn "frv_prefetch"
7640  [(prefetch (unspec:SI [(match_operand:SI 0 "register_operand" "r")]
7641			UNSPEC_PREFETCH)
7642	     (const_int 0)
7643	     (const_int 0))]
7644  "TARGET_FR500_FR550_BUILTINS"
7645  "nop.p\\n\\tnldub @(%0, gr0), gr0"
7646  [(set_attr "length" "8")])
7647
7648;; TLS patterns
7649
7650(define_insn "call_gettlsoff"
7651  [(set (match_operand:SI 0 "register_operand" "=D09")
7652	(unspec:SI
7653	 [(match_operand:SI 1 "symbolic_operand" "")]
7654	 UNSPEC_GETTLSOFF))
7655   (clobber (reg:SI GR8_REG))
7656   (clobber (reg:SI LRREG))
7657   (use (match_operand:SI 2 "register_operand" "D15"))]
7658  "HAVE_AS_TLS"
7659  "call #gettlsoff(%a1)"
7660  [(set_attr "length" "4")
7661   (set_attr "type" "load_or_call")])
7662
7663;; We have to expand this like a libcall (it sort of actually is)
7664;; because otherwise sched may move, for example, an insn that sets up
7665;; GR8 for a subsequence call before the *tls_indirect_call insn, and
7666;; then reload won't be able to fix things up.
7667(define_expand "tls_indirect_call"
7668  [(set (reg:DI GR8_REG)
7669	(match_operand:DI 2 "register_operand" ""))
7670   (parallel
7671    [(set (reg:SI GR9_REG)
7672	  (unspec:SI
7673	   [(match_operand:SI 1 "symbolic_operand" "")
7674	   (reg:DI GR8_REG)]
7675	   UNSPEC_TLS_INDIRECT_CALL))
7676    (clobber (reg:SI GR8_REG))
7677    (clobber (reg:SI LRREG))
7678    (use (match_operand:SI 3 "register_operand" ""))])
7679   (set (match_operand:SI 0 "register_operand" "")
7680	(reg:SI GR9_REG))]
7681  "HAVE_AS_TLS")
7682
7683(define_insn "*tls_indirect_call"
7684  [(set (reg:SI GR9_REG)
7685	(unspec:SI
7686	 [(match_operand:SI 0 "symbolic_operand" "")
7687	  (reg:DI GR8_REG)]
7688	 UNSPEC_TLS_INDIRECT_CALL))
7689   (clobber (reg:SI GR8_REG))
7690   (clobber (reg:SI LRREG))
7691   ;; If there was a way to represent the fact that we don't need GR9
7692   ;; or GR15 to be set before this instruction (it could be in
7693   ;; parallel), we could use it here.  This change wouldn't apply to
7694   ;; call_gettlsoff, thought, since the linker may turn the latter
7695   ;; into ldi @(gr15,offset),gr9.
7696   (use (match_operand:SI 1 "register_operand" "D15"))]
7697  "HAVE_AS_TLS"
7698  "calll #gettlsoff(%a0)@(gr8,gr0)"
7699  [(set_attr "length" "4")
7700   (set_attr "type" "jumpl")])
7701
7702(define_insn "tls_load_gottlsoff12"
7703  [(set (match_operand:SI 0 "register_operand" "=r")
7704	(unspec:SI
7705	 [(match_operand:SI 1 "symbolic_operand" "")
7706	  (match_operand:SI 2 "register_operand" "r")]
7707	 UNSPEC_TLS_LOAD_GOTTLSOFF12))]
7708  "HAVE_AS_TLS"
7709  "ldi @(%2, #gottlsoff12(%1)), %0"
7710  [(set_attr "length" "4")])
7711
7712(define_expand "tlsoff_hilo"
7713  [(set (match_operand:SI 0 "register_operand" "=r")
7714	(high:SI (const:SI (unspec:SI
7715			    [(match_operand:SI 1 "symbolic_operand" "")
7716			     (match_operand:SI 2 "immediate_operand" "n")]
7717			    UNSPEC_GOT))))
7718   (set (match_dup 0)
7719	(lo_sum:SI (match_dup 0)
7720		   (const:SI (unspec:SI [(match_dup 1)
7721					 (match_dup 3)] UNSPEC_GOT))))]
7722  ""
7723  "
7724{
7725  operands[3] = GEN_INT (INTVAL (operands[2]) + 1);
7726}")
7727
7728;; Just like movdi_ldd, but with relaxation annotations.
7729(define_insn "tls_tlsdesc_ldd"
7730  [(set (match_operand:DI 0 "register_operand" "=r")
7731	(unspec:DI [(mem:DI (unspec:SI
7732			     [(match_operand:SI 1 "register_operand" "r")
7733			      (match_operand:SI 2 "register_operand" "r")
7734			      (match_operand:SI 3 "symbolic_operand" "")]
7735			     UNSPEC_TLS_TLSDESC_LDD_AUX))]
7736		   UNSPEC_TLS_TLSDESC_LDD))]
7737  ""
7738  "ldd #tlsdesc(%a3)@(%1,%2), %0"
7739  [(set_attr "length" "4")
7740   (set_attr "type" "gload")])
7741
7742(define_insn "tls_tlsoff_ld"
7743  [(set (match_operand:SI 0 "register_operand" "=r")
7744	(mem:SI (unspec:SI
7745		 [(match_operand:SI 1 "register_operand" "r")
7746		  (match_operand:SI 2 "register_operand" "r")
7747		  (match_operand:SI 3 "symbolic_operand" "")]
7748		 UNSPEC_TLS_TLSOFF_LD)))]
7749  ""
7750  "ld #tlsoff(%a3)@(%1,%2), %0"
7751  [(set_attr "length" "4")
7752   (set_attr "type" "gload")])
7753
7754(define_insn "tls_lddi"
7755  [(set (match_operand:DI 0 "register_operand" "=r")
7756	(unspec:DI [(match_operand:SI 1 "symbolic_operand" "")
7757		    (match_operand:SI 2 "register_operand" "d")]
7758		   UNSPEC_TLS_LDDI))]
7759  ""
7760  "lddi @(%2, #gottlsdesc12(%a1)), %0"
7761  [(set_attr "length" "4")
7762   (set_attr "type" "gload")])
7763