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