OSDN Git Service

PR middle-end/38584
[pf3gnuchains/gcc-fork.git] / gcc / config / frv / frv.md
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
3731 ;; ::::::::::::::::::::
3732 ;; ::
3733 ;; :: Comparisons
3734 ;; ::
3735 ;; ::::::::::::::::::::
3736
3737 ;; Note, we store the operands in the comparison insns, and use them later
3738 ;; when generating the branch or scc operation.
3739
3740 ;; First the routines called by the machine independent part of the compiler
3741 (define_expand "cmpsi"
3742   [(set (cc0)
3743         (compare (match_operand:SI 0 "integer_register_operand" "")
3744                  (match_operand:SI 1 "gpr_or_int10_operand" "")))]
3745   ""
3746   "
3747 {
3748   frv_compare_op0 = operands[0];
3749   frv_compare_op1 = operands[1];
3750   DONE;
3751 }")
3752
3753 ;(define_expand "cmpdi"
3754 ;  [(set (cc0)
3755 ;        (compare (match_operand:DI 0 "register_operand" "")
3756 ;                (match_operand:DI 1 "nonmemory_operand" "")))]
3757 ;  ""
3758 ;  "
3759 ;{
3760 ;  frv_compare_op0 = operands[0];
3761 ;  frv_compare_op1 = operands[1];
3762 ;  DONE;
3763 ;}")
3764
3765 (define_expand "cmpsf"
3766  [(set (cc0)
3767        (compare (match_operand:SF 0 "fpr_operand" "")
3768                  (match_operand:SF 1 "fpr_operand" "")))]
3769  "TARGET_HARD_FLOAT"
3770  "
3771 {
3772   frv_compare_op0 = operands[0];
3773   frv_compare_op1 = operands[1];
3774   DONE;
3775 }")
3776
3777 (define_expand "cmpdf"
3778   [(set (cc0)
3779         (compare (match_operand:DF 0 "fpr_operand" "")
3780                  (match_operand:DF 1 "fpr_operand" "")))]
3781   "TARGET_HARD_FLOAT && TARGET_DOUBLE"
3782   "
3783 {
3784   frv_compare_op0 = operands[0];
3785   frv_compare_op1 = operands[1];
3786   DONE;
3787 }")
3788
3789 ;; Now, the actual comparisons, generated by the branch and/or scc operations
3790
3791 (define_insn "cmpsi_cc"
3792   [(set (match_operand:CC 0 "icc_operand" "=t,t")
3793         (compare:CC (match_operand:SI 1 "integer_register_operand" "d,d")
3794                     (match_operand:SI 2 "gpr_or_int10_operand" "d,J")))]
3795   ""
3796   "cmp%I2 %1,%2,%0"
3797   [(set_attr "length" "4")
3798    (set_attr "type" "int")])
3799
3800 (define_insn "*cmpsi_cc_uns"
3801   [(set (match_operand:CC_UNS 0 "icc_operand" "=t,t")
3802         (compare:CC_UNS (match_operand:SI 1 "integer_register_operand" "d,d")
3803                         (match_operand:SI 2 "gpr_or_int10_operand" "d,J")))]
3804   ""
3805   "cmp%I2 %1,%2,%0"
3806   [(set_attr "length" "4")
3807    (set_attr "type" "int")])
3808
3809 ;; The only requirement for a CC_NZmode GPR or memory value is that
3810 ;; comparing it against zero must set the Z and N flags appropriately.
3811 ;; The source operand is therefore a valid CC_NZmode value.
3812 (define_insn "*cmpsi_cc_nz"
3813   [(set (match_operand:CC_NZ 0 "nonimmediate_operand" "=t,d,m")
3814         (compare:CC_NZ (match_operand:SI 1 "integer_register_operand" "d,d,d")
3815                        (const_int 0)))]
3816   ""
3817   "@
3818    cmpi %1, #0, %0
3819    mov %1, %0
3820    st%I0%U0 %1, %M0"
3821   [(set_attr "length" "4,4,4")
3822    (set_attr "type" "int,int,gstore")])
3823
3824 (define_insn "*cmpsf_cc_fp"
3825   [(set (match_operand:CC_FP 0 "fcc_operand" "=u")
3826         (compare:CC_FP (match_operand:SF 1 "fpr_operand" "f")
3827                        (match_operand:SF 2 "fpr_operand" "f")))]
3828   "TARGET_HARD_FLOAT"
3829   "fcmps %1,%2,%0"
3830   [(set_attr "length" "4")
3831    (set_attr "type" "fscmp")])
3832
3833 (define_insn "*cmpdf_cc_fp"
3834   [(set (match_operand:CC_FP 0 "fcc_operand" "=u")
3835         (compare:CC_FP (match_operand:DF 1 "even_fpr_operand" "h")
3836                        (match_operand:DF 2 "even_fpr_operand" "h")))]
3837   "TARGET_HARD_FLOAT && TARGET_DOUBLE"
3838   "fcmpd %1,%2,%0"
3839   [(set_attr "length" "4")
3840    (set_attr "type" "fdcmp")])
3841
3842 \f
3843 ;; ::::::::::::::::::::
3844 ;; ::
3845 ;; :: Branches
3846 ;; ::
3847 ;; ::::::::::::::::::::
3848
3849 ;; Define_expands called by the machine independent part of the compiler
3850 ;; to allocate a new comparison register.  Each of these named patterns
3851 ;; must be present, and they cannot be amalgamated into one pattern.
3852 ;;
3853 ;; If a fixed condition code register is being used, (as opposed to, say,
3854 ;; using cc0), then the expands should look like this:
3855 ;;
3856 ;; (define_expand "<name_of_test>"
3857 ;;   [(set (reg:CC <number_of_CC_register>)
3858 ;;      (compare:CC (match_dup 1)
3859 ;;                  (match_dup 2)))
3860 ;;    (set (pc)
3861 ;;      (if_then_else (eq:CC (reg:CC <number_of_CC_register>)
3862 ;;                           (const_int 0))
3863 ;;                    (label_ref (match_operand 0 "" ""))
3864 ;;                    (pc)))]
3865 ;;   ""
3866 ;;   "{
3867 ;;     operands[1] = frv_compare_op0;
3868 ;;     operands[2] = frv_compare_op1;
3869 ;;   }"
3870 ;; )
3871
3872 (define_expand "beq"
3873   [(use (match_operand 0 "" ""))]
3874   ""
3875   "
3876 {
3877   if (! frv_emit_cond_branch (EQ, operands[0]))
3878     FAIL;
3879
3880   DONE;
3881 }")
3882
3883 (define_expand "bne"
3884   [(use (match_operand 0 "" ""))]
3885   ""
3886   "
3887 {
3888   if (! frv_emit_cond_branch (NE, operands[0]))
3889     FAIL;
3890
3891   DONE;
3892 }")
3893
3894 (define_expand "blt"
3895   [(use (match_operand 0 "" ""))]
3896   ""
3897   "
3898 {
3899   if (! frv_emit_cond_branch (LT, operands[0]))
3900     FAIL;
3901
3902   DONE;
3903 }")
3904
3905 (define_expand "ble"
3906   [(use (match_operand 0 "" ""))]
3907   ""
3908   "
3909 {
3910   if (! frv_emit_cond_branch (LE, operands[0]))
3911     FAIL;
3912
3913   DONE;
3914 }")
3915
3916 (define_expand "bgt"
3917   [(use (match_operand 0 "" ""))]
3918   ""
3919   "
3920 {
3921   if (! frv_emit_cond_branch (GT, operands[0]))
3922     FAIL;
3923
3924   DONE;
3925 }")
3926
3927 (define_expand "bge"
3928   [(use (match_operand 0 "" ""))]
3929   ""
3930   "
3931 {
3932   if (! frv_emit_cond_branch (GE, operands[0]))
3933     FAIL;
3934
3935   DONE;
3936 }")
3937
3938 (define_expand "bltu"
3939   [(use (match_operand 0 "" ""))]
3940   ""
3941   "
3942 {
3943   if (! frv_emit_cond_branch (LTU, operands[0]))
3944     FAIL;
3945
3946   DONE;
3947 }")
3948
3949 (define_expand "bleu"
3950   [(use (match_operand 0 "" ""))]
3951   ""
3952   "
3953 {
3954   if (! frv_emit_cond_branch (LEU, operands[0]))
3955     FAIL;
3956
3957   DONE;
3958 }")
3959
3960 (define_expand "bgtu"
3961   [(use (match_operand 0 "" ""))]
3962   ""
3963   "
3964 {
3965   if (! frv_emit_cond_branch (GTU, operands[0]))
3966     FAIL;
3967
3968   DONE;
3969 }")
3970
3971 (define_expand "bgeu"
3972   [(use (match_operand 0 "" ""))]
3973   ""
3974   "
3975 {
3976   if (! frv_emit_cond_branch (GEU, operands[0]))
3977     FAIL;
3978
3979   DONE;
3980 }")
3981
3982 ;; Actual branches.  We must allow for the (label_ref) and the (pc) to be
3983 ;; swapped.  If they are swapped, it reverses the sense of the branch.
3984 ;;
3985 ;; Note - unlike the define expands above, these patterns can be amalgamated
3986 ;; into one pattern for branch-if-true and one for branch-if-false.  This does
3987 ;; require an operand operator to select the correct branch mnemonic.
3988 ;;
3989 ;; If a fixed condition code register is being used, (as opposed to, say,
3990 ;; using cc0), then the expands could look like this:
3991 ;;
3992 ;; (define_insn "*branch_true"
3993 ;;   [(set (pc)
3994 ;;      (if_then_else (match_operator:CC 0 "comparison_operator"
3995 ;;                                       [(reg:CC <number_of_CC_register>)
3996 ;;                                        (const_int 0)])
3997 ;;                    (label_ref (match_operand 1 "" ""))
3998 ;;                    (pc)))]
3999 ;;   ""
4000 ;;   "b%B0 %1"
4001 ;;   [(set_attr "length" "4")]
4002 ;; )
4003 ;;
4004 ;; In the above example the %B is a directive to frv_print_operand()
4005 ;; to decode and print the correct branch mnemonic.
4006
4007 (define_insn "*branch_int_true"
4008   [(set (pc)
4009         (if_then_else (match_operator 0 "integer_relational_operator"
4010                                       [(match_operand 1 "icc_operand" "t")
4011                                        (const_int 0)])
4012                       (label_ref (match_operand 2 "" ""))
4013                       (pc)))]
4014   ""
4015   "*
4016 {
4017   if (get_attr_length (insn) == 4)
4018     return \"b%c0 %1,%#,%l2\";
4019   else
4020     return \"b%C0 %1,%#,1f\;call %l2\\n1:\";
4021 }"
4022   [(set (attr "length")
4023         (if_then_else
4024             (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
4025                  (le (minus (match_dup 2) (pc)) (const_int 32764)))
4026             (const_int 4)
4027             (const_int 8)))
4028    (set (attr "far_jump")
4029         (if_then_else
4030             (eq_attr "length" "4")
4031             (const_string "no")
4032             (const_string "yes")))
4033    (set (attr "type")
4034         (if_then_else
4035             (eq_attr "length" "4")
4036             (const_string "branch")
4037             (const_string "multi")))])
4038
4039 (define_insn "*branch_int_false"
4040   [(set (pc)
4041         (if_then_else (match_operator 0 "integer_relational_operator"
4042                                       [(match_operand 1 "icc_operand" "t")
4043                                        (const_int 0)])
4044                       (pc)
4045                       (label_ref (match_operand 2 "" ""))))]
4046   ""
4047   "*
4048 {
4049   if (get_attr_length (insn) == 4)
4050     return \"b%C0 %1,%#,%l2\";
4051   else
4052     return \"b%c0 %1,%#,1f\;call %l2\\n1:\";
4053 }"
4054   [(set (attr "length")
4055         (if_then_else
4056             (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
4057                  (le (minus (match_dup 2) (pc)) (const_int 32764)))
4058             (const_int 4)
4059             (const_int 8)))
4060    (set (attr "far_jump")
4061         (if_then_else
4062             (eq_attr "length" "4")
4063             (const_string "no")
4064             (const_string "yes")))
4065    (set (attr "type")
4066         (if_then_else
4067             (eq_attr "length" "4")
4068             (const_string "branch")
4069             (const_string "multi")))])
4070
4071 (define_insn "*branch_fp_true"
4072   [(set (pc)
4073         (if_then_else (match_operator:CC_FP 0 "float_relational_operator"
4074                                             [(match_operand 1 "fcc_operand" "u")
4075                                              (const_int 0)])
4076                       (label_ref (match_operand 2 "" ""))
4077                       (pc)))]
4078   ""
4079   "*
4080 {
4081   if (get_attr_length (insn) == 4)
4082     return \"fb%f0 %1,%#,%l2\";
4083   else
4084     return \"fb%F0 %1,%#,1f\;call %l2\\n1:\";
4085 }"
4086   [(set (attr "length")
4087         (if_then_else
4088             (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
4089                  (le (minus (match_dup 2) (pc)) (const_int 32764)))
4090             (const_int 4)
4091             (const_int 8)))
4092    (set (attr "far_jump")
4093         (if_then_else
4094             (eq_attr "length" "4")
4095             (const_string "no")
4096             (const_string "yes")))
4097    (set (attr "type")
4098         (if_then_else
4099             (eq_attr "length" "4")
4100             (const_string "branch")
4101             (const_string "multi")))])
4102
4103 (define_insn "*branch_fp_false"
4104   [(set (pc)
4105         (if_then_else (match_operator:CC_FP 0 "float_relational_operator"
4106                                             [(match_operand 1 "fcc_operand" "u")
4107                                              (const_int 0)])
4108                       (pc)
4109                       (label_ref (match_operand 2 "" ""))))]
4110   ""
4111   "*
4112 {
4113   if (get_attr_length (insn) == 4)
4114     return \"fb%F0 %1,%#,%l2\";
4115   else
4116     return \"fb%f0 %1,%#,1f\;call %l2\\n1:\";
4117 }"
4118   [(set (attr "length")
4119         (if_then_else
4120             (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
4121                  (le (minus (match_dup 2) (pc)) (const_int 32764)))
4122             (const_int 4)
4123             (const_int 8)))
4124    (set (attr "far_jump")
4125         (if_then_else
4126             (eq_attr "length" "4")
4127             (const_string "no")
4128             (const_string "yes")))
4129    (set (attr "type")
4130         (if_then_else
4131             (eq_attr "length" "4")
4132             (const_string "branch")
4133             (const_string "multi")))])
4134
4135 \f
4136 ;; ::::::::::::::::::::
4137 ;; ::
4138 ;; :: Set flag operations
4139 ;; ::
4140 ;; ::::::::::::::::::::
4141
4142 ;; Define_expands called by the machine independent part of the compiler
4143 ;; to allocate a new comparison register
4144
4145 (define_expand "seq"
4146   [(match_operand:SI 0 "integer_register_operand" "")]
4147   "TARGET_SCC"
4148   "
4149 {
4150   if (! frv_emit_scc (EQ, operands[0]))
4151     FAIL;
4152
4153   DONE;
4154 }")
4155
4156 (define_expand "sne"
4157   [(match_operand:SI 0 "integer_register_operand" "")]
4158   "TARGET_SCC"
4159   "
4160 {
4161   if (! frv_emit_scc (NE, operands[0]))
4162     FAIL;
4163
4164   DONE;
4165 }")
4166
4167 (define_expand "slt"
4168   [(match_operand:SI 0 "integer_register_operand" "")]
4169   "TARGET_SCC"
4170   "
4171 {
4172   if (! frv_emit_scc (LT, operands[0]))
4173     FAIL;
4174
4175   DONE;
4176 }")
4177
4178 (define_expand "sle"
4179   [(match_operand:SI 0 "integer_register_operand" "")]
4180   "TARGET_SCC"
4181   "
4182 {
4183   if (! frv_emit_scc (LE, operands[0]))
4184     FAIL;
4185
4186   DONE;
4187 }")
4188
4189 (define_expand "sgt"
4190   [(match_operand:SI 0 "integer_register_operand" "")]
4191   "TARGET_SCC"
4192   "
4193 {
4194   if (! frv_emit_scc (GT, operands[0]))
4195     FAIL;
4196
4197   DONE;
4198 }")
4199
4200 (define_expand "sge"
4201   [(match_operand:SI 0 "integer_register_operand" "")]
4202   "TARGET_SCC"
4203   "
4204 {
4205   if (! frv_emit_scc (GE, operands[0]))
4206     FAIL;
4207
4208   DONE;
4209 }")
4210
4211 (define_expand "sltu"
4212   [(match_operand:SI 0 "integer_register_operand" "")]
4213   "TARGET_SCC"
4214   "
4215 {
4216   if (! frv_emit_scc (LTU, operands[0]))
4217     FAIL;
4218
4219   DONE;
4220 }")
4221
4222 (define_expand "sleu"
4223   [(match_operand:SI 0 "integer_register_operand" "")]
4224   "TARGET_SCC"
4225   "
4226 {
4227   if (! frv_emit_scc (LEU, operands[0]))
4228     FAIL;
4229
4230   DONE;
4231 }")
4232
4233 (define_expand "sgtu"
4234   [(match_operand:SI 0 "integer_register_operand" "")]
4235   "TARGET_SCC"
4236   "
4237 {
4238   if (! frv_emit_scc (GTU, operands[0]))
4239     FAIL;
4240
4241   DONE;
4242 }")
4243
4244 (define_expand "sgeu"
4245   [(match_operand:SI 0 "integer_register_operand" "")]
4246   "TARGET_SCC"
4247   "
4248 {
4249   if (! frv_emit_scc (GEU, operands[0]))
4250     FAIL;
4251
4252   DONE;
4253 }")
4254
4255 (define_insn "*scc_int"
4256   [(set (match_operand:SI 0 "integer_register_operand" "=d")
4257         (match_operator:SI 1 "integer_relational_operator"
4258                            [(match_operand 2 "icc_operand" "t")
4259                             (const_int 0)]))
4260    (clobber (match_operand:CC_CCR 3 "icr_operand" "=v"))]
4261   ""
4262   "#"
4263   [(set_attr "length" "12")
4264    (set_attr "type" "multi")])
4265
4266 (define_insn "*scc_float"
4267   [(set (match_operand:SI 0 "integer_register_operand" "=d")
4268         (match_operator:SI 1 "float_relational_operator"
4269                            [(match_operand:CC_FP 2 "fcc_operand" "u")
4270                             (const_int 0)]))
4271    (clobber (match_operand:CC_CCR 3 "fcr_operand" "=w"))]
4272   ""
4273   "#"
4274   [(set_attr "length" "12")
4275    (set_attr "type" "multi")])
4276
4277 ;; XXX -- add reload_completed to the splits, because register allocation
4278 ;; currently isn't ready to see cond_exec packets.
4279 (define_split
4280   [(set (match_operand:SI 0 "integer_register_operand" "")
4281         (match_operator:SI 1 "relational_operator"
4282                            [(match_operand 2 "cc_operand" "")
4283                             (const_int 0)]))
4284    (clobber (match_operand 3 "cr_operand" ""))]
4285   "reload_completed"
4286   [(match_dup 4)]
4287   "operands[4] = frv_split_scc (operands[0], operands[1], operands[2],
4288                                 operands[3], (HOST_WIDE_INT) 1);")
4289
4290 (define_insn "*scc_neg1_int"
4291   [(set (match_operand:SI 0 "integer_register_operand" "=d")
4292         (neg:SI (match_operator:SI 1 "integer_relational_operator"
4293                                    [(match_operand 2 "icc_operand" "t")
4294                                     (const_int 0)])))
4295    (clobber (match_operand:CC_CCR 3 "icr_operand" "=v"))]
4296   ""
4297   "#"
4298   [(set_attr "length" "12")
4299    (set_attr "type" "multi")])
4300
4301 (define_insn "*scc_neg1_float"
4302   [(set (match_operand:SI 0 "integer_register_operand" "=d")
4303         (neg:SI (match_operator:SI 1 "float_relational_operator"
4304                                    [(match_operand:CC_FP 2 "fcc_operand" "u")
4305                                     (const_int 0)])))
4306    (clobber (match_operand:CC_CCR 3 "fcr_operand" "=w"))]
4307   ""
4308   "#"
4309   [(set_attr "length" "12")
4310    (set_attr "type" "multi")])
4311
4312 (define_split
4313   [(set (match_operand:SI 0 "integer_register_operand" "")
4314         (neg:SI (match_operator:SI 1 "relational_operator"
4315                                    [(match_operand 2 "cc_operand" "")
4316                                     (const_int 0)])))
4317    (clobber (match_operand 3 "cr_operand" ""))]
4318   "reload_completed"
4319   [(match_dup 4)]
4320   "operands[4] = frv_split_scc (operands[0], operands[1], operands[2],
4321                                 operands[3], (HOST_WIDE_INT) -1);")
4322
4323 \f
4324 ;; ::::::::::::::::::::
4325 ;; ::
4326 ;; :: Conditionally executed instructions
4327 ;; ::
4328 ;; ::::::::::::::::::::
4329
4330 ;; Convert ICC/FCC comparison into CCR bits so we can do conditional execution
4331 (define_insn "*ck_signed"
4332   [(set (match_operand:CC_CCR 0 "icr_operand" "=v")
4333         (match_operator:CC_CCR 1 "integer_relational_operator"
4334                                [(match_operand 2 "icc_operand" "t")
4335                                 (const_int 0)]))]
4336   ""
4337   "ck%c1 %2, %0"
4338   [(set_attr "length" "4")
4339    (set_attr "type" "ccr")])
4340
4341 (define_insn "*fck_float"
4342   [(set (match_operand:CC_CCR 0 "fcr_operand" "=w")
4343         (match_operator:CC_CCR 1 "float_relational_operator"
4344                                [(match_operand:CC_FP 2 "fcc_operand" "u")
4345                                 (const_int 0)]))]
4346   "TARGET_HAS_FPRS"
4347   "fck%c1 %2, %0"
4348   [(set_attr "length" "4")
4349    (set_attr "type" "ccr")])
4350
4351 ;; Conditionally convert ICC/FCC comparison into CCR bits to provide && and ||
4352 ;; tests in conditional execution
4353 (define_insn "cond_exec_ck"
4354   [(set (match_operand:CC_CCR 0 "cr_operand" "=v,w")
4355         (if_then_else:CC_CCR (match_operator 1 "ccr_eqne_operator"
4356                                              [(match_operand 2 "cr_operand" "C,C")
4357                                               (const_int 0)])
4358                              (match_operator 3 "relational_operator"
4359                                              [(match_operand 4 "cc_operand" "t,u")
4360                                               (const_int 0)])
4361                              (const_int 0)))]
4362   ""
4363   "@
4364    cck%c3 %4, %0, %2, %e1
4365    cfck%f3 %4, %0, %2, %e1"
4366   [(set_attr "length" "4")
4367    (set_attr "type" "ccr")])
4368
4369 ;; Conditionally set a register to either 0 or another register
4370 (define_insn "*cond_exec_movqi"
4371   [(cond_exec
4372     (match_operator 0 "ccr_eqne_operator"
4373                     [(match_operand 1 "cr_operand" "C,C,C,C,C,C")
4374                      (const_int 0)])
4375     (set (match_operand:QI 2 "condexec_dest_operand" "=d,d,U,?f,?f,?d")
4376          (match_operand:QI 3 "condexec_source_operand" "dO,U,dO,f,d,f")))]
4377   "register_operand(operands[2], QImode) || reg_or_0_operand (operands[3], QImode)"
4378   "* return output_condmove_single (operands, insn);"
4379   [(set_attr "length" "4")
4380    (set_attr "type" "int,gload,gstore,fsconv,movgf,movfg")])
4381
4382 (define_insn "*cond_exec_movhi"
4383   [(cond_exec
4384     (match_operator 0 "ccr_eqne_operator"
4385                     [(match_operand 1 "cr_operand" "C,C,C,C,C,C")
4386                      (const_int 0)])
4387     (set (match_operand:HI 2 "condexec_dest_operand" "=d,d,U,?f,?f,?d")
4388          (match_operand:HI 3 "condexec_source_operand" "dO,U,dO,f,d,f")))]
4389   "register_operand(operands[2], HImode) || reg_or_0_operand (operands[3], HImode)"
4390   "* return output_condmove_single (operands, insn);"
4391   [(set_attr "length" "4")
4392    (set_attr "type" "int,gload,gstore,fsconv,movgf,movfg")])
4393
4394 (define_insn "*cond_exec_movsi"
4395   [(cond_exec
4396     (match_operator 0 "ccr_eqne_operator"
4397                     [(match_operand 1 "cr_operand" "C,C,C,C,C,C,C,C")
4398                      (const_int 0)])
4399     (set (match_operand:SI 2 "condexec_dest_operand" "=d,d,U,?f,?f,?d,?f,?m")
4400          (match_operand:SI 3 "condexec_source_operand" "dO,U,dO,f,d,f,m,f")))]
4401   "register_operand(operands[2], SImode) || reg_or_0_operand (operands[3], SImode)"
4402   "* return output_condmove_single (operands, insn);"
4403   [(set_attr "length" "4")
4404    (set_attr "type" "int,gload,gstore,fsconv,movgf,movfg,fload,fstore")])
4405
4406
4407 (define_insn "*cond_exec_movsf_has_fprs"
4408   [(cond_exec
4409     (match_operator 0 "ccr_eqne_operator"
4410                     [(match_operand 1 "cr_operand" "C,C,C,C,C,C,C,C,C,C")
4411                      (const_int 0)])
4412     (set (match_operand:SF 2 "condexec_dest_operand" "=f,?d,?d,?f,f,f,?d,U,?U,U")
4413          (match_operand:SF 3 "condexec_source_operand" "f,d,f,d,G,U,U,f,d,G")))]
4414   "TARGET_HAS_FPRS"
4415   "* return output_condmove_single (operands, insn);"
4416   [(set_attr "length" "4")
4417    (set_attr "type" "fsconv,int,movgf,movfg,movgf,fload,gload,fstore,gstore,gstore")])
4418
4419 (define_insn "*cond_exec_movsf_no_fprs"
4420   [(cond_exec
4421     (match_operator 0 "ccr_eqne_operator"
4422                     [(match_operand 1 "cr_operand" "C,C,C")
4423                      (const_int 0)])
4424     (set (match_operand:SF 2 "condexec_dest_operand" "=d,d,U")
4425          (match_operand:SF 3 "condexec_source_operand" "d,U,dG")))]
4426   "! TARGET_HAS_FPRS"
4427   "* return output_condmove_single (operands, insn);"
4428   [(set_attr "length" "4")
4429    (set_attr "type" "int,gload,gstore")])
4430
4431 (define_insn "*cond_exec_si_binary1"
4432   [(cond_exec
4433     (match_operator 0 "ccr_eqne_operator"
4434                     [(match_operand 1 "cr_operand" "C")
4435                      (const_int 0)])
4436     (set (match_operand:SI 2 "integer_register_operand" "=d")
4437          (match_operator:SI 3 "condexec_si_binary_operator"
4438                             [(match_operand:SI 4 "integer_register_operand" "d")
4439                              (match_operand:SI 5 "integer_register_operand" "d")])))]
4440   ""
4441   "*
4442 {
4443   switch (GET_CODE (operands[3]))
4444     {
4445       case PLUS:     return \"cadd %4, %z5, %2, %1, %e0\";
4446       case MINUS:    return \"csub %4, %z5, %2, %1, %e0\";
4447       case AND:      return \"cand %4, %z5, %2, %1, %e0\";
4448       case IOR:      return \"cor %4, %z5, %2, %1, %e0\";
4449       case XOR:      return \"cxor %4, %z5, %2, %1, %e0\";
4450       case ASHIFT:   return \"csll %4, %z5, %2, %1, %e0\";
4451       case ASHIFTRT: return \"csra %4, %z5, %2, %1, %e0\";
4452       case LSHIFTRT: return \"csrl %4, %z5, %2, %1, %e0\";
4453       default:       gcc_unreachable ();
4454     }
4455 }"
4456   [(set_attr "length" "4")
4457    (set_attr "type" "int")])
4458
4459 (define_insn "*cond_exec_si_binary2"
4460   [(cond_exec
4461     (match_operator 0 "ccr_eqne_operator"
4462                     [(match_operand 1 "cr_operand" "C")
4463                      (const_int 0)])
4464     (set (match_operand:SI 2 "fpr_operand" "=f")
4465          (match_operator:SI 3 "condexec_si_media_operator"
4466                             [(match_operand:SI 4 "fpr_operand" "f")
4467                              (match_operand:SI 5 "fpr_operand" "f")])))]
4468   "TARGET_MEDIA"
4469   "*
4470 {
4471   switch (GET_CODE (operands[3]))
4472     {
4473       case AND: return \"cmand %4, %5, %2, %1, %e0\";
4474       case IOR: return \"cmor %4, %5, %2, %1, %e0\";
4475       case XOR: return \"cmxor %4, %5, %2, %1, %e0\";
4476       default:  gcc_unreachable ();
4477     }
4478 }"
4479   [(set_attr "length" "4")
4480    (set_attr "type" "mlogic")])
4481
4482 ;; Note, flow does not (currently) know how to handle an operation that uses
4483 ;; only part of the hard registers allocated for a multiregister value, such as
4484 ;; DImode in this case if the user is only interested in the lower 32-bits.  So
4485 ;; we emit a USE of the entire register after the csmul instruction so it won't
4486 ;; get confused.  See frv_ifcvt_modify_insn for more details.
4487
4488 (define_insn "*cond_exec_si_smul"
4489   [(cond_exec
4490     (match_operator 0 "ccr_eqne_operator"
4491                     [(match_operand 1 "cr_operand" "C")
4492                      (const_int 0)])
4493     (set (match_operand:DI 2 "even_gpr_operand" "=e")
4494          (mult:DI (sign_extend:DI (match_operand:SI 3 "integer_register_operand" "%d"))
4495                   (sign_extend:DI (match_operand:SI 4 "integer_register_operand" "d")))))]
4496   ""
4497   "csmul %3, %4, %2, %1, %e0"
4498   [(set_attr "length" "4")
4499    (set_attr "type" "mul")])
4500
4501 (define_insn "*cond_exec_si_divide"
4502   [(cond_exec
4503     (match_operator 0 "ccr_eqne_operator"
4504                     [(match_operand 1 "cr_operand" "C")
4505                      (const_int 0)])
4506     (set (match_operand:SI 2 "integer_register_operand" "=d")
4507          (match_operator:SI 3 "condexec_si_divide_operator"
4508                             [(match_operand:SI 4 "integer_register_operand" "d")
4509                              (match_operand:SI 5 "integer_register_operand" "d")])))]
4510   ""
4511   "*
4512 {
4513   switch (GET_CODE (operands[3]))
4514     {
4515       case DIV:  return \"csdiv %4, %z5, %2, %1, %e0\";
4516       case UDIV: return \"cudiv %4, %z5, %2, %1, %e0\";
4517       default:   gcc_unreachable ();
4518     }
4519 }"
4520   [(set_attr "length" "4")
4521    (set_attr "type" "div")])
4522
4523 (define_insn "*cond_exec_si_unary1"
4524   [(cond_exec
4525     (match_operator 0 "ccr_eqne_operator"
4526                     [(match_operand 1 "cr_operand" "C")
4527                      (const_int 0)])
4528     (set (match_operand:SI 2 "integer_register_operand" "=d")
4529          (match_operator:SI 3 "condexec_si_unary_operator"
4530                             [(match_operand:SI 4 "integer_register_operand" "d")])))]
4531   ""
4532   "*
4533 {
4534   switch (GET_CODE (operands[3]))
4535     {
4536       case NOT: return \"cnot %4, %2, %1, %e0\";
4537       case NEG: return \"csub %., %4, %2, %1, %e0\";
4538       default:  gcc_unreachable ();
4539     }
4540 }"
4541   [(set_attr "length" "4")
4542    (set_attr "type" "int")])
4543
4544 (define_insn "*cond_exec_si_unary2"
4545   [(cond_exec
4546     (match_operator 0 "ccr_eqne_operator"
4547                     [(match_operand 1 "cr_operand" "C")
4548                      (const_int 0)])
4549     (set (match_operand:SI 2 "fpr_operand" "=f")
4550          (not:SI (match_operand:SI 3 "fpr_operand" "f"))))]
4551   "TARGET_MEDIA"
4552   "cmnot %3, %2, %1, %e0"
4553   [(set_attr "length" "4")
4554    (set_attr "type" "mlogic")])
4555
4556 (define_insn "*cond_exec_cmpsi_cc"
4557   [(cond_exec
4558     (match_operator 0 "ccr_eqne_operator"
4559                     [(match_operand 1 "cr_operand" "C")
4560                      (const_int 0)])
4561     (set (match_operand:CC 2 "icc_operand" "=t")
4562          (compare:CC (match_operand:SI 3 "integer_register_operand" "d")
4563                      (match_operand:SI 4 "reg_or_0_operand" "dO"))))]
4564   "reload_completed
4565    && REGNO (operands[1]) == REGNO (operands[2]) - ICC_FIRST + ICR_FIRST"
4566   "ccmp %3, %z4, %1, %e0"
4567   [(set_attr "length" "4")
4568    (set_attr "type" "int")])
4569
4570 (define_insn "*cond_exec_cmpsi_cc_uns"
4571   [(cond_exec
4572     (match_operator 0 "ccr_eqne_operator"
4573                     [(match_operand 1 "cr_operand" "C")
4574                      (const_int 0)])
4575     (set (match_operand:CC_UNS 2 "icc_operand" "=t")
4576          (compare:CC_UNS (match_operand:SI 3 "integer_register_operand" "d")
4577                          (match_operand:SI 4 "reg_or_0_operand" "dO"))))]
4578   "reload_completed
4579    && REGNO (operands[1]) == REGNO (operands[2]) - ICC_FIRST + ICR_FIRST"
4580   "ccmp %3, %z4, %1, %e0"
4581   [(set_attr "length" "4")
4582    (set_attr "type" "int")])
4583
4584 (define_insn "*cond_exec_cmpsi_cc_nz"
4585   [(cond_exec
4586     (match_operator 0 "ccr_eqne_operator"
4587                     [(match_operand 1 "cr_operand" "C")
4588                      (const_int 0)])
4589     (set (match_operand:CC_NZ 2 "icc_operand" "=t")
4590          (compare:CC_NZ (match_operand:SI 3 "integer_register_operand" "d")
4591                         (const_int 0))))]
4592   "reload_completed
4593    && REGNO (operands[1]) == REGNO (operands[2]) - ICC_FIRST + ICR_FIRST"
4594   "ccmp %3, %., %1, %e0"
4595   [(set_attr "length" "4")
4596    (set_attr "type" "int")])
4597
4598 (define_insn "*cond_exec_sf_conv"
4599   [(cond_exec
4600     (match_operator 0 "ccr_eqne_operator"
4601                     [(match_operand 1 "cr_operand" "C")
4602                      (const_int 0)])
4603     (set (match_operand:SF 2 "fpr_operand" "=f")
4604          (match_operator:SF 3 "condexec_sf_conv_operator"
4605                             [(match_operand:SF 4 "fpr_operand" "f")])))]
4606   "TARGET_HARD_FLOAT"
4607   "*
4608 {
4609   switch (GET_CODE (operands[3]))
4610     {
4611       case ABS: return \"cfabss %4, %2, %1, %e0\";
4612       case NEG: return \"cfnegs %4, %2, %1, %e0\";
4613       default:  gcc_unreachable ();
4614     }
4615 }"
4616   [(set_attr "length" "4")
4617    (set_attr "type" "fsconv")])
4618
4619 (define_insn "*cond_exec_sf_add"
4620   [(cond_exec
4621     (match_operator 0 "ccr_eqne_operator"
4622                     [(match_operand 1 "cr_operand" "C")
4623                      (const_int 0)])
4624     (set (match_operand:SF 2 "fpr_operand" "=f")
4625          (match_operator:SF 3 "condexec_sf_add_operator"
4626                             [(match_operand:SF 4 "fpr_operand" "f")
4627                              (match_operand:SF 5 "fpr_operand" "f")])))]
4628   "TARGET_HARD_FLOAT"
4629   "*
4630 {
4631   switch (GET_CODE (operands[3]))
4632     {
4633       case PLUS:  return \"cfadds %4, %5, %2, %1, %e0\";
4634       case MINUS: return \"cfsubs %4, %5, %2, %1, %e0\";
4635       default:    gcc_unreachable ();
4636     }
4637 }"
4638   [(set_attr "length" "4")
4639    (set_attr "type" "fsadd")])
4640
4641 (define_insn "*cond_exec_sf_mul"
4642   [(cond_exec
4643     (match_operator 0 "ccr_eqne_operator"
4644                     [(match_operand 1 "cr_operand" "C")
4645                      (const_int 0)])
4646     (set (match_operand:SF 2 "fpr_operand" "=f")
4647          (mult:SF (match_operand:SF 3 "fpr_operand" "f")
4648                   (match_operand:SF 4 "fpr_operand" "f"))))]
4649   "TARGET_HARD_FLOAT"
4650   "cfmuls %3, %4, %2, %1, %e0"
4651   [(set_attr "length" "4")
4652    (set_attr "type" "fsmul")])
4653
4654 (define_insn "*cond_exec_sf_div"
4655   [(cond_exec
4656     (match_operator 0 "ccr_eqne_operator"
4657                     [(match_operand 1 "cr_operand" "C")
4658                      (const_int 0)])
4659     (set (match_operand:SF 2 "fpr_operand" "=f")
4660          (div:SF (match_operand:SF 3 "fpr_operand" "f")
4661                  (match_operand:SF 4 "fpr_operand" "f"))))]
4662   "TARGET_HARD_FLOAT"
4663   "cfdivs %3, %4, %2, %1, %e0"
4664   [(set_attr "length" "4")
4665    (set_attr "type" "fsdiv")])
4666
4667 (define_insn "*cond_exec_sf_sqrt"
4668   [(cond_exec
4669     (match_operator 0 "ccr_eqne_operator"
4670                     [(match_operand 1 "cr_operand" "C")
4671                      (const_int 0)])
4672     (set (match_operand:SF 2 "fpr_operand" "=f")
4673          (sqrt:SF (match_operand:SF 3 "fpr_operand" "f"))))]
4674   "TARGET_HARD_FLOAT"
4675   "cfsqrts %3, %2, %1, %e0"
4676   [(set_attr "length" "4")
4677    (set_attr "type" "fsdiv")])
4678
4679 (define_insn "*cond_exec_cmpsi_cc_fp"
4680   [(cond_exec
4681     (match_operator 0 "ccr_eqne_operator"
4682                     [(match_operand 1 "cr_operand" "C")
4683                      (const_int 0)])
4684     (set (match_operand:CC_FP 2 "fcc_operand" "=u")
4685          (compare:CC_FP (match_operand:SF 3 "fpr_operand" "f")
4686                         (match_operand:SF 4 "fpr_operand" "f"))))]
4687   "reload_completed && TARGET_HARD_FLOAT
4688    && REGNO (operands[1]) == REGNO (operands[2]) - FCC_FIRST + FCR_FIRST"
4689   "cfcmps %3, %4, %2, %1, %e0"
4690   [(set_attr "length" "4")
4691    (set_attr "type" "fsconv")])
4692
4693 \f
4694 ;; ::::::::::::::::::::
4695 ;; ::
4696 ;; :: Logical operations on CR registers
4697 ;; ::
4698 ;; ::::::::::::::::::::
4699
4700 ;; We use UNSPEC to encode andcr/iorcr/etc. rather than the normal RTL
4701 ;; operations, since the RTL operations only have an idea of TRUE and FALSE,
4702 ;; while the CRs have TRUE, FALSE, and UNDEFINED.
4703
4704 (define_expand "andcr"
4705   [(set (match_operand:CC_CCR 0 "cr_operand" "")
4706         (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "")
4707                         (match_operand:CC_CCR 2 "cr_operand" "")
4708                         (const_int 0)] UNSPEC_CR_LOGIC))]
4709   ""
4710   "")
4711
4712 (define_expand "orcr"
4713   [(set (match_operand:CC_CCR 0 "cr_operand" "")
4714         (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "")
4715                         (match_operand:CC_CCR 2 "cr_operand" "")
4716                         (const_int 1)] UNSPEC_CR_LOGIC))]
4717   ""
4718   "")
4719
4720 (define_expand "xorcr"
4721   [(set (match_operand:CC_CCR 0 "cr_operand" "")
4722         (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "")
4723                         (match_operand:CC_CCR 2 "cr_operand" "")
4724                         (const_int 2)] UNSPEC_CR_LOGIC))]
4725   ""
4726   "")
4727
4728 (define_expand "nandcr"
4729   [(set (match_operand:CC_CCR 0 "cr_operand" "")
4730         (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "")
4731                         (match_operand:CC_CCR 2 "cr_operand" "")
4732                         (const_int 3)] UNSPEC_CR_LOGIC))]
4733   ""
4734   "")
4735
4736 (define_expand "norcr"
4737   [(set (match_operand:CC_CCR 0 "cr_operand" "")
4738         (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "")
4739                         (match_operand:CC_CCR 2 "cr_operand" "")
4740                         (const_int 4)] UNSPEC_CR_LOGIC))]
4741   ""
4742   "")
4743
4744 (define_expand "andncr"
4745   [(set (match_operand:CC_CCR 0 "cr_operand" "")
4746         (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "")
4747                         (match_operand:CC_CCR 2 "cr_operand" "")
4748                         (const_int 5)] UNSPEC_CR_LOGIC))]
4749   ""
4750   "")
4751
4752 (define_expand "orncr"
4753   [(set (match_operand:CC_CCR 0 "cr_operand" "")
4754         (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "")
4755                         (match_operand:CC_CCR 2 "cr_operand" "")
4756                         (const_int 6)] UNSPEC_CR_LOGIC))]
4757   ""
4758   "")
4759
4760 (define_expand "nandncr"
4761   [(set (match_operand:CC_CCR 0 "cr_operand" "")
4762         (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "")
4763                         (match_operand:CC_CCR 2 "cr_operand" "")
4764                         (const_int 7)] UNSPEC_CR_LOGIC))]
4765   ""
4766   "")
4767
4768 (define_expand "norncr"
4769   [(set (match_operand:CC_CCR 0 "cr_operand" "")
4770         (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "")
4771                         (match_operand:CC_CCR 2 "cr_operand" "")
4772                         (const_int 8)] UNSPEC_CR_LOGIC))]
4773   ""
4774   "")
4775
4776 (define_expand "notcr"
4777   [(set (match_operand:CC_CCR 0 "cr_operand" "")
4778         (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "")
4779                         (match_dup 1)
4780                         (const_int 9)] UNSPEC_CR_LOGIC))]
4781   ""
4782   "")
4783
4784 (define_insn "*logical_cr"
4785   [(set (match_operand:CC_CCR 0 "cr_operand" "=C")
4786         (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "C")
4787                         (match_operand:CC_CCR 2 "cr_operand" "C")
4788                         (match_operand:SI 3 "const_int_operand" "n")]
4789                        UNSPEC_CR_LOGIC))]
4790   ""
4791   "*
4792 {
4793   switch (INTVAL (operands[3]))
4794   {
4795   default: break;
4796   case 0: return \"andcr %1, %2, %0\";
4797   case 1: return \"orcr %1, %2, %0\";
4798   case 2: return \"xorcr %1, %2, %0\";
4799   case 3: return \"nandcr %1, %2, %0\";
4800   case 4: return \"norcr %1, %2, %0\";
4801   case 5: return \"andncr %1, %2, %0\";
4802   case 6: return \"orncr %1, %2, %0\";
4803   case 7: return \"nandncr %1, %2, %0\";
4804   case 8: return \"norncr %1, %2, %0\";
4805   case 9: return \"notcr %1, %0\";
4806   }
4807
4808   fatal_insn (\"logical_cr\", insn);
4809 }"
4810   [(set_attr "length" "4")
4811    (set_attr "type" "ccr")])
4812
4813 \f
4814 ;; ::::::::::::::::::::
4815 ;; ::
4816 ;; :: Conditional move instructions
4817 ;; ::
4818 ;; ::::::::::::::::::::
4819
4820
4821 ;; - conditional moves based on floating-point comparisons require
4822 ;;   TARGET_HARD_FLOAT, because an FPU is required to do the comparison.
4823
4824 ;; - conditional moves between FPRs based on integer comparisons
4825 ;;   require TARGET_HAS_FPRS.
4826
4827 (define_expand "movqicc"
4828   [(set (match_operand:QI 0 "integer_register_operand" "")
4829         (if_then_else:QI (match_operand 1 "" "")
4830                          (match_operand:QI 2 "gpr_or_int_operand" "")
4831                          (match_operand:QI 3 "gpr_or_int_operand" "")))]
4832   "TARGET_COND_MOVE"
4833   "
4834 {
4835   if (!frv_emit_cond_move (operands[0], operands[1], operands[2], operands[3]))
4836     FAIL;
4837
4838   DONE;
4839 }")
4840
4841 (define_insn "*movqicc_internal1_int"
4842   [(set (match_operand:QI 0 "integer_register_operand" "=d,d,d")
4843         (if_then_else:QI (match_operator 1 "integer_relational_operator"
4844                              [(match_operand 2 "icc_operand" "t,t,t")
4845                               (const_int 0)])
4846                          (match_operand:QI 3 "reg_or_0_operand" "0,dO,dO")
4847                          (match_operand:QI 4 "reg_or_0_operand" "dO,0,dO")))
4848    (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v"))]
4849   ""
4850   "#"
4851   [(set_attr "length" "8,8,12")
4852    (set_attr "type" "multi")])
4853
4854 (define_insn "*movqicc_internal1_float"
4855   [(set (match_operand:QI 0 "integer_register_operand" "=d,d,d")
4856         (if_then_else:QI (match_operator:CC_FP 1 "float_relational_operator"
4857                              [(match_operand:CC_FP 2 "fcc_operand" "u,u,u")
4858                               (const_int 0)])
4859                          (match_operand:QI 3 "reg_or_0_operand" "0,dO,dO")
4860                          (match_operand:QI 4 "reg_or_0_operand" "dO,0,dO")))
4861    (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w"))]
4862   "TARGET_HARD_FLOAT"
4863   "#"
4864   [(set_attr "length" "8,8,12")
4865    (set_attr "type" "multi")])
4866
4867 (define_insn "*movqicc_internal2_int"
4868   [(set (match_operand:QI 0 "integer_register_operand" "=d,d,d,d,d")
4869         (if_then_else:QI (match_operator 1 "integer_relational_operator"
4870                              [(match_operand 2 "icc_operand" "t,t,t,t,t")
4871                               (const_int 0)])
4872                          (match_operand:QI 3 "const_int_operand" "O,O,L,n,n")
4873                          (match_operand:QI 4 "const_int_operand" "L,n,O,O,n")))
4874    (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v,v,v"))]
4875   "(INTVAL (operands[3]) == 0
4876     || INTVAL (operands[4]) == 0
4877     || (IN_RANGE_P (INTVAL (operands[3]), -2048, 2047)
4878         && IN_RANGE_P (INTVAL (operands[4]) - INTVAL (operands[3]), -2048, 2047)))"
4879   "#"
4880   [(set_attr "length" "8,12,8,12,12")
4881    (set_attr "type" "multi")])
4882
4883 (define_insn "*movqicc_internal2_float"
4884   [(set (match_operand:QI 0 "integer_register_operand" "=d,d,d,d,d")
4885         (if_then_else:QI (match_operator:CC_FP 1 "float_relational_operator"
4886                              [(match_operand:CC_FP 2 "fcc_operand" "u,u,u,u,u")
4887                               (const_int 0)])
4888                          (match_operand:QI 3 "const_int_operand" "O,O,L,n,n")
4889                          (match_operand:QI 4 "const_int_operand" "L,n,O,O,n")))
4890    (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w,w,w"))]
4891   "TARGET_HARD_FLOAT
4892    && (INTVAL (operands[3]) == 0
4893        || INTVAL (operands[4]) == 0
4894        || (IN_RANGE_P (INTVAL (operands[3]), -2048, 2047)
4895            && IN_RANGE_P (INTVAL (operands[4]) - INTVAL (operands[3]), -2048, 2047)))"
4896   "#"
4897   [(set_attr "length" "8,12,8,12,12")
4898    (set_attr "type" "multi")])
4899
4900 (define_split
4901   [(set (match_operand:QI 0 "integer_register_operand" "")
4902         (if_then_else:QI (match_operator 1 "relational_operator"
4903                              [(match_operand 2 "cc_operand" "")
4904                               (const_int 0)])
4905                          (match_operand:QI 3 "gpr_or_int_operand" "")
4906                          (match_operand:QI 4 "gpr_or_int_operand" "")))
4907    (clobber (match_operand:CC_CCR 5 "cr_operand" ""))]
4908   "reload_completed"
4909   [(match_dup 6)]
4910   "operands[6] = frv_split_cond_move (operands);")
4911
4912 (define_expand "movhicc"
4913   [(set (match_operand:HI 0 "integer_register_operand" "")
4914         (if_then_else:HI (match_operand 1 "" "")
4915                          (match_operand:HI 2 "gpr_or_int_operand" "")
4916                          (match_operand:HI 3 "gpr_or_int_operand" "")))]
4917   "TARGET_COND_MOVE"
4918   "
4919 {
4920   if (!frv_emit_cond_move (operands[0], operands[1], operands[2], operands[3]))
4921     FAIL;
4922
4923   DONE;
4924 }")
4925
4926 (define_insn "*movhicc_internal1_int"
4927   [(set (match_operand:HI 0 "integer_register_operand" "=d,d,d")
4928         (if_then_else:HI (match_operator 1 "integer_relational_operator"
4929                              [(match_operand 2 "icc_operand" "t,t,t")
4930                               (const_int 0)])
4931                          (match_operand:HI 3 "reg_or_0_operand" "0,dO,dO")
4932                          (match_operand:HI 4 "reg_or_0_operand" "dO,0,dO")))
4933    (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v"))]
4934   ""
4935   "#"
4936   [(set_attr "length" "8,8,12")
4937    (set_attr "type" "multi")])
4938
4939 (define_insn "*movhicc_internal1_float"
4940   [(set (match_operand:HI 0 "integer_register_operand" "=d,d,d")
4941         (if_then_else:HI (match_operator:CC_FP 1 "float_relational_operator"
4942                              [(match_operand:CC_FP 2 "fcc_operand" "u,u,u")
4943                               (const_int 0)])
4944                          (match_operand:HI 3 "reg_or_0_operand" "0,dO,dO")
4945                          (match_operand:HI 4 "reg_or_0_operand" "dO,0,dO")))
4946    (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w"))]
4947   "TARGET_HARD_FLOAT"
4948   "#"
4949   [(set_attr "length" "8,8,12")
4950    (set_attr "type" "multi")])
4951
4952 (define_insn "*movhicc_internal2_int"
4953   [(set (match_operand:HI 0 "integer_register_operand" "=d,d,d,d,d")
4954         (if_then_else:HI (match_operator 1 "integer_relational_operator"
4955                              [(match_operand 2 "icc_operand" "t,t,t,t,t")
4956                               (const_int 0)])
4957                          (match_operand:HI 3 "const_int_operand" "O,O,L,n,n")
4958                          (match_operand:HI 4 "const_int_operand" "L,n,O,O,n")))
4959    (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v,v,v"))]
4960   "(INTVAL (operands[3]) == 0
4961     || INTVAL (operands[4]) == 0
4962     || (IN_RANGE_P (INTVAL (operands[3]), -2048, 2047)
4963         && IN_RANGE_P (INTVAL (operands[4]) - INTVAL (operands[3]), -2048, 2047)))"
4964   "#"
4965   [(set_attr "length" "8,12,8,12,12")
4966    (set_attr "type" "multi")])
4967
4968 (define_insn "*movhicc_internal2_float"
4969   [(set (match_operand:HI 0 "integer_register_operand" "=d,d,d,d,d")
4970         (if_then_else:HI (match_operator:CC_FP 1 "float_relational_operator"
4971                              [(match_operand:CC_FP 2 "fcc_operand" "u,u,u,u,u")
4972                               (const_int 0)])
4973                          (match_operand:HI 3 "const_int_operand" "O,O,L,n,n")
4974                          (match_operand:HI 4 "const_int_operand" "L,n,O,O,n")))
4975    (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w,w,w"))]
4976   "TARGET_HARD_FLOAT
4977    && (INTVAL (operands[3]) == 0
4978        || INTVAL (operands[4]) == 0
4979        || (IN_RANGE_P (INTVAL (operands[3]), -2048, 2047)
4980            && IN_RANGE_P (INTVAL (operands[4]) - INTVAL (operands[3]), -2048, 2047)))"
4981   "#"
4982   [(set_attr "length" "8,12,8,12,12")
4983    (set_attr "type" "multi")])
4984
4985 (define_split
4986   [(set (match_operand:HI 0 "integer_register_operand" "")
4987         (if_then_else:HI (match_operator 1 "relational_operator"
4988                              [(match_operand 2 "cc_operand" "")
4989                               (const_int 0)])
4990                          (match_operand:HI 3 "gpr_or_int_operand" "")
4991                          (match_operand:HI 4 "gpr_or_int_operand" "")))
4992    (clobber (match_operand:CC_CCR 5 "cr_operand" ""))]
4993   "reload_completed"
4994   [(match_dup 6)]
4995   "operands[6] = frv_split_cond_move (operands);")
4996
4997 (define_expand "movsicc"
4998   [(set (match_operand:SI 0 "integer_register_operand" "")
4999         (if_then_else:SI (match_operand 1 "" "")
5000                          (match_operand:SI 2 "gpr_or_int_operand" "")
5001                          (match_operand:SI 3 "gpr_or_int_operand" "")))]
5002   "TARGET_COND_MOVE"
5003   "
5004 {
5005   if (!frv_emit_cond_move (operands[0], operands[1], operands[2], operands[3]))
5006     FAIL;
5007
5008   DONE;
5009 }")
5010
5011 (define_insn "*movsicc_internal1_int"
5012   [(set (match_operand:SI 0 "integer_register_operand" "=d,d,d")
5013         (if_then_else:SI (match_operator 1 "integer_relational_operator"
5014                              [(match_operand 2 "icc_operand" "t,t,t")
5015                               (const_int 0)])
5016                          (match_operand:SI 3 "reg_or_0_operand" "0,dO,dO")
5017                          (match_operand:SI 4 "reg_or_0_operand" "dO,0,dO")))
5018    (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v"))]
5019   ""
5020   "#"
5021   [(set_attr "length" "8,8,12")
5022    (set_attr "type" "multi")])
5023
5024 (define_insn "*movsicc_internal1_float"
5025   [(set (match_operand:SI 0 "integer_register_operand" "=d,d,d")
5026         (if_then_else:SI (match_operator:CC_FP 1 "float_relational_operator"
5027                              [(match_operand:CC_FP 2 "fcc_operand" "u,u,u")
5028                               (const_int 0)])
5029                          (match_operand:SI 3 "reg_or_0_operand" "0,dO,dO")
5030                          (match_operand:SI 4 "reg_or_0_operand" "dO,0,dO")))
5031    (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w"))]
5032   "TARGET_HARD_FLOAT"
5033   "#"
5034   [(set_attr "length" "8,8,12")
5035    (set_attr "type" "multi")])
5036
5037 (define_insn "*movsicc_internal2_int"
5038   [(set (match_operand:SI 0 "integer_register_operand" "=d,d,d,d,d")
5039         (if_then_else:SI (match_operator 1 "integer_relational_operator"
5040                              [(match_operand 2 "icc_operand" "t,t,t,t,t")
5041                               (const_int 0)])
5042                          (match_operand:SI 3 "const_int_operand" "O,O,L,n,n")
5043                          (match_operand:SI 4 "const_int_operand" "L,n,O,O,n")))
5044    (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v,v,v"))]
5045   "(INTVAL (operands[3]) == 0
5046     || INTVAL (operands[4]) == 0
5047     || (IN_RANGE_P (INTVAL (operands[3]), -2048, 2047)
5048         && IN_RANGE_P (INTVAL (operands[4]) - INTVAL (operands[3]), -2048, 2047)))"
5049   "#"
5050   [(set_attr "length" "8,12,8,12,12")
5051    (set_attr "type" "multi")])
5052
5053 (define_insn "*movsicc_internal2_float"
5054   [(set (match_operand:SI 0 "integer_register_operand" "=d,d,d,d,d")
5055         (if_then_else:SI (match_operator:CC_FP 1 "float_relational_operator"
5056                              [(match_operand:CC_FP 2 "fcc_operand" "u,u,u,u,u")
5057                               (const_int 0)])
5058                          (match_operand:SI 3 "const_int_operand" "O,O,L,n,n")
5059                          (match_operand:SI 4 "const_int_operand" "L,n,O,O,n")))
5060    (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w,w,w"))]
5061   "TARGET_HARD_FLOAT
5062    && (INTVAL (operands[3]) == 0
5063        || INTVAL (operands[4]) == 0
5064        || (IN_RANGE_P (INTVAL (operands[3]), -2048, 2047)
5065            && IN_RANGE_P (INTVAL (operands[4]) - INTVAL (operands[3]), -2048, 2047)))"
5066   "#"
5067   [(set_attr "length" "8,12,8,12,12")
5068    (set_attr "type" "multi")])
5069
5070 (define_split
5071   [(set (match_operand:SI 0 "integer_register_operand" "")
5072         (if_then_else:SI (match_operator 1 "relational_operator"
5073                              [(match_operand 2 "cc_operand" "")
5074                               (const_int 0)])
5075                          (match_operand:SI 3 "gpr_or_int_operand" "")
5076                          (match_operand:SI 4 "gpr_or_int_operand" "")))
5077    (clobber (match_operand:CC_CCR 5 "cr_operand" ""))]
5078   "reload_completed"
5079   [(match_dup 6)]
5080   "operands[6] = frv_split_cond_move (operands);")
5081
5082 (define_expand "movsfcc"
5083   [(set (match_operand:SF 0 "register_operand" "")
5084         (if_then_else:SF (match_operand 1 "" "")
5085                          (match_operand:SF 2 "register_operand" "")
5086                          (match_operand:SF 3 "register_operand" "")))]
5087   "TARGET_COND_MOVE"
5088   "
5089 {
5090   if (!frv_emit_cond_move (operands[0], operands[1], operands[2], operands[3]))
5091     FAIL;
5092
5093   DONE;
5094 }")
5095
5096 (define_insn "*movsfcc_has_fprs_int"
5097   [(set (match_operand:SF 0 "register_operand" "=f,f,f,?f,?f,?d")
5098         (if_then_else:SF (match_operator 1 "integer_relational_operator"
5099                              [(match_operand 2 "icc_operand" "t,t,t,t,t,t")
5100                               (const_int 0)])
5101                          (match_operand:SF 3 "register_operand" "0,f,f,f,d,fd")
5102                          (match_operand:SF 4 "register_operand" "f,0,f,d,fd,fd")))
5103    (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v,v,v,v"))]
5104   "TARGET_HAS_FPRS"
5105   "#"
5106   [(set_attr "length" "8,8,12,12,12,12")
5107    (set_attr "type" "multi")])
5108
5109 (define_insn "*movsfcc_hardfloat_float"
5110   [(set (match_operand:SF 0 "register_operand" "=f,f,f,?f,?f,?d")
5111         (if_then_else:SF (match_operator:CC_FP 1 "float_relational_operator"
5112                              [(match_operand:CC_FP 2 "fcc_operand" "u,u,u,u,u,u")
5113                               (const_int 0)])
5114                          (match_operand:SF 3 "register_operand" "0,f,f,f,d,fd")
5115                          (match_operand:SF 4 "register_operand" "f,0,f,d,fd,fd")))
5116    (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w,w,w,w"))]
5117   "TARGET_HARD_FLOAT"
5118   "#"
5119   [(set_attr "length" "8,8,12,12,12,12")
5120    (set_attr "type" "multi")])
5121
5122 (define_insn "*movsfcc_no_fprs_int"
5123   [(set (match_operand:SF 0 "integer_register_operand" "=d,d,d")
5124         (if_then_else:SF (match_operator 1 "integer_relational_operator"
5125                              [(match_operand 2 "icc_operand" "t,t,t")
5126                               (const_int 0)])
5127                          (match_operand:SF 3 "integer_register_operand" "0,d,d")
5128                          (match_operand:SF 4 "integer_register_operand" "d,0,d")))
5129    (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v"))]
5130   "! TARGET_HAS_FPRS"
5131   "#"
5132   [(set_attr "length" "8,8,12")
5133    (set_attr "type" "multi")])
5134
5135 (define_split
5136   [(set (match_operand:SF 0 "register_operand" "")
5137         (if_then_else:SF (match_operator 1 "relational_operator"
5138                              [(match_operand 2 "cc_operand" "")
5139                               (const_int 0)])
5140                          (match_operand:SF 3 "register_operand" "")
5141                          (match_operand:SF 4 "register_operand" "")))
5142    (clobber (match_operand:CC_CCR 5 "cr_operand" ""))]
5143   "reload_completed"
5144   [(match_dup 6)]
5145   "operands[6] = frv_split_cond_move (operands);")
5146
5147 \f
5148 ;; ::::::::::::::::::::
5149 ;; ::
5150 ;; :: Minimum, maximum, and integer absolute value
5151 ;; ::
5152 ;; ::::::::::::::::::::
5153
5154 ;; These 'instructions' are provided to give the compiler a slightly better
5155 ;; nudge at register allocation, then it would if it constructed the
5156 ;; instructions from basic building blocks (since it indicates it prefers one
5157 ;; of the operands to be the same as the destination.  It also helps the
5158 ;; earlier passes of the compiler, by not breaking things into small basic
5159 ;; blocks.
5160
5161 (define_expand "abssi2"
5162   [(parallel [(set (match_operand:SI 0 "integer_register_operand" "")
5163                    (abs:SI (match_operand:SI 1 "integer_register_operand" "")))
5164               (clobber (match_dup 2))
5165               (clobber (match_dup 3))])]
5166   "TARGET_COND_MOVE"
5167   "
5168 {
5169   operands[2] = gen_reg_rtx (CCmode);
5170   operands[3] = gen_reg_rtx (CC_CCRmode);
5171 }")
5172
5173 (define_insn_and_split "*abssi2_internal"
5174   [(set (match_operand:SI 0 "integer_register_operand" "=d,d")
5175         (abs:SI (match_operand:SI 1 "integer_register_operand" "0,d")))
5176    (clobber (match_operand:CC 2 "icc_operand" "=t,t"))
5177    (clobber (match_operand:CC_CCR 3 "icr_operand" "=v,v"))]
5178   "TARGET_COND_MOVE"
5179   "#"
5180   "reload_completed"
5181   [(match_dup 4)]
5182   "operands[4] = frv_split_abs (operands);"
5183   [(set_attr "length" "12,16")
5184    (set_attr "type" "multi")])
5185
5186 (define_expand "sminsi3"
5187   [(parallel [(set (match_operand:SI 0 "integer_register_operand" "")
5188                    (smin:SI (match_operand:SI 1 "integer_register_operand" "")
5189                             (match_operand:SI 2 "gpr_or_int10_operand" "")))
5190               (clobber (match_dup 3))
5191               (clobber (match_dup 4))])]
5192   "TARGET_COND_MOVE"
5193   "
5194 {
5195   operands[3] = gen_reg_rtx (CCmode);
5196   operands[4] = gen_reg_rtx (CC_CCRmode);
5197 }")
5198
5199 (define_expand "smaxsi3"
5200   [(parallel [(set (match_operand:SI 0 "integer_register_operand" "")
5201                    (smax:SI (match_operand:SI 1 "integer_register_operand" "")
5202                             (match_operand:SI 2 "gpr_or_int10_operand" "")))
5203               (clobber (match_dup 3))
5204               (clobber (match_dup 4))])]
5205   "TARGET_COND_MOVE"
5206   "
5207 {
5208   operands[3] = gen_reg_rtx (CCmode);
5209   operands[4] = gen_reg_rtx (CC_CCRmode);
5210 }")
5211
5212 (define_insn_and_split "*minmax_si_signed"
5213   [(set (match_operand:SI 0 "integer_register_operand" "=d,d,&d")
5214         (match_operator:SI 1 "minmax_operator"
5215                            [(match_operand:SI 2 "integer_register_operand" "%0,dO,d")
5216                             (match_operand:SI 3 "gpr_or_int10_operand" "dO,0,dJ")]))
5217    (clobber (match_operand:CC 4 "icc_operand" "=t,t,t"))
5218    (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v"))]
5219   "TARGET_COND_MOVE"
5220   "#"
5221   "reload_completed"
5222   [(match_dup 6)]
5223   "operands[6] = frv_split_minmax (operands);"
5224   [(set_attr "length" "12,12,16")
5225    (set_attr "type" "multi")])
5226
5227 (define_expand "uminsi3"
5228   [(parallel [(set (match_operand:SI 0 "integer_register_operand" "")
5229                    (umin:SI (match_operand:SI 1 "integer_register_operand" "")
5230                             (match_operand:SI 2 "gpr_or_int10_operand" "")))
5231               (clobber (match_dup 3))
5232               (clobber (match_dup 4))])]
5233   "TARGET_COND_MOVE"
5234   "
5235 {
5236   operands[3] = gen_reg_rtx (CC_UNSmode);
5237   operands[4] = gen_reg_rtx (CC_CCRmode);
5238 }")
5239
5240 (define_expand "umaxsi3"
5241   [(parallel [(set (match_operand:SI 0 "integer_register_operand" "")
5242                    (umax:SI (match_operand:SI 1 "integer_register_operand" "")
5243                             (match_operand:SI 2 "gpr_or_int10_operand" "")))
5244               (clobber (match_dup 3))
5245               (clobber (match_dup 4))])]
5246   "TARGET_COND_MOVE"
5247   "
5248 {
5249   operands[3] = gen_reg_rtx (CC_UNSmode);
5250   operands[4] = gen_reg_rtx (CC_CCRmode);
5251 }")
5252
5253 (define_insn_and_split "*minmax_si_unsigned"
5254   [(set (match_operand:SI 0 "integer_register_operand" "=d,d,&d")
5255         (match_operator:SI 1 "minmax_operator"
5256                            [(match_operand:SI 2 "integer_register_operand" "%0,dO,d")
5257                             (match_operand:SI 3 "gpr_or_int10_operand" "dO,0,dJ")]))
5258    (clobber (match_operand:CC_UNS 4 "icc_operand" "=t,t,t"))
5259    (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v"))]
5260   "TARGET_COND_MOVE"
5261   "#"
5262   "reload_completed"
5263   [(match_dup 6)]
5264   "operands[6] = frv_split_minmax (operands);"
5265   [(set_attr "length" "12,12,16")
5266    (set_attr "type" "multi")])
5267
5268 (define_expand "sminsf3"
5269   [(parallel [(set (match_operand:SF 0 "fpr_operand" "")
5270                    (smin:SF (match_operand:SF 1 "fpr_operand" "")
5271                             (match_operand:SF 2 "fpr_operand" "")))
5272               (clobber (match_dup 3))
5273               (clobber (match_dup 4))])]
5274   "TARGET_COND_MOVE && TARGET_HARD_FLOAT"
5275   "
5276 {
5277   operands[3] = gen_reg_rtx (CC_FPmode);
5278   operands[4] = gen_reg_rtx (CC_CCRmode);
5279 }")
5280
5281 (define_expand "smaxsf3"
5282   [(parallel [(set (match_operand:SF 0 "fpr_operand" "")
5283                    (smax:SF (match_operand:SF 1 "fpr_operand" "")
5284                             (match_operand:SF 2 "fpr_operand" "")))
5285               (clobber (match_dup 3))
5286               (clobber (match_dup 4))])]
5287   "TARGET_COND_MOVE && TARGET_HARD_FLOAT"
5288   "
5289 {
5290   operands[3] = gen_reg_rtx (CC_FPmode);
5291   operands[4] = gen_reg_rtx (CC_CCRmode);
5292 }")
5293
5294 (define_insn_and_split "*minmax_sf"
5295   [(set (match_operand:SF 0 "fpr_operand" "=f,f,f")
5296         (match_operator:SF 1 "minmax_operator"
5297                            [(match_operand:SF 2 "fpr_operand" "%0,f,f")
5298                             (match_operand:SF 3 "fpr_operand" "f,0,f")]))
5299    (clobber (match_operand:CC_FP 4 "fcc_operand" "=u,u,u"))
5300    (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w"))]
5301   "TARGET_COND_MOVE && TARGET_HARD_FLOAT"
5302   "#"
5303   "reload_completed"
5304   [(match_dup 6)]
5305   "operands[6] = frv_split_minmax (operands);"
5306   [(set_attr "length" "12,12,16")
5307    (set_attr "type" "multi")])
5308
5309 (define_expand "smindf3"
5310   [(parallel [(set (match_operand:DF 0 "fpr_operand" "")
5311                    (smin:DF (match_operand:DF 1 "fpr_operand" "")
5312                             (match_operand:DF 2 "fpr_operand" "")))
5313               (clobber (match_dup 3))
5314               (clobber (match_dup 4))])]
5315   "TARGET_COND_MOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE"
5316   "
5317 {
5318   operands[3] = gen_reg_rtx (CC_FPmode);
5319   operands[4] = gen_reg_rtx (CC_CCRmode);
5320 }")
5321
5322 (define_expand "smaxdf3"
5323   [(parallel [(set (match_operand:DF 0 "fpr_operand" "")
5324                    (smax:DF (match_operand:DF 1 "fpr_operand" "")
5325                             (match_operand:DF 2 "fpr_operand" "")))
5326               (clobber (match_dup 3))
5327               (clobber (match_dup 4))])]
5328   "TARGET_COND_MOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE"
5329   "
5330 {
5331   operands[3] = gen_reg_rtx (CC_FPmode);
5332   operands[4] = gen_reg_rtx (CC_CCRmode);
5333 }")
5334
5335 (define_insn_and_split "*minmax_df"
5336   [(set (match_operand:DF 0 "fpr_operand" "=f,f,f")
5337         (match_operator:DF 1 "minmax_operator"
5338                            [(match_operand:DF 2 "fpr_operand" "%0,f,f")
5339                             (match_operand:DF 3 "fpr_operand" "f,0,f")]))
5340    (clobber (match_operand:CC_FP 4 "fcc_operand" "=u,u,u"))
5341    (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w"))]
5342   "TARGET_COND_MOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE"
5343   "#"
5344   "reload_completed"
5345   [(match_dup 6)]
5346   "operands[6] = frv_split_minmax (operands);"
5347   [(set_attr "length" "12,12,16")
5348    (set_attr "type" "multi")])
5349
5350 \f
5351 ;; ::::::::::::::::::::
5352 ;; ::
5353 ;; :: Call and branch instructions
5354 ;; ::
5355 ;; ::::::::::::::::::::
5356
5357 ;; Subroutine call instruction returning no value.  Operand 0 is the function
5358 ;; to call; operand 1 is the number of bytes of arguments pushed (in mode
5359 ;; `SImode', except it is normally a `const_int'); operand 2 is the number of
5360 ;; registers used as operands.
5361
5362 ;; On most machines, operand 2 is not actually stored into the RTL pattern.  It
5363 ;; is supplied for the sake of some RISC machines which need to put this
5364 ;; information into the assembler code; they can put it in the RTL instead of
5365 ;; operand 1.
5366
5367 (define_expand "call"
5368   [(use (match_operand:QI 0 "" ""))
5369    (use (match_operand 1 "" ""))
5370    (use (match_operand 2 "" ""))
5371    (use (match_operand 3 "" ""))]
5372   ""
5373   "
5374 {
5375   rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
5376   rtx addr;
5377
5378   gcc_assert (GET_CODE (operands[0]) == MEM);
5379
5380   addr = XEXP (operands[0], 0);
5381   if (! call_operand (addr, Pmode))
5382     addr = force_reg (Pmode, addr);
5383
5384   if (! operands[2])
5385     operands[2] = const0_rtx;
5386
5387   if (TARGET_FDPIC)
5388     frv_expand_fdpic_call (operands, false, false);
5389   else
5390     emit_call_insn (gen_call_internal (addr, operands[1], operands[2], lr));
5391
5392   DONE;
5393 }")
5394
5395 (define_insn "call_internal"
5396   [(call (mem:QI (match_operand:SI 0 "call_operand" "S,dNOP"))
5397          (match_operand 1 "" ""))
5398    (use (match_operand 2 "" ""))
5399    (clobber (match_operand:SI 3 "lr_operand" "=l,l"))]
5400   "! TARGET_FDPIC"
5401   "@
5402    call %0
5403    call%i0l %M0"
5404   [(set_attr "length" "4")
5405    (set_attr "type" "call,jumpl")])
5406
5407 ;; The odd use of GR0 within the UNSPEC below prevents cseing or
5408 ;; hoisting function descriptor loads out of loops.  This is almost
5409 ;; never desirable, since if we preserve the function descriptor in a
5410 ;; pair of registers, it takes two insns to move it to gr14/gr15, and
5411 ;; if it's in the stack, we just waste space with the store, since
5412 ;; we'll have to load back from memory anyway.  And, in the worst
5413 ;; case, we may end up reusing a function descriptor still pointing at
5414 ;; a PLT entry, instead of to the resolved function, which means going
5415 ;; through the resolver for every call that uses the outdated value.
5416 ;; Bad!
5417
5418 ;; The explicit MEM inside the SPEC prevents the compiler from moving
5419 ;; the load before a branch after a NULL test, or before a store that
5420 ;; initializes a function descriptor.
5421
5422 (define_insn "movdi_ldd"
5423   [(set (match_operand:DI 0 "fdpic_fptr_operand" "=e")
5424         (unspec:DI [(mem:DI (match_operand:SI 1 "ldd_address_operand" "p"))
5425                     (reg:SI 0)] UNSPEC_LDD))]
5426   ""
5427   "ldd%I1 %M1, %0"
5428   [(set_attr "length" "4")
5429    (set_attr "type" "gload")])
5430
5431 (define_insn "call_fdpicdi"
5432   [(call (mem:QI (match_operand:DI 0 "fdpic_fptr_operand" "W"))
5433          (match_operand 1 "" ""))
5434    (clobber (match_operand:SI 2 "lr_operand" "=l"))]
5435   "TARGET_FDPIC"
5436   "call%i0l %M0"
5437   [(set_attr "length" "4")
5438    (set_attr "type" "jumpl")])
5439
5440 (define_insn "call_fdpicsi"
5441   [(call (mem:QI (match_operand:SI 0 "call_operand" "S,dNOP"))
5442          (match_operand 1 "" ""))
5443    (use (match_operand 2 "" ""))
5444    (use (match_operand:SI 3 "fdpic_operand" "Z,Z"))
5445    (clobber (match_operand:SI 4 "lr_operand" "=l,l"))]
5446   "TARGET_FDPIC"
5447   "@
5448    call %0
5449    call%i0l %M0"
5450   [(set_attr "length" "4")
5451    (set_attr "type" "call,jumpl")])
5452
5453 (define_expand "sibcall"
5454   [(use (match_operand:QI 0 "" ""))
5455    (use (match_operand 1 "" ""))
5456    (use (match_operand 2 "" ""))
5457    (use (match_operand 3 "" ""))]
5458   ""
5459   "
5460 {
5461   rtx addr;
5462
5463   gcc_assert (GET_CODE (operands[0]) == MEM);
5464
5465   addr = XEXP (operands[0], 0);
5466   if (! sibcall_operand (addr, Pmode))
5467     addr = force_reg (Pmode, addr);
5468
5469   if (! operands[2])
5470     operands[2] = const0_rtx;
5471
5472   if (TARGET_FDPIC)
5473     frv_expand_fdpic_call (operands, false, true);
5474   else
5475     emit_call_insn (gen_sibcall_internal (addr, operands[1], operands[2]));
5476
5477   DONE;
5478 }")
5479   
5480 ;; It might seem that these sibcall patterns are missing references to
5481 ;; LR, but they're not necessary because sibcall_epilogue will make
5482 ;; sure LR is restored, and having LR here will set
5483 ;; regs_ever_used[REG_LR], forcing it to be saved on the stack, and
5484 ;; then restored in sibcalls and regular return code paths, even if
5485 ;; the function becomes a leaf function after tail-call elimination.
5486
5487 ;; We must not use a call-saved register here.  `W' limits ourselves
5488 ;; to gr14 or gr15, but since we're almost running out of constraint
5489 ;; letters, and most other call-clobbered registers are often used for
5490 ;; argument-passing, this will do.
5491 (define_insn "sibcall_internal"
5492   [(call (mem:QI (match_operand:SI 0 "sibcall_operand" "WNOP"))
5493          (match_operand 1 "" ""))
5494    (use (match_operand 2 "" ""))
5495    (return)]
5496   "! TARGET_FDPIC"
5497   "jmp%i0l %M0"
5498   [(set_attr "length" "4")
5499    (set_attr "type" "jumpl")])
5500
5501 (define_insn "sibcall_fdpicdi"
5502   [(call (mem:QI (match_operand:DI 0 "fdpic_fptr_operand" "W"))
5503          (match_operand 1 "" ""))
5504    (return)]
5505   "TARGET_FDPIC"
5506   "jmp%i0l %M0"
5507   [(set_attr "length" "4")
5508    (set_attr "type" "jumpl")])
5509
5510
5511 ;; Subroutine call instruction returning a value.  Operand 0 is the hard
5512 ;; register in which the value is returned.  There are three more operands, the
5513 ;; same as the three operands of the `call' instruction (but with numbers
5514 ;; increased by one).
5515
5516 ;; Subroutines that return `BLKmode' objects use the `call' insn.
5517
5518 (define_expand "call_value"
5519   [(use (match_operand 0 "" ""))
5520    (use (match_operand:QI 1 "" ""))
5521    (use (match_operand 2 "" ""))
5522    (use (match_operand 3 "" ""))
5523    (use (match_operand 4 "" ""))]
5524   ""
5525   "
5526 {
5527   rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
5528   rtx addr;
5529
5530   gcc_assert (GET_CODE (operands[1]) == MEM);
5531
5532   addr = XEXP (operands[1], 0);
5533   if (! call_operand (addr, Pmode))
5534     addr = force_reg (Pmode, addr);
5535
5536   if (! operands[3])
5537     operands[3] = const0_rtx;
5538
5539   if (TARGET_FDPIC)
5540     frv_expand_fdpic_call (operands, true, false);
5541   else
5542     emit_call_insn (gen_call_value_internal (operands[0], addr, operands[2],
5543                                              operands[3], lr));
5544
5545   DONE;
5546 }")
5547
5548 (define_insn "call_value_internal"
5549   [(set (match_operand 0 "register_operand" "=d,d")
5550         (call (mem:QI (match_operand:SI 1 "call_operand" "S,dNOP"))
5551                       (match_operand 2 "" "")))
5552    (use (match_operand 3 "" ""))
5553    (clobber (match_operand:SI 4 "lr_operand" "=l,l"))]
5554   "! TARGET_FDPIC"
5555   "@
5556    call %1
5557    call%i1l %M1"
5558   [(set_attr "length" "4")
5559    (set_attr "type" "call,jumpl")])
5560
5561 (define_insn "call_value_fdpicdi"
5562   [(set (match_operand 0 "register_operand" "=d")
5563         (call (mem:QI (match_operand:DI 1 "fdpic_fptr_operand" "W"))
5564               (match_operand 2 "" "")))
5565    (clobber (match_operand:SI 3 "lr_operand" "=l"))]
5566   "TARGET_FDPIC"
5567   "call%i1l %M1"
5568   [(set_attr "length" "4")
5569    (set_attr "type" "jumpl")])
5570
5571 (define_insn "call_value_fdpicsi"
5572   [(set (match_operand 0 "register_operand" "=d,d")
5573         (call (mem:QI (match_operand:SI 1 "call_operand" "S,dNOP"))
5574                       (match_operand 2 "" "")))
5575    (use (match_operand 3 "" ""))
5576    (use (match_operand:SI 4 "fdpic_operand" "Z,Z"))
5577    (clobber (match_operand:SI 5 "lr_operand" "=l,l"))]
5578   "TARGET_FDPIC"
5579   "@
5580    call %1
5581    call%i1l %M1"
5582   [(set_attr "length" "4")
5583    (set_attr "type" "call,jumpl")])
5584
5585 (define_expand "sibcall_value"
5586   [(use (match_operand 0 "" ""))
5587    (use (match_operand:QI 1 "" ""))
5588    (use (match_operand 2 "" ""))
5589    (use (match_operand 3 "" ""))
5590    (use (match_operand 4 "" ""))]
5591   ""
5592   "
5593 {
5594   rtx addr;
5595
5596   gcc_assert (GET_CODE (operands[1]) == MEM);
5597
5598   addr = XEXP (operands[1], 0);
5599   if (! sibcall_operand (addr, Pmode))
5600     addr = force_reg (Pmode, addr);
5601
5602   if (! operands[3])
5603     operands[3] = const0_rtx;
5604
5605   if (TARGET_FDPIC)
5606     frv_expand_fdpic_call (operands, true, true);
5607   else
5608     emit_call_insn (gen_sibcall_value_internal (operands[0], addr, operands[2],
5609                                                 operands[3]));
5610   DONE;
5611 }")
5612
5613 (define_insn "sibcall_value_internal"
5614   [(set (match_operand 0 "register_operand" "=d")
5615         (call (mem:QI (match_operand:SI 1 "sibcall_operand" "WNOP"))
5616                       (match_operand 2 "" "")))
5617    (use (match_operand 3 "" ""))
5618    (return)]
5619   "! TARGET_FDPIC"
5620   "jmp%i1l %M1"
5621   [(set_attr "length" "4")
5622    (set_attr "type" "jumpl")])
5623
5624 (define_insn "sibcall_value_fdpicdi"
5625   [(set (match_operand 0 "register_operand" "=d")
5626         (call (mem:QI (match_operand:DI 1 "fdpic_fptr_operand" "W"))
5627               (match_operand 2 "" "")))
5628    (return)]
5629   "TARGET_FDPIC"
5630   "jmp%i1l %M1"
5631   [(set_attr "length" "4")
5632    (set_attr "type" "jumpl")])
5633
5634 ;; return instruction generated instead of jmp to epilog
5635 (define_expand "return"
5636   [(parallel [(return)
5637               (use (match_dup 0))
5638               (use (const_int 1))])]
5639   "direct_return_p ()"
5640   "
5641 {
5642   operands[0] = gen_rtx_REG (Pmode, LR_REGNO);
5643 }")
5644
5645 ;; return instruction generated by the epilogue
5646 (define_expand "epilogue_return"
5647   [(parallel [(return)
5648               (use (match_operand:SI 0 "register_operand" ""))
5649               (use (const_int 0))])]
5650   ""
5651   "")
5652
5653 (define_insn "*return_internal"
5654   [(return)
5655    (use (match_operand:SI 0 "register_operand" "l,d"))
5656    (use (match_operand:SI 1 "immediate_operand" "n,n"))]
5657   ""
5658   "@
5659     ret
5660     jmpl @(%0,%.)"
5661   [(set_attr "length" "4")
5662    (set_attr "type" "jump,jumpl")])
5663
5664 (define_insn "*return_true"
5665   [(set (pc)
5666         (if_then_else (match_operator 0 "integer_relational_operator"
5667                                       [(match_operand 1 "icc_operand" "t")
5668                                        (const_int 0)])
5669                       (return)
5670                       (pc)))]
5671   "direct_return_p ()"
5672   "b%c0lr %1,%#"
5673   [(set_attr "length" "4")
5674    (set_attr "type" "jump")])
5675
5676 (define_insn "*return_false"
5677   [(set (pc)
5678         (if_then_else (match_operator 0 "integer_relational_operator"
5679                                       [(match_operand 1 "icc_operand" "t")
5680                                        (const_int 0)])
5681                       (pc)
5682                       (return)))]
5683   "direct_return_p ()"
5684   "b%C0lr %1,%#"
5685   [(set_attr "length" "4")
5686    (set_attr "type" "jump")])
5687
5688 ;; A version of addsi3 for deallocating stack space at the end of the
5689 ;; epilogue.  The addition is done in parallel with an (unspec_volatile),
5690 ;; which represents the clobbering of the deallocated space.
5691 (define_insn "stack_adjust"
5692   [(set (match_operand:SI 0 "register_operand" "=d")
5693         (plus:SI (match_operand:SI 1 "register_operand" "d")
5694                  (match_operand:SI 2 "general_operand" "dNOP")))
5695    (unspec_volatile [(const_int 0)] UNSPEC_STACK_ADJUST)]
5696   ""
5697   "add%I2 %1,%2,%0"
5698   [(set_attr "length" "4")
5699    (set_attr "type" "int")])
5700
5701 ;; Normal unconditional jump
5702
5703 ;; Use the "call" instruction for long branches, but prefer to use "bra" for
5704 ;; short ones since it does not force us to save the link register.
5705
5706 ;; This define_insn uses the branch-shortening code to decide which
5707 ;; instruction it emits.  Since the main branch-shortening interface is
5708 ;; through get_attr_length(), the two alternatives must be given different
5709 ;; lengths.  Here we pretend that the far jump is 8 rather than 4 bytes
5710 ;; long, though both alternatives are really the same size.
5711 (define_insn "jump"
5712   [(set (pc) (label_ref (match_operand 0 "" "")))]
5713   ""
5714   "*
5715 {
5716   if (get_attr_length (insn) == 4)
5717     return \"bra %l0\";
5718   else
5719     return \"call %l0\";
5720 }"
5721   [(set (attr "length")
5722         (if_then_else
5723             (and (ge (minus (match_dup 0) (pc)) (const_int -32768))
5724                  (le (minus (match_dup 0) (pc)) (const_int 32764)))
5725             (const_int 4)
5726             (const_int 8)))
5727    (set (attr "far_jump")
5728         (if_then_else
5729             (eq_attr "length" "4")
5730             (const_string "no")
5731             (const_string "yes")))
5732    (set (attr "type")
5733         (if_then_else
5734             (eq_attr "length" "4")
5735             (const_string "jump")
5736             (const_string "call")))])
5737
5738 ;; Indirect jump through a register
5739 (define_insn "indirect_jump"
5740   [(set (pc) (match_operand:SI 0 "register_operand" "d,l"))]
5741   ""
5742   "@
5743    jmpl @(%0,%.)
5744    bralr"
5745   [(set_attr "length" "4")
5746    (set_attr "type" "jumpl,branch")])
5747
5748 ;; Instruction to jump to a variable address.  This is a low-level capability
5749 ;; which can be used to implement a dispatch table when there is no `casesi'
5750 ;; pattern.  Either the 'casesi' pattern or the 'tablejump' pattern, or both,
5751 ;; MUST be present in this file.
5752
5753 ;; This pattern requires two operands: the address or offset, and a label which
5754 ;; should immediately precede the jump table.  If the macro
5755 ;; `CASE_VECTOR_PC_RELATIVE' is defined then the first operand is an offset
5756 ;; which counts from the address of the table; otherwise, it is an absolute
5757 ;; address to jump to.  In either case, the first operand has mode `Pmode'.
5758
5759 ;; The `tablejump' insn is always the last insn before the jump table it uses.
5760 ;; Its assembler code normally has no need to use the second operand, but you
5761 ;; should incorporate it in the RTL pattern so that the jump optimizer will not
5762 ;; delete the table as unreachable code.
5763
5764 (define_expand "tablejump"
5765   [(parallel [(set (pc) (match_operand:SI 0 "address_operand" "p"))
5766               (use (label_ref (match_operand 1 "" "")))])]
5767   "!flag_pic"
5768   "")
5769
5770 (define_insn "tablejump_insn"
5771   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
5772    (use (label_ref (match_operand 1 "" "")))]
5773   ""
5774   "jmp%I0l %M0"
5775   [(set_attr "length" "4")
5776    (set_attr "type" "jumpl")])
5777
5778 ;; Implement switch statements when generating PIC code.  Switches are
5779 ;; implemented by `tablejump' when not using -fpic.
5780
5781 ;; Emit code here to do the range checking and make the index zero based.
5782 ;; operand 0 is the index
5783 ;; operand 1 is the lower bound
5784 ;; operand 2 is the range of indices (highest - lowest + 1)
5785 ;; operand 3 is the label that precedes the table itself
5786 ;; operand 4 is the fall through label
5787
5788 (define_expand "casesi"
5789   [(use (match_operand:SI 0 "integer_register_operand" ""))
5790    (use (match_operand:SI 1 "const_int_operand" ""))
5791    (use (match_operand:SI 2 "const_int_operand" ""))
5792    (use (match_operand 3 "" ""))
5793    (use (match_operand 4 "" ""))]
5794   "flag_pic"
5795   "
5796 {
5797   rtx indx;
5798   rtx scale;
5799   rtx low = operands[1];
5800   rtx range = operands[2];
5801   rtx table = operands[3];
5802   rtx treg;
5803   rtx fail = operands[4];
5804   rtx mem;
5805   rtx reg2;
5806   rtx reg3;
5807
5808   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
5809
5810   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
5811
5812   /* If we can't generate an immediate instruction, promote to register.  */
5813   if (! IN_RANGE_P (INTVAL (range), -2048, 2047))
5814     range = force_reg (SImode, range);
5815
5816   /* If low bound is 0, we don't have to subtract it.  */
5817   if (INTVAL (operands[1]) == 0)
5818     indx = operands[0];
5819   else
5820     {
5821       indx = gen_reg_rtx (SImode);
5822       if (IN_RANGE_P (INTVAL (low), -2047, 2048))
5823         emit_insn (gen_addsi3 (indx, operands[0], GEN_INT (- INTVAL (low))));
5824       else
5825         emit_insn (gen_subsi3 (indx, operands[0], force_reg (SImode, low)));
5826     }
5827
5828   /* Do an unsigned comparison (in the proper mode) between the index
5829      expression and the value which represents the length of the range.
5830      Since we just finished subtracting the lower bound of the range
5831      from the index expression, this comparison allows us to simultaneously
5832      check that the original index expression value is both greater than
5833      or equal to the minimum value of the range and less than or equal to
5834      the maximum value of the range.  */
5835
5836   emit_cmp_and_jump_insns (indx, range, GTU, NULL_RTX, SImode, 1, fail);
5837
5838   /* Move the table address to a register.  */
5839   treg = gen_reg_rtx (Pmode);
5840   emit_insn (gen_movsi (treg, gen_rtx_LABEL_REF (VOIDmode, table)));
5841
5842   /* Scale index-low by wordsize.  */
5843   scale = gen_reg_rtx (SImode);
5844   emit_insn (gen_ashlsi3 (scale, indx, const2_rtx));
5845
5846   /* Load the address, add the start of the table back in,
5847      and jump to it.  */
5848   mem = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, scale, treg));
5849   reg2 = gen_reg_rtx (SImode);
5850   reg3 = gen_reg_rtx (SImode);
5851   emit_insn (gen_movsi (reg2, mem));
5852   emit_insn (gen_addsi3 (reg3, reg2, treg));
5853   emit_jump_insn (gen_tablejump_insn (reg3, table));
5854   DONE;
5855 }")
5856
5857 \f
5858 ;; ::::::::::::::::::::
5859 ;; ::
5860 ;; :: Prologue and Epilogue instructions
5861 ;; ::
5862 ;; ::::::::::::::::::::
5863
5864 ;; Called after register allocation to add any instructions needed for the
5865 ;; prologue.  Using a prologue insn is favored compared to putting all of the
5866 ;; instructions in the FUNCTION_PROLOGUE macro, since it allows the scheduler
5867 ;; to intermix instructions with the saves of the caller saved registers.  In
5868 ;; some cases, it might be necessary to emit a barrier instruction as the last
5869 ;; insn to prevent such scheduling.
5870 (define_expand "prologue"
5871   [(const_int 1)]
5872   ""
5873   "
5874 {
5875   frv_expand_prologue ();
5876   DONE;
5877 }")
5878
5879 ;; Called after register allocation to add any instructions needed for the
5880 ;; epilogue.  Using an epilogue insn is favored compared to putting all of the
5881 ;; instructions in the FUNCTION_EPILOGUE macro, since it allows the scheduler
5882 ;; to intermix instructions with the restores of the caller saved registers.
5883 ;; In some cases, it might be necessary to emit a barrier instruction as the
5884 ;; first insn to prevent such scheduling.
5885 (define_expand "epilogue"
5886   [(const_int 2)]
5887   ""
5888   "
5889 {
5890   frv_expand_epilogue (true);
5891   DONE;
5892 }")
5893
5894 ;; This pattern, if defined, emits RTL for exit from a function without the final
5895 ;; branch back to the calling function.  This pattern will be emitted before any
5896 ;; sibling call (aka tail call) sites.
5897 ;;
5898 ;; The sibcall_epilogue pattern must not clobber any arguments used for
5899 ;; parameter passing or any stack slots for arguments passed to the current
5900 ;; function.
5901 (define_expand "sibcall_epilogue"
5902   [(const_int 3)]
5903   ""
5904   "
5905 {
5906   frv_expand_epilogue (false);
5907   DONE;
5908 }")
5909
5910 ;; Set up the pic register to hold the address of the pic table
5911 (define_insn "pic_prologue"
5912   [(set (match_operand:SI 0 "integer_register_operand" "=d")
5913         (unspec_volatile:SI [(const_int 0)] UNSPEC_PIC_PROLOGUE))
5914    (clobber (match_operand:SI 1 "lr_operand" "=l"))
5915    (clobber (match_operand:SI 2 "integer_register_operand" "=d"))]
5916   ""
5917   "*
5918 {
5919   static int frv_pic_labelno = 0;
5920
5921   operands[3] = GEN_INT (frv_pic_labelno++);
5922   return \"call %P3\\n%P3:\;movsg %1, %0\;sethi #gprelhi(%P3), %2\;setlo #gprello(%P3), %2\;sub %0,%2,%0\";
5923 }"
5924   [(set_attr "length" "16")
5925    (set_attr "type" "multi")])
5926 \f
5927 ;; ::::::::::::::::::::
5928 ;; ::
5929 ;; :: Miscellaneous instructions
5930 ;; ::
5931 ;; ::::::::::::::::::::
5932
5933 ;; No operation, needed in case the user uses -g but not -O.
5934 (define_insn "nop"
5935   [(const_int 0)]
5936   ""
5937   "nop"
5938   [(set_attr "length" "4")
5939    (set_attr "type" "int")])
5940
5941 (define_insn "fnop"
5942   [(const_int 1)]
5943   ""
5944   "fnop"
5945   [(set_attr "length" "4")
5946    (set_attr "type" "fnop")])
5947
5948 (define_insn "mnop"
5949   [(const_int 2)]
5950   ""
5951   "mnop"
5952   [(set_attr "length" "4")
5953    (set_attr "type" "mnop")])
5954
5955 ;; Pseudo instruction that prevents the scheduler from moving code above this
5956 ;; point.  Note, type unknown is used to make sure the VLIW instructions are
5957 ;; not continued past this point.
5958 (define_insn "blockage"
5959   [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
5960   ""
5961   "# blockage"
5962   [(set_attr "length" "0")
5963    (set_attr "type" "unknown")])
5964 \f
5965 ;; ::::::::::::::::::::
5966 ;; ::
5967 ;; :: Media instructions
5968 ;; ::
5969 ;; ::::::::::::::::::::
5970
5971 ;; Unimplemented instructions:
5972 ;;   - MCMPSH, MCMPUH
5973
5974 (define_constants
5975   [(UNSPEC_MLOGIC               100)
5976    (UNSPEC_MNOT                 101)
5977    (UNSPEC_MAVEH                102)
5978    (UNSPEC_MSATH                103)
5979    (UNSPEC_MADDH                104)
5980    (UNSPEC_MQADDH               105)
5981    (UNSPEC_MPACKH               106)
5982    (UNSPEC_MUNPACKH             107)
5983    (UNSPEC_MDPACKH              108)
5984    (UNSPEC_MBTOH                109)
5985    (UNSPEC_MHTOB                110)
5986    (UNSPEC_MROT                 111)
5987    (UNSPEC_MSHIFT               112)
5988    (UNSPEC_MEXPDHW              113)
5989    (UNSPEC_MEXPDHD              114)
5990    (UNSPEC_MWCUT                115)
5991    (UNSPEC_MMULH                116)
5992    (UNSPEC_MMULXH               117)
5993    (UNSPEC_MMACH                118)
5994    (UNSPEC_MMRDH                119)
5995    (UNSPEC_MQMULH               120)
5996    (UNSPEC_MQMULXH              121)
5997    (UNSPEC_MQMACH               122)
5998    (UNSPEC_MCPX                 123)
5999    (UNSPEC_MQCPX                124)
6000    (UNSPEC_MCUT                 125)
6001    (UNSPEC_MRDACC               126)
6002    (UNSPEC_MRDACCG              127)
6003    (UNSPEC_MWTACC               128)
6004    (UNSPEC_MWTACCG              129)
6005    (UNSPEC_MTRAP                130)
6006    (UNSPEC_MCLRACC              131)
6007    (UNSPEC_MCLRACCA             132)
6008    (UNSPEC_MCOP1                133)
6009    (UNSPEC_MCOP2                134)
6010    (UNSPEC_MDUNPACKH            135)
6011    (UNSPEC_MDUNPACKH_INTERNAL   136)
6012    (UNSPEC_MBTOHE               137)
6013    (UNSPEC_MBTOHE_INTERNAL      138)
6014    (UNSPEC_MBTOHE               137)
6015    (UNSPEC_MBTOHE_INTERNAL      138)
6016    (UNSPEC_MQMACH2              139)
6017    (UNSPEC_MADDACC              140)
6018    (UNSPEC_MDADDACC             141)
6019    (UNSPEC_MABSHS               142)
6020    (UNSPEC_MDROTLI              143)
6021    (UNSPEC_MCPLHI               144)
6022    (UNSPEC_MCPLI                145)
6023    (UNSPEC_MDCUTSSI             146)
6024    (UNSPEC_MQSATHS              147)
6025    (UNSPEC_MHSETLOS             148)
6026    (UNSPEC_MHSETLOH             149)
6027    (UNSPEC_MHSETHIS             150)
6028    (UNSPEC_MHSETHIH             151)
6029    (UNSPEC_MHDSETS              152)
6030    (UNSPEC_MHDSETH              153)
6031    (UNSPEC_MQLCLRHS             154)
6032    (UNSPEC_MQLMTHS              155)
6033    (UNSPEC_MQSLLHI              156)
6034    (UNSPEC_MQSRAHI              157)
6035    (UNSPEC_MASACCS              158)
6036    (UNSPEC_MDASACCS             159)
6037 ])
6038
6039 ;; Logic operations: type "mlogic"
6040
6041 (define_expand "mand"
6042   [(set (match_operand:SI 0 "fpr_operand" "")
6043         (unspec:SI [(match_operand:SI 1 "fpr_operand" "")
6044                     (match_operand:SI 2 "fpr_operand" "")
6045                     (match_dup 3)]
6046                    UNSPEC_MLOGIC))]
6047   "TARGET_MEDIA"
6048   "operands[3] = GEN_INT (FRV_BUILTIN_MAND);")
6049
6050 (define_expand "mor"
6051   [(set (match_operand:SI 0 "fpr_operand" "")
6052         (unspec:SI [(match_operand:SI 1 "fpr_operand" "")
6053                     (match_operand:SI 2 "fpr_operand" "")
6054                     (match_dup 3)]
6055                    UNSPEC_MLOGIC))]
6056   "TARGET_MEDIA"
6057   "operands[3] = GEN_INT (FRV_BUILTIN_MOR);")
6058
6059 (define_expand "mxor"
6060   [(set (match_operand:SI 0 "fpr_operand" "")
6061         (unspec:SI [(match_operand:SI 1 "fpr_operand" "")
6062                     (match_operand:SI 2 "fpr_operand" "")
6063                     (match_dup 3)]
6064                    UNSPEC_MLOGIC))]
6065   "TARGET_MEDIA"
6066   "operands[3] = GEN_INT (FRV_BUILTIN_MXOR);")
6067
6068 (define_insn "*mlogic"
6069   [(set (match_operand:SI 0 "fpr_operand" "=f")
6070         (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
6071                     (match_operand:SI 2 "fpr_operand" "f")
6072                     (match_operand:SI 3 "const_int_operand" "n")]
6073                    UNSPEC_MLOGIC))]
6074   "TARGET_MEDIA"
6075   "*
6076 {
6077   switch (INTVAL (operands[3]))
6078   {
6079   default:               break;
6080   case FRV_BUILTIN_MAND: return \"mand %1, %2, %0\";
6081   case FRV_BUILTIN_MOR:  return \"mor %1, %2, %0\";
6082   case FRV_BUILTIN_MXOR: return \"mxor %1, %2, %0\";
6083   }
6084
6085   fatal_insn (\"Bad media insn, mlogic\", insn);
6086 }"
6087   [(set_attr "length" "4")
6088    (set_attr "type" "mlogic")])
6089
6090 (define_insn "*cond_exec_mlogic"
6091   [(cond_exec
6092     (match_operator 0 "ccr_eqne_operator"
6093                     [(match_operand 1 "cr_operand" "C")
6094                      (const_int 0)])
6095     (set (match_operand:SI 2 "fpr_operand" "=f")
6096          (unspec:SI [(match_operand:SI 3 "fpr_operand" "f")
6097                      (match_operand:SI 4 "fpr_operand" "f")
6098                      (match_operand:SI 5 "const_int_operand" "n")]
6099                     UNSPEC_MLOGIC)))]
6100   "TARGET_MEDIA"
6101   "*
6102 {
6103   switch (INTVAL (operands[5]))
6104   {
6105   default:                  break;
6106   case FRV_BUILTIN_MAND: return \"cmand %3, %4, %2, %1, %e0\";
6107   case FRV_BUILTIN_MOR:  return \"cmor %3, %4, %2, %1, %e0\";
6108   case FRV_BUILTIN_MXOR: return \"cmxor %3, %4, %2, %1, %e0\";
6109   }
6110
6111   fatal_insn (\"Bad media insn, cond_exec_mlogic\", insn);
6112 }"
6113   [(set_attr "length" "4")
6114    (set_attr "type" "mlogic")])
6115
6116 ;; Logical not: type "mlogic"
6117
6118 (define_insn "mnot"
6119   [(set (match_operand:SI 0 "fpr_operand" "=f")
6120         (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")] UNSPEC_MNOT))]
6121   "TARGET_MEDIA"
6122   "mnot %1, %0"
6123   [(set_attr "length" "4")
6124    (set_attr "type" "mlogic")])
6125
6126 (define_insn "*cond_exec_mnot"
6127   [(cond_exec
6128     (match_operator 0 "ccr_eqne_operator"
6129                     [(match_operand 1 "cr_operand" "C")
6130                      (const_int 0)])
6131     (set (match_operand:SI 2 "fpr_operand" "=f")
6132          (unspec:SI [(match_operand:SI 3 "fpr_operand" "f")] UNSPEC_MNOT)))]
6133   "TARGET_MEDIA"
6134   "cmnot %3, %2, %1, %e0"
6135   [(set_attr "length" "4")
6136    (set_attr "type" "mlogic")])
6137
6138 ;; Dual average (halfword): type "maveh"
6139
6140 (define_insn "maveh"
6141   [(set (match_operand:SI 0 "fpr_operand" "=f")
6142         (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
6143                     (match_operand:SI 2 "fpr_operand" "f")]
6144                    UNSPEC_MAVEH))]
6145   "TARGET_MEDIA"
6146   "maveh %1, %2, %0"
6147   [(set_attr "length" "4")
6148    (set_attr "type" "maveh")])
6149
6150 ;; Dual saturation (halfword): type "msath"
6151
6152 (define_expand "msaths"
6153   [(set (match_operand:SI 0 "fpr_operand" "=f")
6154         (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
6155                     (match_operand:SI 2 "fpr_operand" "f")
6156                     (match_dup 3)]
6157                    UNSPEC_MSATH))]
6158   "TARGET_MEDIA"
6159   "operands[3] = GEN_INT (FRV_BUILTIN_MSATHS);")
6160
6161 (define_expand "msathu"
6162   [(set (match_operand:SI 0 "fpr_operand" "=f")
6163         (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
6164                     (match_operand:SI 2 "fpr_operand" "f")
6165                     (match_dup 3)]
6166                    UNSPEC_MSATH))]
6167   "TARGET_MEDIA"
6168   "operands[3] = GEN_INT (FRV_BUILTIN_MSATHU);")
6169
6170 (define_insn "*msath"
6171   [(set (match_operand:SI 0 "fpr_operand" "=f")
6172         (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
6173                     (match_operand:SI 2 "fpr_operand" "f")
6174                     (match_operand:SI 3 "const_int_operand" "n")]
6175                    UNSPEC_MSATH))]
6176   "TARGET_MEDIA"
6177   "*
6178 {
6179   switch (INTVAL (operands[3]))
6180   {
6181   default:                  break;
6182   case FRV_BUILTIN_MSATHS:  return \"msaths %1, %2, %0\";
6183   case FRV_BUILTIN_MSATHU:  return \"msathu %1, %2, %0\";
6184   }
6185
6186   fatal_insn (\"Bad media insn, msath\", insn);
6187 }"
6188   [(set_attr "length" "4")
6189    (set_attr "type" "msath")])
6190
6191 ;; Dual addition/subtraction with saturation (halfword): type "maddh"
6192
6193 (define_expand "maddhss"
6194   [(set (match_operand:SI 0 "fpr_operand" "=f")
6195         (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
6196                     (match_operand:SI 2 "fpr_operand" "f")
6197                     (match_dup 3)]
6198                    UNSPEC_MADDH))]
6199   "TARGET_MEDIA"
6200   "operands[3] = GEN_INT (FRV_BUILTIN_MADDHSS);")
6201
6202 (define_expand "maddhus"
6203   [(set (match_operand:SI 0 "fpr_operand" "=f")
6204         (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
6205                     (match_operand:SI 2 "fpr_operand" "f")
6206                     (match_dup 3)]
6207                    UNSPEC_MADDH))]
6208   "TARGET_MEDIA"
6209   "operands[3] = GEN_INT (FRV_BUILTIN_MADDHUS);")
6210
6211 (define_expand "msubhss"
6212   [(set (match_operand:SI 0 "fpr_operand" "=f")
6213         (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
6214                     (match_operand:SI 2 "fpr_operand" "f")
6215                     (match_dup 3)]
6216                    UNSPEC_MADDH))]
6217   "TARGET_MEDIA"
6218   "operands[3] = GEN_INT (FRV_BUILTIN_MSUBHSS);")
6219
6220 (define_expand "msubhus"
6221   [(set (match_operand:SI 0 "fpr_operand" "=f")
6222         (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
6223                     (match_operand:SI 2 "fpr_operand" "f")
6224                     (match_dup 3)]
6225                    UNSPEC_MADDH))]
6226   "TARGET_MEDIA"
6227   "operands[3] = GEN_INT (FRV_BUILTIN_MSUBHUS);")
6228
6229 (define_insn "*maddh"
6230   [(set (match_operand:SI 0 "fpr_operand" "=f")
6231         (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
6232                     (match_operand:SI 2 "fpr_operand" "f")
6233                     (match_operand:SI 3 "const_int_operand" "n")]
6234                    UNSPEC_MADDH))]
6235   "TARGET_MEDIA"
6236   "*
6237 {
6238   switch (INTVAL (operands[3]))
6239   {
6240   default:                  break;
6241   case FRV_BUILTIN_MADDHSS: return \"maddhss %1, %2, %0\";
6242   case FRV_BUILTIN_MADDHUS: return \"maddhus %1, %2, %0\";
6243   case FRV_BUILTIN_MSUBHSS: return \"msubhss %1, %2, %0\";
6244   case FRV_BUILTIN_MSUBHUS: return \"msubhus %1, %2, %0\";
6245   }
6246
6247   fatal_insn (\"Bad media insn, maddh\", insn);
6248 }"
6249   [(set_attr "length" "4")
6250    (set_attr "type" "maddh")])
6251
6252 (define_insn "*cond_exec_maddh"
6253   [(cond_exec
6254     (match_operator 0 "ccr_eqne_operator"
6255                     [(match_operand 1 "cr_operand" "C")
6256                      (const_int 0)])
6257     (set (match_operand:SI 2 "fpr_operand" "=f")
6258          (unspec:SI [(match_operand:SI 3 "fpr_operand" "f")
6259                      (match_operand:SI 4 "fpr_operand" "f")
6260                      (match_operand:SI 5 "const_int_operand" "n")]
6261                     UNSPEC_MADDH)))]
6262   "TARGET_MEDIA"
6263   "*
6264 {
6265   switch (INTVAL (operands[5]))
6266   {
6267   default:                  break;
6268   case FRV_BUILTIN_MADDHSS: return \"cmaddhss %3, %4, %2, %1, %e0\";
6269   case FRV_BUILTIN_MADDHUS: return \"cmaddhus %3, %4, %2, %1, %e0\";
6270   case FRV_BUILTIN_MSUBHSS: return \"cmsubhss %3, %4, %2, %1, %e0\";
6271   case FRV_BUILTIN_MSUBHUS: return \"cmsubhus %3, %4, %2, %1, %e0\";
6272   }
6273
6274   fatal_insn (\"Bad media insn, cond_exec_maddh\", insn);
6275 }"
6276   [(set_attr "length" "4")
6277    (set_attr "type" "maddh")])
6278
6279 ;; Quad addition/subtraction with saturation (halfword): type "mqaddh"
6280
6281 (define_expand "mqaddhss"
6282   [(set (match_operand:DI 0 "even_fpr_operand" "=h")
6283         (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
6284                     (match_operand:DI 2 "even_fpr_operand" "h")
6285                     (match_dup 3)]
6286                    UNSPEC_MQADDH))]
6287   "TARGET_MEDIA"
6288   "operands[3] = GEN_INT (FRV_BUILTIN_MQADDHSS);")
6289
6290 (define_expand "mqaddhus"
6291   [(set (match_operand:DI 0 "even_fpr_operand" "=h")
6292         (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
6293                     (match_operand:DI 2 "even_fpr_operand" "h")
6294                     (match_dup 3)]
6295                    UNSPEC_MQADDH))]
6296   "TARGET_MEDIA"
6297   "operands[3] = GEN_INT (FRV_BUILTIN_MQADDHUS);")
6298
6299 (define_expand "mqsubhss"
6300   [(set (match_operand:DI 0 "even_fpr_operand" "=h")
6301         (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
6302                     (match_operand:DI 2 "even_fpr_operand" "h")
6303                     (match_dup 3)]
6304                    UNSPEC_MQADDH))]
6305   "TARGET_MEDIA"
6306   "operands[3] = GEN_INT (FRV_BUILTIN_MQSUBHSS);")
6307
6308 (define_expand "mqsubhus"
6309   [(set (match_operand:DI 0 "even_fpr_operand" "=h")
6310         (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
6311                     (match_operand:DI 2 "even_fpr_operand" "h")
6312                     (match_dup 3)]
6313                    UNSPEC_MQADDH))]
6314   "TARGET_MEDIA"
6315   "operands[3] = GEN_INT (FRV_BUILTIN_MQSUBHUS);")
6316
6317 (define_insn "*mqaddh"
6318   [(set (match_operand:DI 0 "even_fpr_operand" "=h")
6319         (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
6320                     (match_operand:DI 2 "even_fpr_operand" "h")
6321                     (match_operand:SI 3 "const_int_operand" "n")]
6322                    UNSPEC_MQADDH))]
6323   "TARGET_MEDIA"
6324   "*
6325 {
6326   switch (INTVAL (operands[3]))
6327   {
6328   default:                   break;
6329   case FRV_BUILTIN_MQADDHSS: return \"mqaddhss %1, %2, %0\";
6330   case FRV_BUILTIN_MQADDHUS: return \"mqaddhus %1, %2, %0\";
6331   case FRV_BUILTIN_MQSUBHSS: return \"mqsubhss %1, %2, %0\";
6332   case FRV_BUILTIN_MQSUBHUS: return \"mqsubhus %1, %2, %0\";
6333   }
6334
6335   fatal_insn (\"Bad media insn, mqaddh\", insn);
6336 }"
6337   [(set_attr "length" "4")
6338    (set_attr "type" "mqaddh")])
6339
6340 (define_insn "*cond_exec_mqaddh"
6341   [(cond_exec
6342     (match_operator 0 "ccr_eqne_operator"
6343                     [(match_operand 1 "cr_operand" "C")
6344                      (const_int 0)])
6345     (set (match_operand:DI 2 "even_fpr_operand" "=h")
6346          (unspec:DI [(match_operand:DI 3 "even_fpr_operand" "h")
6347                      (match_operand:DI 4 "even_fpr_operand" "h")
6348                      (match_operand:SI 5 "const_int_operand" "n")]
6349                     UNSPEC_MQADDH)))]
6350   "TARGET_MEDIA"
6351   "*
6352 {
6353   switch (INTVAL (operands[5]))
6354   {
6355   default:                   break;
6356   case FRV_BUILTIN_MQADDHSS: return \"cmqaddhss %3, %4, %2, %1, %e0\";
6357   case FRV_BUILTIN_MQADDHUS: return \"cmqaddhus %3, %4, %2, %1, %e0\";
6358   case FRV_BUILTIN_MQSUBHSS: return \"cmqsubhss %3, %4, %2, %1, %e0\";
6359   case FRV_BUILTIN_MQSUBHUS: return \"cmqsubhus %3, %4, %2, %1, %e0\";
6360   }
6361
6362   fatal_insn (\"Bad media insn, cond_exec_mqaddh\", insn);
6363 }"
6364   [(set_attr "length" "4")
6365    (set_attr "type" "mqaddh")])
6366
6367 ;; Pack halfword: type "mpackh"
6368
6369 (define_insn "mpackh"
6370   [(set (match_operand:SI 0 "fpr_operand" "=f")
6371         (unspec:SI [(match_operand:HI 1 "fpr_operand" "f")
6372                     (match_operand:HI 2 "fpr_operand" "f")]
6373                    UNSPEC_MPACKH))]
6374   "TARGET_MEDIA"
6375   "mpackh %1, %2, %0"
6376   [(set_attr "length" "4")
6377    (set_attr "type" "mpackh")])
6378
6379 ;; Unpack halfword: type "mpackh"
6380
6381 (define_insn "munpackh"
6382   [(set (match_operand:DI 0 "even_fpr_operand" "=h")
6383         (unspec:DI [(match_operand:SI 1 "fpr_operand" "f")]
6384                    UNSPEC_MUNPACKH))]
6385   "TARGET_MEDIA"
6386   "munpackh %1, %0"
6387   [(set_attr "length" "4")
6388    (set_attr "type" "munpackh")])
6389
6390 ;; Dual pack halfword: type "mdpackh"
6391
6392 (define_insn "mdpackh"
6393     [(set (match_operand:DI 0 "even_fpr_operand" "=h")
6394           (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
6395                       (match_operand:DI 2 "even_fpr_operand" "h")]
6396                      UNSPEC_MDPACKH))]
6397   "TARGET_MEDIA"
6398   "mdpackh %1, %2, %0"
6399   [(set_attr "length" "4")
6400    (set_attr "type" "mdpackh")])
6401
6402 ;; Byte-halfword conversion: type "mbhconv"
6403
6404 (define_insn "mbtoh"
6405   [(set (match_operand:DI 0 "even_fpr_operand" "=h")
6406         (unspec:DI [(match_operand:SI 1 "fpr_operand" "f")]
6407                    UNSPEC_MBTOH))]
6408   "TARGET_MEDIA"
6409   "mbtoh %1, %0"
6410   [(set_attr "length" "4")
6411    (set_attr "type" "mbhconv")])
6412
6413 (define_insn "*cond_exec_mbtoh"
6414   [(cond_exec
6415     (match_operator 0 "ccr_eqne_operator"
6416                     [(match_operand 1 "cr_operand" "C")
6417                      (const_int 0)])
6418     (set (match_operand:DI 2 "even_fpr_operand" "=h")
6419          (unspec:DI [(match_operand:SI 3 "fpr_operand" "f")]
6420                     UNSPEC_MBTOH)))]
6421   "TARGET_MEDIA"
6422   "cmbtoh %3, %2, %1, %e0"
6423   [(set_attr "length" "4")
6424    (set_attr "type" "mbhconv")])
6425
6426 (define_insn "mhtob"
6427   [(set (match_operand:SI 0 "fpr_operand" "=f")
6428         (unspec:SI [(match_operand:DI 1 "even_fpr_operand" "h")]
6429                    UNSPEC_MHTOB))]
6430   "TARGET_MEDIA"
6431   "mhtob %1, %0"
6432   [(set_attr "length" "4")
6433    (set_attr "type" "mbhconv")])
6434
6435 (define_insn "*cond_exec_mhtob"
6436   [(cond_exec
6437     (match_operator 0 "ccr_eqne_operator"
6438                     [(match_operand 1 "cr_operand" "C")
6439                      (const_int 0)])
6440     (set (match_operand:SI 2 "fpr_operand" "=f")
6441          (unspec:SI [(match_operand:DI 3 "even_fpr_operand" "h")]
6442                     UNSPEC_MHTOB)))]
6443   "TARGET_MEDIA"
6444   "cmhtob %3, %2, %1, %e0"
6445   [(set_attr "length" "4")
6446    (set_attr "type" "mbhconv")])
6447
6448 ;; Rotate: type "mrot"
6449
6450 (define_expand "mrotli"
6451   [(set (match_operand:SI 0 "fpr_operand" "")
6452         (unspec:SI [(match_operand:SI 1 "fpr_operand" "")
6453                     (match_operand:SI 2 "uint5_operand" "")
6454                     (match_dup 3)]
6455                    UNSPEC_MROT))]
6456   "TARGET_MEDIA"
6457   "operands[3] = GEN_INT (FRV_BUILTIN_MROTLI);")
6458
6459 (define_expand "mrotri"
6460   [(set (match_operand:SI 0 "fpr_operand" "")
6461         (unspec:SI [(match_operand:SI 1 "fpr_operand" "")
6462                     (match_operand:SI 2 "uint5_operand" "")
6463                     (match_dup 3)]
6464                    UNSPEC_MROT))]
6465   "TARGET_MEDIA"
6466   "operands[3] = GEN_INT (FRV_BUILTIN_MROTRI);")
6467
6468 (define_insn "*mrot"
6469   [(set (match_operand:SI 0 "fpr_operand" "=f")
6470         (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
6471                     (match_operand:SI 2 "uint5_operand" "I")
6472                     (match_operand:SI 3 "const_int_operand" "n")]
6473                    UNSPEC_MROT))]
6474   "TARGET_MEDIA"
6475   "*
6476 {
6477   switch (INTVAL (operands[3]))
6478   {
6479   default:                 break;
6480   case FRV_BUILTIN_MROTLI: return \"mrotli %1, %2, %0\";
6481   case FRV_BUILTIN_MROTRI: return \"mrotri %1, %2, %0\";
6482   }
6483
6484   fatal_insn (\"Bad media insn, mrot\", insn);
6485 }"
6486   [(set_attr "length" "4")
6487    (set_attr "type" "mrot")])
6488
6489 ;; Dual shift halfword: type "msh"
6490
6491 (define_expand "msllhi"
6492   [(set (match_operand:SI 0 "fpr_operand" "")
6493         (unspec:SI [(match_operand:SI 1 "fpr_operand" "")
6494                     (match_operand:SI 2 "uint4_operand" "")
6495                     (match_dup 3)]
6496                    UNSPEC_MSHIFT))]
6497   "TARGET_MEDIA"
6498   "operands[3] = GEN_INT (FRV_BUILTIN_MSLLHI);")
6499
6500 (define_expand "msrlhi"
6501   [(set (match_operand:SI 0 "fpr_operand" "")
6502         (unspec:SI [(match_operand:SI 1 "fpr_operand" "")
6503                     (match_operand:SI 2 "uint4_operand" "")
6504                     (match_dup 3)]
6505                    UNSPEC_MSHIFT))]
6506   "TARGET_MEDIA"
6507   "operands[3] = GEN_INT (FRV_BUILTIN_MSRLHI);")
6508
6509 (define_expand "msrahi"
6510   [(set (match_operand:SI 0 "fpr_operand" "")
6511         (unspec:SI [(match_operand:SI 1 "fpr_operand" "")
6512                     (match_operand:SI 2 "uint4_operand" "")
6513                     (match_dup 3)]
6514                    UNSPEC_MSHIFT))]
6515   "TARGET_MEDIA"
6516   "operands[3] = GEN_INT (FRV_BUILTIN_MSRAHI);")
6517
6518 (define_insn "*mshift"
6519   [(set (match_operand:SI 0 "fpr_operand" "=f")
6520         (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
6521                     (match_operand:SI 2 "uint4_operand" "I")
6522                     (match_operand:SI 3 "const_int_operand" "n")]
6523                    UNSPEC_MSHIFT))]
6524   "TARGET_MEDIA"
6525   "*
6526 {
6527   switch (INTVAL (operands[3]))
6528   {
6529   default:                 break;
6530   case FRV_BUILTIN_MSLLHI: return \"msllhi %1, %2, %0\";
6531   case FRV_BUILTIN_MSRLHI: return \"msrlhi %1, %2, %0\";
6532   case FRV_BUILTIN_MSRAHI: return \"msrahi %1, %2, %0\";
6533   }
6534
6535   fatal_insn (\"Bad media insn, mshift\", insn);
6536 }"
6537   [(set_attr "length" "4")
6538    (set_attr "type" "mshift")])
6539
6540 ;; Expand halfword to word: type "mexpdhw"
6541
6542 (define_insn "mexpdhw"
6543   [(set (match_operand:SI 0 "fpr_operand" "=f")
6544         (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
6545                     (match_operand:SI 2 "uint1_operand" "I")]
6546                    UNSPEC_MEXPDHW))]
6547   "TARGET_MEDIA"
6548   "mexpdhw %1, %2, %0"
6549   [(set_attr "length" "4")
6550    (set_attr "type" "mexpdhw")])
6551
6552 (define_insn "*cond_exec_mexpdhw"
6553   [(cond_exec
6554     (match_operator 0 "ccr_eqne_operator"
6555                     [(match_operand 1 "cr_operand" "C")
6556                      (const_int 0)])
6557     (set (match_operand:SI 2 "fpr_operand" "=f")
6558          (unspec:SI [(match_operand:SI 3 "fpr_operand" "f")
6559                      (match_operand:SI 4 "uint1_operand" "I")]
6560                     UNSPEC_MEXPDHW)))]
6561   "TARGET_MEDIA"
6562   "cmexpdhw %3, %4, %2, %1, %e0"
6563   [(set_attr "length" "4")
6564    (set_attr "type" "mexpdhw")])
6565
6566 ;; Expand halfword to double: type "mexpdhd"
6567
6568 (define_insn "mexpdhd"
6569   [(set (match_operand:DI 0 "even_fpr_operand" "=h")
6570         (unspec:DI [(match_operand:SI 1 "fpr_operand" "f")
6571                     (match_operand:SI 2 "uint1_operand" "I")]
6572                    UNSPEC_MEXPDHD))]
6573   "TARGET_MEDIA"
6574   "mexpdhd %1, %2, %0"
6575   [(set_attr "length" "4")
6576    (set_attr "type" "mexpdhd")])
6577
6578 (define_insn "*cond_exec_mexpdhd"
6579   [(cond_exec
6580     (match_operator 0 "ccr_eqne_operator"
6581                     [(match_operand 1 "cr_operand" "C")
6582                      (const_int 0)])
6583     (set (match_operand:DI 2 "even_fpr_operand" "=h")
6584          (unspec:DI [(match_operand:SI 3 "fpr_operand" "f")
6585                      (match_operand:SI 4 "uint1_operand" "I")]
6586                     UNSPEC_MEXPDHD)))]
6587   "TARGET_MEDIA"
6588   "cmexpdhd %3, %4, %2, %1, %e0"
6589   [(set_attr "length" "4")
6590    (set_attr "type" "mexpdhd")])
6591
6592 ;; FR cut: type "mwcut"
6593
6594 (define_insn "mwcut"
6595   [(set (match_operand:SI 0 "fpr_operand" "=f")
6596         (unspec:SI [(match_operand:DI 1 "fpr_operand" "f")
6597                     (match_operand:SI 2 "fpr_or_int6_operand" "fI")]
6598                    UNSPEC_MWCUT))]
6599   "TARGET_MEDIA"
6600   "mwcut%i2 %1, %2, %0"
6601   [(set_attr "length" "4")
6602    (set_attr "type" "mwcut")])
6603
6604 ;; Dual multiplication (halfword): type "mmulh"
6605
6606 (define_expand "mmulhs"
6607   [(parallel [(set (match_operand:DI 0 "even_acc_operand" "=b")
6608                    (unspec:DI [(match_operand:SI 1 "fpr_operand" "f")
6609                                (match_operand:SI 2 "fpr_operand" "f")
6610                                (match_dup 4)]
6611                               UNSPEC_MMULH))
6612               (set (match_operand:HI 3 "accg_operand" "=B")
6613                    (unspec:HI [(const_int 0)] UNSPEC_MMULH))])]
6614   "TARGET_MEDIA"
6615   "operands[4] = GEN_INT (FRV_BUILTIN_MMULHS);")
6616
6617 (define_expand "mmulhu"
6618   [(parallel [(set (match_operand:DI 0 "even_acc_operand" "=b")
6619                    (unspec:DI [(match_operand:SI 1 "fpr_operand" "f")
6620                                (match_operand:SI 2 "fpr_operand" "f")
6621                                (match_dup 4)]
6622                               UNSPEC_MMULH))
6623               (set (match_operand:HI 3 "accg_operand" "=B")
6624                    (unspec:HI [(const_int 0)] UNSPEC_MMULH))])]
6625   "TARGET_MEDIA"
6626   "operands[4] = GEN_INT (FRV_BUILTIN_MMULHU);")
6627
6628 (define_insn "*mmulh"
6629   [(set (match_operand:DI 0 "even_acc_operand" "=b")
6630         (unspec:DI [(match_operand:SI 1 "fpr_operand" "f")
6631                     (match_operand:SI 2 "fpr_operand" "f")
6632                     (match_operand:SI 3 "const_int_operand" "n")]
6633                    UNSPEC_MMULH))
6634    (set (match_operand:HI 4 "accg_operand" "=B")
6635         (unspec:HI [(const_int 0)] UNSPEC_MMULH))]
6636   "TARGET_MEDIA"
6637   "*
6638 {
6639   switch (INTVAL (operands[3]))
6640   {
6641   default:                  break;
6642   case FRV_BUILTIN_MMULHS:  return \"mmulhs %1, %2, %0\";
6643   case FRV_BUILTIN_MMULHU:  return \"mmulhu %1, %2, %0\";
6644   }
6645
6646   fatal_insn (\"Bad media insn, mmulh\", insn);
6647 }"
6648   [(set_attr "length" "4")
6649    (set_attr "type" "mmulh")])
6650
6651 (define_insn "*cond_exec_mmulh"
6652   [(cond_exec
6653     (match_operator 0 "ccr_eqne_operator"
6654                     [(match_operand 1 "cr_operand" "C")
6655                      (const_int 0)])
6656     (parallel [(set (match_operand:DI 2 "even_acc_operand" "=b")
6657                     (unspec:DI [(match_operand:SI 3 "fpr_operand" "f")
6658                                 (match_operand:SI 4 "fpr_operand" "f")
6659                                 (match_operand:SI 5 "const_int_operand" "n")]
6660                                UNSPEC_MMULH))
6661                (set (match_operand:HI 6 "accg_operand" "=B")
6662                     (unspec:HI [(const_int 0)] UNSPEC_MMULH))]))]
6663   "TARGET_MEDIA"
6664   "*
6665 {
6666   switch (INTVAL (operands[5]))
6667   {
6668   default:                  break;
6669   case FRV_BUILTIN_MMULHS:  return \"cmmulhs %3, %4, %2, %1, %e0\";
6670   case FRV_BUILTIN_MMULHU:  return \"cmmulhu %3, %4, %2, %1, %e0\";
6671   }
6672
6673   fatal_insn (\"Bad media insn, cond_exec_mmulh\", insn);
6674 }"
6675   [(set_attr "length" "4")
6676    (set_attr "type" "mmulh")])
6677
6678 ;; Dual cross multiplication (halfword): type "mmulxh"
6679
6680 (define_expand "mmulxhs"
6681   [(parallel [(set (match_operand:DI 0 "even_acc_operand" "=b")
6682                    (unspec:DI [(match_operand:SI 1 "fpr_operand" "f")
6683                                (match_operand:SI 2 "fpr_operand" "f")
6684                                (match_dup 4)]
6685                               UNSPEC_MMULXH))
6686               (set (match_operand:HI 3 "accg_operand" "=B")
6687                    (unspec:HI [(const_int 0)] UNSPEC_MMULXH))])]
6688   "TARGET_MEDIA"
6689   "operands[4] = GEN_INT (FRV_BUILTIN_MMULXHS);")
6690
6691 (define_expand "mmulxhu"
6692   [(parallel [(set (match_operand:DI 0 "even_acc_operand" "=b")
6693                    (unspec:DI [(match_operand:SI 1 "fpr_operand" "f")
6694                                (match_operand:SI 2 "fpr_operand" "f")
6695                                (match_dup 4)]
6696                               UNSPEC_MMULXH))
6697               (set (match_operand:HI 3 "accg_operand" "=B")
6698                    (unspec:HI [(const_int 0)] UNSPEC_MMULXH))])]
6699   "TARGET_MEDIA"
6700   "operands[4] = GEN_INT (FRV_BUILTIN_MMULXHU);")
6701
6702 (define_insn "*mmulxh"
6703   [(set (match_operand:DI 0 "even_acc_operand" "=b")
6704         (unspec:DI [(match_operand:SI 1 "fpr_operand" "f")
6705                     (match_operand:SI 2 "fpr_operand" "f")
6706                     (match_operand:SI 3 "const_int_operand" "n")]
6707                    UNSPEC_MMULXH))
6708    (set (match_operand:HI 4 "accg_operand" "=B")
6709         (unspec:HI [(const_int 0)] UNSPEC_MMULXH))]
6710   "TARGET_MEDIA"
6711   "*
6712 {
6713   switch (INTVAL (operands[3]))
6714   {
6715   default:                  break;
6716   case FRV_BUILTIN_MMULXHS: return \"mmulxhs %1, %2, %0\";
6717   case FRV_BUILTIN_MMULXHU: return \"mmulxhu %1, %2, %0\";
6718   }
6719
6720   fatal_insn (\"Bad media insn, mmulxh\", insn);
6721 }"
6722   [(set_attr "length" "4")
6723    (set_attr "type" "mmulxh")])
6724
6725 ;; Dual product-sum (halfword): type "mmach"
6726
6727 (define_expand "mmachs"
6728   [(parallel [(set (match_operand:DI 0 "even_acc_operand" "+b")
6729                    (unspec:DI [(match_dup 0)
6730                                (match_operand:SI 1 "fpr_operand" "f")
6731                                (match_operand:SI 2 "fpr_operand" "f")
6732                                (match_operand:HI 3 "accg_operand" "+B")
6733                                (match_dup 4)]
6734                               UNSPEC_MMACH))
6735               (set (match_dup 3)
6736                    (unspec:HI [(const_int 0)] UNSPEC_MMACH))])]
6737   "TARGET_MEDIA"
6738   "operands[4] = GEN_INT (FRV_BUILTIN_MMACHS);")
6739
6740 (define_expand "mmachu"
6741   [(parallel [(set (match_operand:DI 0 "even_acc_operand" "+b")
6742                    (unspec:DI [(match_dup 0)
6743                                (match_operand:SI 1 "fpr_operand" "f")
6744                                (match_operand:SI 2 "fpr_operand" "f")
6745                                (match_operand:HI 3 "accg_operand" "+B")
6746                                (match_dup 4)]
6747                               UNSPEC_MMACH))
6748               (set (match_dup 3)
6749                    (unspec:HI [(const_int 0)] UNSPEC_MMACH))])]
6750   "TARGET_MEDIA"
6751   "operands[4] = GEN_INT (FRV_BUILTIN_MMACHU);")
6752
6753 (define_insn "*mmach"
6754   [(set (match_operand:DI 0 "even_acc_operand" "+b")
6755         (unspec:DI [(match_dup 0)
6756                     (match_operand:SI 1 "fpr_operand" "f")
6757                     (match_operand:SI 2 "fpr_operand" "f")
6758                     (match_operand:HI 3 "accg_operand" "+B")
6759                     (match_operand:SI 4 "const_int_operand" "n")]
6760                    UNSPEC_MMACH))
6761    (set (match_dup 3) (unspec:HI [(const_int 0)] UNSPEC_MMACH))]
6762   "TARGET_MEDIA"
6763   "*
6764 {
6765   switch (INTVAL (operands[4]))
6766   {
6767   default:                 break;
6768   case FRV_BUILTIN_MMACHS: return \"mmachs %1, %2, %0\";
6769   case FRV_BUILTIN_MMACHU: return \"mmachu %1, %2, %0\";
6770   }
6771
6772   fatal_insn (\"Bad media insn, mmach\", insn);
6773 }"
6774   [(set_attr "length" "4")
6775    (set_attr "type" "mmach")])
6776
6777 (define_insn "*cond_exec_mmach"
6778   [(cond_exec
6779     (match_operator 0 "ccr_eqne_operator"
6780                     [(match_operand 1 "cr_operand" "C")
6781                      (const_int 0)])
6782     (parallel [(set (match_operand:DI 2 "even_acc_operand" "+b")
6783                     (unspec:DI [(match_dup 2)
6784                                 (match_operand:SI 3 "fpr_operand" "f")
6785                                 (match_operand:SI 4 "fpr_operand" "f")
6786                                 (match_operand:HI 5 "accg_operand" "+B")
6787                                 (match_operand:SI 6 "const_int_operand" "n")]
6788                                UNSPEC_MMACH))
6789                (set (match_dup 5)
6790                     (unspec:HI [(const_int 0)] UNSPEC_MMACH))]))]
6791   "TARGET_MEDIA"
6792   "*
6793 {
6794   switch (INTVAL (operands[6]))
6795   {
6796   default:                 break;
6797   case FRV_BUILTIN_MMACHS: return \"cmmachs %3, %4, %2, %1, %e0\";
6798   case FRV_BUILTIN_MMACHU: return \"cmmachu %3, %4, %2, %1, %e0\";
6799   }
6800
6801   fatal_insn (\"Bad media insn, cond_exec_mmach\", insn);
6802 }"
6803   [(set_attr "length" "4")
6804    (set_attr "type" "mmach")])
6805
6806 ;; Dual product-difference: type "mmrdh"
6807
6808 (define_expand "mmrdhs"
6809   [(parallel [(set (match_operand:DI 0 "even_acc_operand" "+b")
6810                    (unspec:DI [(match_dup 0)
6811                                (match_operand:SI 1 "fpr_operand" "f")
6812                                (match_operand:SI 2 "fpr_operand" "f")
6813                                (match_operand:HI 3 "accg_operand" "+B")
6814                                (match_dup 4)]
6815                               UNSPEC_MMRDH))
6816               (set (match_dup 3)
6817                    (unspec:HI [(const_int 0)] UNSPEC_MMRDH))])]
6818   "TARGET_MEDIA"
6819   "operands[4] = GEN_INT (FRV_BUILTIN_MMRDHS);")
6820
6821 (define_expand "mmrdhu"
6822   [(parallel [(set (match_operand:DI 0 "even_acc_operand" "+b")
6823                    (unspec:DI [(match_dup 0)
6824                                (match_operand:SI 1 "fpr_operand" "f")
6825                                (match_operand:SI 2 "fpr_operand" "f")
6826                                (match_operand:HI 3 "accg_operand" "+B")
6827                                (match_dup 4)]
6828                               UNSPEC_MMRDH))
6829               (set (match_dup 3)
6830                    (unspec:HI [(const_int 0)] UNSPEC_MMRDH))])]
6831   "TARGET_MEDIA"
6832   "operands[4] = GEN_INT (FRV_BUILTIN_MMRDHU);")
6833
6834 (define_insn "*mmrdh"
6835   [(set (match_operand:DI 0 "even_acc_operand" "+b")
6836         (unspec:DI [(match_dup 0)
6837                     (match_operand:SI 1 "fpr_operand" "f")
6838                     (match_operand:SI 2 "fpr_operand" "f")
6839                     (match_operand:HI 3 "accg_operand" "+B")
6840                     (match_operand:SI 4 "const_int_operand" "n")]
6841                    UNSPEC_MMRDH))
6842    (set (match_dup 3)
6843         (unspec:HI [(const_int 0)] UNSPEC_MMRDH))]
6844   "TARGET_MEDIA"
6845   "*
6846 {
6847   switch (INTVAL (operands[4]))
6848   {
6849   default:                 break;
6850   case FRV_BUILTIN_MMRDHS: return \"mmrdhs %1, %2, %0\";
6851   case FRV_BUILTIN_MMRDHU: return \"mmrdhu %1, %2, %0\";
6852   }
6853
6854   fatal_insn (\"Bad media insn, mrdh\", insn);
6855 }"
6856   [(set_attr "length" "4")
6857    (set_attr "type" "mmrdh")])
6858
6859 ;; Quad multiply (halfword): type "mqmulh"
6860
6861 (define_expand "mqmulhs"
6862   [(parallel [(set (match_operand:V4SI 0 "quad_acc_operand" "=A")
6863                    (unspec:V4SI [(match_operand:DI 1 "even_fpr_operand" "h")
6864                                  (match_operand:DI 2 "even_fpr_operand" "h")
6865                                  (match_dup 4)]
6866                                 UNSPEC_MQMULH))
6867               (set (match_operand:V4QI 3 "accg_operand" "=B")
6868                    (unspec:V4QI [(const_int 0)] UNSPEC_MQMULH))])]
6869   "TARGET_MEDIA"
6870   "operands[4] = GEN_INT (FRV_BUILTIN_MQMULHS);")
6871
6872 (define_expand "mqmulhu"
6873   [(parallel [(set (match_operand:V4SI 0 "quad_acc_operand" "=A")
6874                    (unspec:V4SI [(match_operand:DI 1 "even_fpr_operand" "h")
6875                                  (match_operand:DI 2 "even_fpr_operand" "h")
6876                                  (match_dup 4)]
6877                                 UNSPEC_MQMULH))
6878               (set (match_operand:V4QI 3 "accg_operand" "=B")
6879                    (unspec:V4QI [(const_int 0)] UNSPEC_MQMULH))])]
6880   "TARGET_MEDIA"
6881   "operands[4] = GEN_INT (FRV_BUILTIN_MQMULHU);")
6882
6883 (define_insn "*mqmulh"
6884   [(set (match_operand:V4SI 0 "quad_acc_operand" "=A")
6885         (unspec:V4SI [(match_operand:DI 1 "even_fpr_operand" "h")
6886                       (match_operand:DI 2 "even_fpr_operand" "h")
6887                       (match_operand:SI 3 "const_int_operand" "n")]
6888                      UNSPEC_MQMULH))
6889    (set (match_operand:V4QI 4 "accg_operand" "=B")
6890         (unspec:V4QI [(const_int 0)] UNSPEC_MQMULH))]
6891   "TARGET_MEDIA"
6892   "*
6893 {
6894   switch (INTVAL (operands[3]))
6895   {
6896   default:                   break;
6897   case FRV_BUILTIN_MQMULHS:  return \"mqmulhs %1, %2, %0\";
6898   case FRV_BUILTIN_MQMULHU:  return \"mqmulhu %1, %2, %0\";
6899   }
6900
6901   fatal_insn (\"Bad media insn, mqmulh\", insn);
6902 }"
6903   [(set_attr "length" "4")
6904    (set_attr "type" "mqmulh")])
6905
6906 (define_insn "*cond_exec_mqmulh"
6907   [(cond_exec
6908     (match_operator 0 "ccr_eqne_operator"
6909                     [(match_operand 1 "cr_operand" "C")
6910                      (const_int 0)])
6911     (parallel [(set (match_operand:V4SI 2 "quad_acc_operand" "=A")
6912                     (unspec:V4SI [(match_operand:DI 3 "even_fpr_operand" "h")
6913                                   (match_operand:DI 4 "even_fpr_operand" "h")
6914                                   (match_operand:SI 5 "const_int_operand" "n")]
6915                                  UNSPEC_MQMULH))
6916                (set (match_operand:V4QI 6 "accg_operand" "=B")
6917                     (unspec:V4QI [(const_int 0)] UNSPEC_MQMULH))]))]
6918   "TARGET_MEDIA"
6919   "*
6920 {
6921   switch (INTVAL (operands[5]))
6922   {
6923   default:                   break;
6924   case FRV_BUILTIN_MQMULHS:  return \"cmqmulhs %3, %4, %2, %1, %e0\";
6925   case FRV_BUILTIN_MQMULHU:  return \"cmqmulhu %3, %4, %2, %1, %e0\";
6926   }
6927
6928   fatal_insn (\"Bad media insn, cond_exec_mqmulh\", insn);
6929 }"
6930   [(set_attr "length" "4")
6931    (set_attr "type" "mqmulh")])
6932
6933 ;; Quad cross multiply (halfword): type "mqmulxh"
6934
6935 (define_expand "mqmulxhs"
6936   [(parallel [(set (match_operand:V4SI 0 "quad_acc_operand" "=A")
6937                    (unspec:V4SI [(match_operand:DI 1 "even_fpr_operand" "h")
6938                                  (match_operand:DI 2 "even_fpr_operand" "h")
6939                                  (match_dup 4)]
6940                                 UNSPEC_MQMULXH))
6941               (set (match_operand:V4QI 3 "accg_operand" "=B")
6942                    (unspec:V4QI [(const_int 0)] UNSPEC_MQMULXH))])]
6943   "TARGET_MEDIA"
6944   "operands[4] = GEN_INT (FRV_BUILTIN_MQMULXHS);")
6945
6946 (define_expand "mqmulxhu"
6947   [(parallel [(set (match_operand:V4SI 0 "quad_acc_operand" "=A")
6948                    (unspec:V4SI [(match_operand:DI 1 "even_fpr_operand" "h")
6949                                  (match_operand:DI 2 "even_fpr_operand" "h")
6950                                  (match_dup 4)]
6951                                 UNSPEC_MQMULXH))
6952               (set (match_operand:V4QI 3 "accg_operand" "=B")
6953                    (unspec:V4QI [(const_int 0)] UNSPEC_MQMULXH))])]
6954   "TARGET_MEDIA"
6955   "operands[4] = GEN_INT (FRV_BUILTIN_MQMULXHU);")
6956
6957 (define_insn "*mqmulxh"
6958   [(set (match_operand:V4SI 0 "quad_acc_operand" "=A")
6959         (unspec:V4SI [(match_operand:DI 1 "even_fpr_operand" "h")
6960                       (match_operand:DI 2 "even_fpr_operand" "h")
6961                       (match_operand:SI 3 "const_int_operand" "n")]
6962                      UNSPEC_MQMULXH))
6963    (set (match_operand:V4QI 4 "accg_operand" "=B")
6964         (unspec:V4QI [(const_int 0)] UNSPEC_MQMULXH))]
6965   "TARGET_MEDIA"
6966   "*
6967 {
6968   switch (INTVAL (operands[3]))
6969   {
6970   default:                   break;
6971   case FRV_BUILTIN_MQMULXHS: return \"mqmulxhs %1, %2, %0\";
6972   case FRV_BUILTIN_MQMULXHU: return \"mqmulxhu %1, %2, %0\";
6973   }
6974
6975   fatal_insn (\"Bad media insn, mqmulxh\", insn);
6976 }"
6977   [(set_attr "length" "4")
6978    (set_attr "type" "mqmulxh")])
6979
6980 ;; Quad product-sum (halfword): type "mqmach"
6981
6982 (define_expand "mqmachs"
6983   [(parallel [(set (match_operand:V4SI 0 "even_acc_operand" "+A")
6984                    (unspec:V4SI [(match_dup 0)
6985                                  (match_operand:DI 1 "even_fpr_operand" "h")
6986                                  (match_operand:DI 2 "even_fpr_operand" "h")
6987                                  (match_operand:V4QI 3 "accg_operand" "+B")
6988                                  (match_dup 4)]
6989                                 UNSPEC_MQMACH))
6990               (set (match_dup 3)
6991                    (unspec:V4QI [(const_int 0)] UNSPEC_MQMACH))])]
6992   "TARGET_MEDIA"
6993   "operands[4] = GEN_INT (FRV_BUILTIN_MQMACHS);")
6994
6995 (define_expand "mqmachu"
6996   [(parallel [(set (match_operand:V4SI 0 "even_acc_operand" "+A")
6997                    (unspec:V4SI [(match_dup 0)
6998                                  (match_operand:DI 1 "even_fpr_operand" "h")
6999                                  (match_operand:DI 2 "even_fpr_operand" "h")
7000                                  (match_operand:V4QI 3 "accg_operand" "+B")
7001                                  (match_dup 4)]
7002                                 UNSPEC_MQMACH))
7003               (set (match_dup 3)
7004                    (unspec:V4QI [(const_int 0)] UNSPEC_MQMACH))])]
7005   "TARGET_MEDIA"
7006   "operands[4] = GEN_INT (FRV_BUILTIN_MQMACHU);")
7007
7008 (define_insn "*mqmach"
7009   [(set (match_operand:V4SI 0 "even_acc_operand" "+A")
7010         (unspec:V4SI [(match_dup 0)
7011                       (match_operand:DI 1 "even_fpr_operand" "h")
7012                       (match_operand:DI 2 "even_fpr_operand" "h")
7013                       (match_operand:V4QI 3 "accg_operand" "+B")
7014                       (match_operand:SI 4 "const_int_operand" "n")]
7015                      UNSPEC_MQMACH))
7016    (set (match_dup 3)
7017         (unspec:V4QI [(const_int 0)] UNSPEC_MQMACH))]
7018   "TARGET_MEDIA"
7019   "*
7020 {
7021   switch (INTVAL (operands[4]))
7022   {
7023   default:                  break;
7024   case FRV_BUILTIN_MQMACHS: return \"mqmachs %1, %2, %0\";
7025   case FRV_BUILTIN_MQMACHU: return \"mqmachu %1, %2, %0\";
7026   }
7027
7028   fatal_insn (\"Bad media insn, mqmach\", insn);
7029 }"
7030   [(set_attr "length" "4")
7031    (set_attr "type" "mqmach")])
7032
7033 (define_insn "*cond_exec_mqmach"
7034   [(cond_exec
7035     (match_operator 0 "ccr_eqne_operator"
7036                     [(match_operand 1 "cr_operand" "C")
7037                      (const_int 0)])
7038     (parallel [(set (match_operand:V4SI 2 "even_acc_operand" "+A")
7039                     (unspec:V4SI [(match_dup 2)
7040                                   (match_operand:DI 3 "even_fpr_operand" "h")
7041                                   (match_operand:DI 4 "even_fpr_operand" "h")
7042                                   (match_operand:V4QI 5 "accg_operand" "+B")
7043                                   (match_operand:SI 6 "const_int_operand" "n")]
7044                                  UNSPEC_MQMACH))
7045                (set (match_dup 5)
7046                     (unspec:V4QI [(const_int 0)] UNSPEC_MQMACH))]))]
7047   "TARGET_MEDIA"
7048   "*
7049 {
7050   switch (INTVAL (operands[6]))
7051   {
7052   default:                  break;
7053   case FRV_BUILTIN_MQMACHS: return \"cmqmachs %3, %4, %2, %1, %e0\";
7054   case FRV_BUILTIN_MQMACHU: return \"cmqmachu %3, %4, %2, %1, %e0\";
7055   }
7056
7057   fatal_insn (\"Bad media insn, cond_exec_mqmach\", insn);
7058 }"
7059   [(set_attr "length" "4")
7060    (set_attr "type" "mqmach")])
7061
7062 ;; Dual complex number product-sum (halfword)
7063
7064 (define_expand "mcpxrs"
7065   [(parallel [(set (match_operand:SI 0 "acc_operand" "=a")
7066                    (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
7067                                (match_operand:SI 2 "fpr_operand" "f")
7068                                (match_dup 4)]
7069                               UNSPEC_MCPX))
7070               (set (match_operand:QI 3 "accg_operand" "=B")
7071                    (unspec:QI [(const_int 0)] UNSPEC_MCPX))])]
7072   "TARGET_MEDIA"
7073   "operands[4] = GEN_INT (FRV_BUILTIN_MCPXRS);")
7074
7075 (define_expand "mcpxru"
7076   [(parallel [(set (match_operand:SI 0 "acc_operand" "=a")
7077                    (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
7078                                (match_operand:SI 2 "fpr_operand" "f")
7079                                (match_dup 4)]
7080                               UNSPEC_MCPX))
7081               (set (match_operand:QI 3 "accg_operand" "=B")
7082                    (unspec:QI [(const_int 0)] UNSPEC_MCPX))])]
7083   "TARGET_MEDIA"
7084   "operands[4] = GEN_INT (FRV_BUILTIN_MCPXRU);")
7085
7086 (define_expand "mcpxis"
7087   [(parallel [(set (match_operand:SI 0 "acc_operand" "=a")
7088                    (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
7089                                (match_operand:SI 2 "fpr_operand" "f")
7090                                (match_dup 4)]
7091                               UNSPEC_MCPX))
7092               (set (match_operand:QI 3 "accg_operand" "=B")
7093                    (unspec:QI [(const_int 0)] UNSPEC_MCPX))])]
7094   "TARGET_MEDIA"
7095   "operands[4] = GEN_INT (FRV_BUILTIN_MCPXIS);")
7096
7097 (define_expand "mcpxiu"
7098   [(parallel [(set (match_operand:SI 0 "acc_operand" "=a")
7099                    (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
7100                                (match_operand:SI 2 "fpr_operand" "f")
7101                                (match_dup 4)]
7102                               UNSPEC_MCPX))
7103               (set (match_operand:QI 3 "accg_operand" "=B")
7104                    (unspec:QI [(const_int 0)] UNSPEC_MCPX))])]
7105   "TARGET_MEDIA"
7106   "operands[4] = GEN_INT (FRV_BUILTIN_MCPXIU);")
7107
7108 (define_insn "*mcpx"
7109   [(parallel [(set (match_operand:SI 0 "acc_operand" "=a")
7110                    (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
7111                                (match_operand:SI 2 "fpr_operand" "f")
7112                                (match_operand:SI 3 "const_int_operand" "n")]
7113                               UNSPEC_MCPX))
7114               (set (match_operand:QI 4 "accg_operand" "=B")
7115                    (unspec:QI [(const_int 0)] UNSPEC_MCPX))])]
7116   "TARGET_MEDIA"
7117   "*
7118 {
7119   switch (INTVAL (operands[3]))
7120   {
7121   default:                 break;
7122   case FRV_BUILTIN_MCPXRS: return \"mcpxrs %1, %2, %0\";
7123   case FRV_BUILTIN_MCPXRU: return \"mcpxru %1, %2, %0\";
7124   case FRV_BUILTIN_MCPXIS: return \"mcpxis %1, %2, %0\";
7125   case FRV_BUILTIN_MCPXIU: return \"mcpxiu %1, %2, %0\";
7126   }
7127
7128   fatal_insn (\"Bad media insn, mcpx\", insn);
7129 }"
7130   [(set_attr "length" "4")
7131    (set_attr "type" "mcpx")])
7132
7133 (define_insn "*cond_exec_mcpx"
7134   [(cond_exec
7135     (match_operator 0 "ccr_eqne_operator"
7136                     [(match_operand 1 "cr_operand" "C")
7137                      (const_int 0)])
7138     (parallel [(set (match_operand:SI 2 "acc_operand" "=a")
7139                     (unspec:SI [(match_operand:SI 3 "fpr_operand" "f")
7140                                 (match_operand:SI 4 "fpr_operand" "f")
7141                                 (match_operand:SI 5 "const_int_operand" "n")]
7142                                UNSPEC_MCPX))
7143                (set (match_operand:QI 6 "accg_operand" "=B")
7144                     (unspec:QI [(const_int 0)] UNSPEC_MCPX))]))]
7145   "TARGET_MEDIA"
7146   "*
7147 {
7148   switch (INTVAL (operands[5]))
7149   {
7150   default:                 break;
7151   case FRV_BUILTIN_MCPXRS: return \"cmcpxrs %3, %4, %2, %1, %e0\";
7152   case FRV_BUILTIN_MCPXRU: return \"cmcpxru %3, %4, %2, %1, %e0\";
7153   case FRV_BUILTIN_MCPXIS: return \"cmcpxis %3, %4, %2, %1, %e0\";
7154   case FRV_BUILTIN_MCPXIU: return \"cmcpxiu %3, %4, %2, %1, %e0\";
7155   }
7156
7157   fatal_insn (\"Bad media insn, cond_exec_mcpx\", insn);
7158 }"
7159   [(set_attr "length" "4")
7160    (set_attr "type" "mcpx")])
7161
7162 ;; Quad complex number product-sum (halfword): type "mqcpx"
7163
7164 (define_expand "mqcpxrs"
7165   [(parallel [(set (match_operand:DI 0 "even_acc_operand" "=b")
7166                    (unspec:DI [(match_operand:DI 1 "fpr_operand" "f")
7167                                (match_operand:DI 2 "fpr_operand" "f")
7168                                (match_dup 4)]
7169                               UNSPEC_MQCPX))
7170               (set (match_operand:HI 3 "accg_operand" "=B")
7171                    (unspec:HI [(const_int 0)] UNSPEC_MQCPX))])]
7172   "TARGET_MEDIA"
7173   "operands[4] = GEN_INT (FRV_BUILTIN_MQCPXRS);")
7174
7175 (define_expand "mqcpxru"
7176   [(parallel [(set (match_operand:DI 0 "even_acc_operand" "=b")
7177                    (unspec:DI [(match_operand:DI 1 "fpr_operand" "f")
7178                                (match_operand:DI 2 "fpr_operand" "f")
7179                                (match_dup 4)]
7180                               UNSPEC_MQCPX))
7181               (set (match_operand:HI 3 "accg_operand" "=B")
7182                    (unspec:HI [(const_int 0)] UNSPEC_MQCPX))])]
7183   "TARGET_MEDIA"
7184   "operands[4] = GEN_INT (FRV_BUILTIN_MQCPXRU);")
7185
7186 (define_expand "mqcpxis"
7187   [(parallel [(set (match_operand:DI 0 "even_acc_operand" "=b")
7188                    (unspec:DI [(match_operand:DI 1 "fpr_operand" "f")
7189                                (match_operand:DI 2 "fpr_operand" "f")
7190                                (match_dup 4)]
7191                               UNSPEC_MQCPX))
7192               (set (match_operand:HI 3 "accg_operand" "=B")
7193                    (unspec:HI [(const_int 0)] UNSPEC_MQCPX))])]
7194   "TARGET_MEDIA"
7195   "operands[4] = GEN_INT (FRV_BUILTIN_MQCPXIS);")
7196
7197 (define_expand "mqcpxiu"
7198   [(parallel [(set (match_operand:DI 0 "even_acc_operand" "=b")
7199                    (unspec:DI [(match_operand:DI 1 "fpr_operand" "f")
7200                                (match_operand:DI 2 "fpr_operand" "f")
7201                                (match_dup 4)]
7202                               UNSPEC_MQCPX))
7203               (set (match_operand:HI 3 "accg_operand" "=B")
7204                    (unspec:HI [(const_int 0)] UNSPEC_MQCPX))])]
7205   "TARGET_MEDIA"
7206   "operands[4] = GEN_INT (FRV_BUILTIN_MQCPXIU);")
7207
7208 (define_insn "*mqcpx"
7209   [(set (match_operand:DI 0 "even_acc_operand" "=b")
7210         (unspec:DI [(match_operand:DI 1 "fpr_operand" "f")
7211                     (match_operand:DI 2 "fpr_operand" "f")
7212                     (match_operand:SI 3 "const_int_operand" "n")]
7213                    UNSPEC_MQCPX))
7214    (set (match_operand:HI 4 "accg_operand" "=B")
7215         (unspec:HI [(const_int 0)] UNSPEC_MQCPX))]
7216   "TARGET_MEDIA"
7217   "*
7218 {
7219   switch (INTVAL (operands[3]))
7220   {
7221   default:                  break;
7222   case FRV_BUILTIN_MQCPXRS: return \"mqcpxrs %1, %2, %0\";
7223   case FRV_BUILTIN_MQCPXRU: return \"mqcpxru %1, %2, %0\";
7224   case FRV_BUILTIN_MQCPXIS: return \"mqcpxis %1, %2, %0\";
7225   case FRV_BUILTIN_MQCPXIU: return \"mqcpxiu %1, %2, %0\";
7226   }
7227
7228   fatal_insn (\"Bad media insn, mqcpx\", insn);
7229 }"
7230   [(set_attr "length" "4")
7231    (set_attr "type" "mqcpx")])
7232
7233 ;; Cut: type "mcut"
7234
7235 (define_expand "mcut"
7236   [(set (match_operand:SI 0 "fpr_operand" "=f")
7237         (unspec:SI [(match_operand:SI 1 "acc_operand" "a")
7238                     (match_operand:SI 2 "fpr_or_int6_operand" "fI")
7239                     (match_operand:QI 3 "accg_operand" "B")
7240                     (match_dup 4)]
7241                    UNSPEC_MCUT))]
7242   "TARGET_MEDIA"
7243   "operands[4] = GEN_INT (FRV_BUILTIN_MCUT);")
7244
7245 (define_expand "mcutss"
7246   [(set (match_operand:SI 0 "fpr_operand" "=f")
7247         (unspec:SI [(match_operand:SI 1 "acc_operand" "a")
7248                     (match_operand:SI 2 "fpr_or_int6_operand" "fI")
7249                     (match_operand:QI 3 "accg_operand" "B")
7250                     (match_dup 4)]
7251                    UNSPEC_MCUT))]
7252   "TARGET_MEDIA"
7253   "operands[4] = GEN_INT (FRV_BUILTIN_MCUTSS);")
7254
7255 (define_insn "*mcut"
7256   [(set (match_operand:SI 0 "fpr_operand" "=f")
7257         (unspec:SI [(match_operand:SI 1 "acc_operand" "a")
7258                     (match_operand:SI 2 "fpr_or_int6_operand" "fI")
7259                     (match_operand:QI 3 "accg_operand" "B")
7260                     (match_operand:SI 4 "const_int_operand" "n")]
7261                    UNSPEC_MCUT))]
7262   "TARGET_MEDIA"
7263   "*
7264 {
7265   switch (INTVAL (operands[4]))
7266   {
7267   default:                 break;
7268   case FRV_BUILTIN_MCUT:   return \"mcut%i2 %1, %2, %0\";
7269   case FRV_BUILTIN_MCUTSS: return \"mcutss%i2 %1, %2, %0\";
7270   }
7271
7272   fatal_insn (\"Bad media insn, mcut\", insn);
7273 }"
7274   [(set_attr "length" "4")
7275    (set_attr "type" "mcut")])
7276
7277 ;; Accumulator read: type "mrdacc"
7278
7279 (define_insn "mrdacc"
7280   [(set (match_operand:SI 0 "fpr_operand" "=f")
7281         (unspec:SI [(match_operand:SI 1 "acc_operand" "a")] UNSPEC_MRDACC))]
7282   "TARGET_MEDIA"
7283   "mrdacc %1, %0"
7284   [(set_attr "length" "4")
7285    (set_attr "type" "mrdacc")])
7286
7287 (define_insn "mrdaccg"
7288   [(set (match_operand:SI 0 "fpr_operand" "=f")
7289         (unspec:SI [(match_operand:QI 1 "accg_operand" "B")] UNSPEC_MRDACCG))]
7290   "TARGET_MEDIA"
7291   "mrdaccg %1, %0"
7292   [(set_attr "length" "4")
7293    (set_attr "type" "mrdacc")])
7294
7295 ;; Accumulator write: type "mwtacc"
7296
7297 (define_insn "mwtacc"
7298   [(set (match_operand:SI 0 "acc_operand" "=a")
7299         (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")] UNSPEC_MWTACC))]
7300   "TARGET_MEDIA"
7301   "mwtacc %1, %0"
7302   [(set_attr "length" "4")
7303    (set_attr "type" "mwtacc")])
7304
7305 (define_insn "mwtaccg"
7306   [(set (match_operand:QI 0 "accg_operand" "=B")
7307         (unspec:QI [(match_operand:SI 1 "fpr_operand" "f")] UNSPEC_MWTACCG))]
7308   "TARGET_MEDIA"
7309   "mwtaccg %1, %0"
7310   [(set_attr "length" "4")
7311    (set_attr "type" "mwtacc")])
7312
7313 ;; Trap: This one executes on the control unit, not the media units.
7314
7315 (define_insn "mtrap"
7316   [(unspec_volatile [(const_int 0)] UNSPEC_MTRAP)]
7317   "TARGET_MEDIA"
7318   "mtrap"
7319   [(set_attr "length" "4")
7320    (set_attr "type" "trap")])
7321
7322 ;; Clear single accumulator: type "mclracc"
7323
7324 (define_insn "mclracc_internal"
7325   [(set (match_operand:SI 0 "acc_operand" "=a")
7326         (unspec:SI [(const_int 0)] UNSPEC_MCLRACC))
7327    (set (match_operand:QI 1 "accg_operand" "=B")
7328         (unspec:QI [(const_int 0)] UNSPEC_MCLRACC))]
7329   "TARGET_MEDIA"
7330   "mclracc %0,#0"
7331   [(set_attr "length" "4")
7332    (set_attr "type" "mclracc")])
7333
7334 (define_expand "mclracc"
7335   [(parallel [(set (match_operand:SI 0 "acc_operand" "=a")
7336                    (unspec:SI [(const_int 0)] UNSPEC_MCLRACC))
7337               (set (match_dup 1)
7338                    (unspec:QI [(const_int 0)] UNSPEC_MCLRACC))])]
7339   "TARGET_MEDIA"
7340   "
7341 {
7342   if (GET_CODE (operands[0]) != REG || !ACC_P (REGNO (operands[0])))
7343     FAIL;
7344
7345   operands[1] = frv_matching_accg_for_acc (operands[0]);
7346 }")
7347
7348 ;; Clear all accumulators: type "mclracca"
7349
7350 (define_insn "mclracca8_internal"
7351   [(set (match_operand:V4SI 0 "quad_acc_operand" "=b")
7352         (unspec:V4SI [(const_int 0)] UNSPEC_MCLRACCA))
7353    (set (match_operand:V4SI 1 "quad_acc_operand" "=b")
7354         (unspec:V4SI [(const_int 0)] UNSPEC_MCLRACCA))
7355    (set (match_operand:V4QI 2 "accg_operand" "=B")
7356         (unspec:V4QI [(const_int 0)] UNSPEC_MCLRACCA))
7357    (set (match_operand:V4QI 3 "accg_operand" "=B")
7358         (unspec:V4QI [(const_int 0)] UNSPEC_MCLRACCA))]
7359   "TARGET_MEDIA && TARGET_ACC_8"
7360   "mclracc acc0,#1"
7361   [(set_attr "length" "4")
7362    (set_attr "type" "mclracca")])
7363
7364 (define_insn "mclracca4_internal"
7365   [(set (match_operand:V4SI 0 "quad_acc_operand" "=b")
7366         (unspec:V4SI [(const_int 0)] UNSPEC_MCLRACCA))
7367    (set (match_operand:V4QI 1 "accg_operand" "=B")
7368         (unspec:V4QI [(const_int 0)] UNSPEC_MCLRACCA))]
7369   "TARGET_MEDIA && TARGET_ACC_4"
7370   "mclracc acc0,#1"
7371   [(set_attr "length" "4")
7372    (set_attr "type" "mclracca")])
7373
7374 (define_expand "mclracca8"
7375   [(parallel [(set (match_dup 0) (unspec:V4SI [(const_int 0)] UNSPEC_MCLRACCA))
7376               (set (match_dup 1) (unspec:V4SI [(const_int 0)] UNSPEC_MCLRACCA))
7377               (set (match_dup 2) (unspec:V4QI [(const_int 0)] UNSPEC_MCLRACCA))
7378               (set (match_dup 3) (unspec:V4QI [(const_int 0)] UNSPEC_MCLRACCA))])]
7379   "TARGET_MEDIA && TARGET_ACC_8"
7380   "
7381 {
7382   operands[0] = gen_rtx_REG (V4SImode, ACC_FIRST);
7383   operands[1] = gen_rtx_REG (V4SImode, ACC_FIRST + (~3 & ACC_MASK));
7384   operands[2] = gen_rtx_REG (V4QImode, ACCG_FIRST);
7385   operands[3] = gen_rtx_REG (V4QImode, ACCG_FIRST + (~3 & ACC_MASK));
7386 }")
7387
7388 (define_expand "mclracca4"
7389   [(parallel [(set (match_dup 0) (unspec:V4SI [(const_int 0)] UNSPEC_MCLRACCA))
7390               (set (match_dup 1) (unspec:V4QI [(const_int 0)] UNSPEC_MCLRACCA))])]
7391   "TARGET_MEDIA && TARGET_ACC_4"
7392   "
7393 {
7394   operands[0] = gen_rtx_REG (V4SImode, ACC_FIRST);
7395   operands[1] = gen_rtx_REG (V4QImode, ACCG_FIRST);
7396 }")
7397
7398 (define_insn "mcop1"
7399   [(set (match_operand:SI 0 "fpr_operand" "=f")
7400         (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
7401                     (match_operand:SI 2 "fpr_operand" "f")] UNSPEC_MCOP1))]
7402   "TARGET_MEDIA_REV1"
7403   "mcop1 %1, %2, %0"
7404   [(set_attr "length" "4")
7405 ;; What is the class of the insn ???
7406    (set_attr "type" "multi")])
7407
7408 (define_insn "mcop2"
7409   [(set (match_operand:SI 0 "fpr_operand" "=f")
7410         (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
7411                     (match_operand:SI 2 "fpr_operand" "f")] UNSPEC_MCOP2))]
7412   "TARGET_MEDIA_REV1"
7413   "mcop2 %1, %2, %0"
7414   [(set_attr "length" "4")
7415 ;; What is the class of the insn ???
7416    (set_attr "type" "multi")])
7417
7418 (define_insn "*mdunpackh_internal"
7419   [(set (match_operand:V4SI 0 "quad_fpr_operand" "=x")
7420         (unspec:V4SI [(match_operand:DI 1 "even_fpr_operand" "h")]
7421                      UNSPEC_MDUNPACKH_INTERNAL))]
7422   "TARGET_MEDIA_REV1"
7423   "mdunpackh %1, %0"
7424   [(set_attr "length" "4")
7425    (set_attr "type" "mdunpackh")])
7426
7427 (define_insn_and_split "mdunpackh"
7428   [(set (match_operand:V4SI 0 "memory_operand" "=o")
7429         (unspec:V4SI [(match_operand:DI 1 "even_fpr_operand" "h")]
7430                      UNSPEC_MDUNPACKH))
7431    (clobber (match_scratch:V4SI 2 "=x"))]
7432   "TARGET_MEDIA_REV1"
7433   "#"
7434   "reload_completed"
7435   [(set (match_dup 2)
7436         (unspec:V4SI [(match_dup 1)] UNSPEC_MDUNPACKH_INTERNAL))
7437    (set (match_dup 3)
7438         (match_dup 4))
7439    (set (match_dup 5)
7440         (match_dup 6))]
7441   "
7442 {
7443   operands[3] = change_address (operands[0], DImode, NULL_RTX);
7444   operands[4] = gen_rtx_REG (DImode, REGNO (operands[2]));
7445   operands[5] = frv_index_memory (operands[0], DImode, 1);
7446   operands[6] = gen_rtx_REG (DImode, REGNO (operands[2])+2);
7447 }"
7448   [(set_attr "length" "20")
7449    (set_attr "type" "multi")])
7450
7451 (define_insn "*mbtohe_internal"
7452   [(set (match_operand:V4SI 0 "quad_fpr_operand" "=x")
7453         (unspec:V4SI [(match_operand:SI 1 "fpr_operand" "f")]
7454                      UNSPEC_MBTOHE_INTERNAL))]
7455   "TARGET_MEDIA_REV1"
7456   "mbtohe %1, %0"
7457   [(set_attr "length" "4")
7458    (set_attr "type" "mbhconve")])
7459
7460 (define_insn_and_split "mbtohe"
7461   [(set (match_operand:V4SI 0 "memory_operand" "=o")
7462         (unspec:V4SI [(match_operand:SI 1 "fpr_operand" "f")]
7463                      UNSPEC_MBTOHE))
7464    (clobber (match_scratch:V4SI 2 "=x"))]
7465   "TARGET_MEDIA_REV1"
7466   "#"
7467   "reload_completed"
7468   [(set (match_dup 2)
7469         (unspec:V4SI [(match_dup 1)] UNSPEC_MBTOHE_INTERNAL))
7470    (set (match_dup 3)
7471         (match_dup 4))
7472    (set (match_dup 5)
7473         (match_dup 6))]
7474   "
7475 {
7476   operands[3] = change_address (operands[0], DImode, NULL_RTX);
7477   operands[4] = gen_rtx_REG (DImode, REGNO (operands[2]));
7478   operands[5] = frv_index_memory (operands[0], DImode, 1);
7479   operands[6] = gen_rtx_REG (DImode, REGNO (operands[2])+2);
7480 }"
7481   [(set_attr "length" "20")
7482    (set_attr "type" "multi")])
7483
7484 ;; Quad product-sum (halfword) instructions only found on the FR400.
7485 ;; type "mqmach"
7486
7487 (define_expand "mqxmachs"
7488   [(parallel [(set (match_operand:V4SI 0 "quad_acc_operand" "")
7489                    (unspec:V4SI [(match_dup 0)
7490                                  (match_operand:DI 1 "even_fpr_operand" "")
7491                                  (match_operand:DI 2 "even_fpr_operand" "")
7492                                  (match_operand:V4QI 3 "accg_operand" "")
7493                                  (match_dup 4)]
7494                                 UNSPEC_MQMACH2))
7495                 (set (match_dup 3)
7496                      (unspec:V4QI [(const_int 0)] UNSPEC_MQMACH2))])]
7497   "TARGET_MEDIA_REV2"
7498   "operands[4] = GEN_INT (FRV_BUILTIN_MQXMACHS);")
7499
7500 (define_expand "mqxmacxhs"
7501   [(parallel [(set (match_operand:V4SI 0 "quad_acc_operand" "")
7502                    (unspec:V4SI [(match_dup 0)
7503                                  (match_operand:DI 1 "even_fpr_operand" "")
7504                                  (match_operand:DI 2 "even_fpr_operand" "")
7505                                  (match_operand:V4QI 3 "accg_operand" "")
7506                                  (match_dup 4)]
7507                                 UNSPEC_MQMACH2))
7508               (set (match_dup 3)
7509                    (unspec:V4QI [(const_int 0)] UNSPEC_MQMACH2))])]
7510   "TARGET_MEDIA_REV2"
7511   "operands[4] = GEN_INT (FRV_BUILTIN_MQXMACXHS);")
7512
7513 (define_expand "mqmacxhs"
7514   [(parallel [(set (match_operand:V4SI 0 "quad_acc_operand" "")
7515                    (unspec:V4SI [(match_dup 0)
7516                                  (match_operand:DI 1 "even_fpr_operand" "")
7517                                  (match_operand:DI 2 "even_fpr_operand" "")
7518                                  (match_operand:V4QI 3 "accg_operand" "")
7519                                  (match_dup 4)]
7520                                 UNSPEC_MQMACH2))
7521               (set (match_dup 3)
7522                    (unspec:V4QI [(const_int 0)] UNSPEC_MQMACH2))])]
7523   "TARGET_MEDIA_REV2"
7524   "operands[4] = GEN_INT (FRV_BUILTIN_MQMACXHS);")
7525
7526 (define_insn "*mqmach2"
7527   [(set (match_operand:V4SI 0 "quad_acc_operand" "+A")
7528         (unspec:V4SI [(match_dup 0)
7529                       (match_operand:DI 1 "even_fpr_operand" "h")
7530                       (match_operand:DI 2 "even_fpr_operand" "h")
7531                       (match_operand:V4QI 3 "accg_operand" "+B")
7532                       (match_operand:SI 4 "const_int_operand" "n")]
7533                      UNSPEC_MQMACH2))
7534    (set (match_dup 3)
7535         (unspec:V4QI [(const_int 0)] UNSPEC_MQMACH2))]
7536   "TARGET_MEDIA_REV2"
7537   "*
7538 {
7539   switch (INTVAL (operands[4]))
7540   {
7541   default:                    break;
7542   case FRV_BUILTIN_MQXMACHS:  return \"mqxmachs %1, %2, %0\";
7543   case FRV_BUILTIN_MQXMACXHS: return \"mqxmacxhs %1, %2, %0\";
7544   case FRV_BUILTIN_MQMACXHS:  return \"mqmacxhs %1, %2, %0\";
7545   }
7546
7547   fatal_insn (\"Bad media insn, mqmach2\", insn);
7548 }"
7549   [(set_attr "length" "4")
7550    (set_attr "type" "mqmach")])
7551
7552 ;; Accumulator addition/subtraction: type "maddacc"
7553
7554 (define_expand "maddaccs"
7555   [(parallel [(set (match_operand:SI 0 "acc_operand" "")
7556                    (unspec:SI [(match_operand:DI 1 "even_acc_operand" "")]
7557                               UNSPEC_MADDACC))
7558               (set (match_operand:QI 2 "accg_operand" "")
7559                    (unspec:QI [(match_operand:HI 3 "accg_operand" "")
7560                                (match_dup 4)]
7561                               UNSPEC_MADDACC))])]
7562   "TARGET_MEDIA_REV2"
7563   "operands[4] = GEN_INT (FRV_BUILTIN_MADDACCS);")
7564
7565 (define_expand "msubaccs"
7566   [(parallel [(set (match_operand:SI 0 "acc_operand" "")
7567                    (unspec:SI [(match_operand:DI 1 "even_acc_operand" "")]
7568                               UNSPEC_MADDACC))
7569               (set (match_operand:QI 2 "accg_operand" "")
7570                    (unspec:QI [(match_operand:HI 3 "accg_operand" "")
7571                                (match_dup 4)]
7572                               UNSPEC_MADDACC))])]
7573   "TARGET_MEDIA_REV2"
7574   "operands[4] = GEN_INT (FRV_BUILTIN_MSUBACCS);")
7575
7576 (define_insn "masaccs"
7577   [(set (match_operand:DI 0 "even_acc_operand" "=b")
7578         (unspec:DI [(match_operand:DI 1 "even_acc_operand" "b")]
7579                    UNSPEC_MASACCS))
7580    (set (match_operand:HI 2 "accg_operand" "=B")
7581         (unspec:HI [(match_operand:HI 3 "accg_operand" "B")]
7582                    UNSPEC_MASACCS))]
7583   "TARGET_MEDIA_REV2"
7584   "masaccs %1, %0"
7585   [(set_attr "length" "4")
7586    (set_attr "type" "maddacc")])
7587
7588 (define_insn "*maddacc"
7589   [(set (match_operand:SI 0 "acc_operand" "=a")
7590         (unspec:SI [(match_operand:DI 1 "even_acc_operand" "b")]
7591                    UNSPEC_MADDACC))
7592    (set (match_operand:QI 2 "accg_operand" "=B")
7593         (unspec:QI [(match_operand:HI 3 "accg_operand" "B")
7594                     (match_operand:SI 4 "const_int_operand" "n")]
7595                    UNSPEC_MADDACC))]
7596   "TARGET_MEDIA_REV2"
7597   "*
7598 {
7599   switch (INTVAL (operands[4]))
7600   {
7601   default:                   break;
7602   case FRV_BUILTIN_MADDACCS: return \"maddaccs %1, %0\";
7603   case FRV_BUILTIN_MSUBACCS: return \"msubaccs %1, %0\";
7604   }
7605
7606   fatal_insn (\"Bad media insn, maddacc\", insn);
7607 }"
7608   [(set_attr "length" "4")
7609    (set_attr "type" "maddacc")])
7610
7611 ;; Dual accumulator addition/subtraction: type "mdaddacc"
7612
7613 (define_expand "mdaddaccs"
7614   [(parallel [(set (match_operand:DI 0 "even_acc_operand" "")
7615                    (unspec:DI [(match_operand:V4SI 1 "quad_acc_operand" "")]
7616                               UNSPEC_MDADDACC))
7617               (set (match_operand:HI 2 "accg_operand" "")
7618                    (unspec:HI [(match_operand:V4QI 3 "accg_operand" "")
7619                                (match_dup 4)]
7620                               UNSPEC_MDADDACC))])]
7621   "TARGET_MEDIA_REV2"
7622   "operands[4] = GEN_INT (FRV_BUILTIN_MDADDACCS);")
7623
7624 (define_expand "mdsubaccs"
7625   [(parallel [(set (match_operand:DI 0 "even_acc_operand" "")
7626                    (unspec:DI [(match_operand:V4SI 1 "quad_acc_operand" "")]
7627                               UNSPEC_MDADDACC))
7628               (set (match_operand:HI 2 "accg_operand" "")
7629                    (unspec:HI [(match_operand:V4QI 3 "accg_operand" "")
7630                                (match_dup 4)]
7631                               UNSPEC_MDADDACC))])]
7632   "TARGET_MEDIA_REV2"
7633   "operands[4] = GEN_INT (FRV_BUILTIN_MDSUBACCS);")
7634
7635 (define_insn "mdasaccs"
7636   [(set (match_operand:V4SI 0 "quad_acc_operand" "=A")
7637         (unspec:V4SI [(match_operand:V4SI 1 "quad_acc_operand" "A")]
7638                      UNSPEC_MDASACCS))
7639    (set (match_operand:V4QI 2 "accg_operand" "=B")
7640         (unspec:V4QI [(match_operand:V4QI 3 "accg_operand" "B")]
7641                      UNSPEC_MDASACCS))]
7642   "TARGET_MEDIA_REV2"
7643   "mdasaccs %1, %0"
7644   [(set_attr "length" "4")
7645    (set_attr "type" "mdaddacc")])
7646
7647 (define_insn "*mdaddacc"
7648   [(set (match_operand:DI 0 "even_acc_operand" "=b")
7649         (unspec:DI [(match_operand:V4SI 1 "quad_acc_operand" "A")]
7650                    UNSPEC_MDADDACC))
7651    (set (match_operand:HI 2 "accg_operand" "=B")
7652         (unspec:HI [(match_operand:V4QI 3 "accg_operand" "B")
7653                     (match_operand:SI 4 "const_int_operand" "n")]
7654                    UNSPEC_MDADDACC))]
7655   "TARGET_MEDIA_REV2"
7656   "*
7657 {
7658   switch (INTVAL (operands[4]))
7659   {
7660   default:                    break;
7661   case FRV_BUILTIN_MDADDACCS: return \"mdaddaccs %1, %0\";
7662   case FRV_BUILTIN_MDSUBACCS: return \"mdsubaccs %1, %0\";
7663   }
7664
7665   fatal_insn (\"Bad media insn, mdaddacc\", insn);
7666 }"
7667   [(set_attr "length" "4")
7668    (set_attr "type" "mdaddacc")])
7669
7670 ;; Dual absolute (halfword): type "mabsh"
7671
7672 (define_insn "mabshs"
7673   [(set (match_operand:SI 0 "fpr_operand" "=f")
7674         (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")] UNSPEC_MABSHS))]
7675   "TARGET_MEDIA_REV2"
7676   "mabshs %1, %0"
7677   [(set_attr "length" "4")
7678    (set_attr "type" "mabsh")])
7679
7680 ;; Dual rotate: type "mdrot"
7681
7682 (define_insn "mdrotli"
7683   [(set (match_operand:DI 0 "even_fpr_operand" "=h")
7684         (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
7685                     (match_operand:SI 2 "uint5_operand" "I")]
7686                    UNSPEC_MDROTLI))]
7687   "TARGET_MEDIA_REV2"
7688   "mdrotli %1, %2, %0"
7689   [(set_attr "length" "4")
7690    (set_attr "type" "mdrot")])
7691
7692 ;; Dual coupling (concatenation): type "mcpl"
7693
7694 (define_insn "mcplhi"
7695   [(set (match_operand:SI 0 "fpr_operand" "=f")
7696         (unspec:SI [(match_operand:DI 1 "fpr_operand" "h")
7697                     (match_operand:SI 2 "uint4_operand" "I")]
7698                    UNSPEC_MCPLHI))]
7699   "TARGET_MEDIA_REV2"
7700   "mcplhi %1, %2, %0"
7701   [(set_attr "length" "4")
7702    (set_attr "type" "mcpl")])
7703
7704 (define_insn "mcpli"
7705   [(set (match_operand:SI 0 "fpr_operand" "=f")
7706         (unspec:SI [(match_operand:DI 1 "fpr_operand" "h")
7707                     (match_operand:SI 2 "uint5_operand" "I")]
7708                    UNSPEC_MCPLI))]
7709   "TARGET_MEDIA_REV2"
7710   "mcpli %1, %2, %0"
7711   [(set_attr "length" "4")
7712    (set_attr "type" "mcpl")])
7713
7714 ;; Dual cut: type "mdcut"
7715
7716 (define_insn "mdcutssi"
7717   [(set (match_operand:DI 0 "even_fpr_operand" "=h")
7718         (unspec:DI [(match_operand:DI 1 "even_acc_operand" "b")
7719                     (match_operand:SI 2 "int6_operand" "I")
7720                     (match_operand:HI 3 "accg_operand" "B")]
7721                    UNSPEC_MDCUTSSI))]
7722   "TARGET_MEDIA_REV2"
7723   "mdcutssi %1, %2, %0"
7724   [(set_attr "length" "4")
7725    (set_attr "type" "mdcut")])
7726
7727 ;; Quad saturate (halfword): type "mqsath"
7728
7729 (define_insn "mqsaths"
7730   [(set (match_operand:DI 0 "even_fpr_operand" "=h")
7731         (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
7732                     (match_operand:DI 2 "even_fpr_operand" "h")]
7733                    UNSPEC_MQSATHS))]
7734   "TARGET_MEDIA_REV2"
7735   "mqsaths %1, %2, %0"
7736   [(set_attr "length" "4")
7737    (set_attr "type" "mqsath")])
7738
7739 ;; Quad limit instructions: type "mqlimh"
7740
7741 (define_insn "mqlclrhs"
7742   [(set (match_operand:DI 0 "even_fpr_operand" "=h")
7743         (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
7744                     (match_operand:DI 2 "even_fpr_operand" "h")]
7745                    UNSPEC_MQLCLRHS))]
7746   "TARGET_MEDIA_FR450"
7747   "mqlclrhs %1, %2, %0"
7748   [(set_attr "length" "4")
7749    (set_attr "type" "mqlimh")])
7750
7751 (define_insn "mqlmths"
7752   [(set (match_operand:DI 0 "even_fpr_operand" "=h")
7753         (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
7754                     (match_operand:DI 2 "even_fpr_operand" "h")]
7755                    UNSPEC_MQLMTHS))]
7756   "TARGET_MEDIA_FR450"
7757   "mqlmths %1, %2, %0"
7758   [(set_attr "length" "4")
7759    (set_attr "type" "mqlimh")])
7760
7761 (define_insn "mqsllhi"
7762   [(set (match_operand:DI 0 "even_fpr_operand" "=h")
7763         (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
7764                     (match_operand:SI 2 "int6_operand" "I")]
7765                    UNSPEC_MQSLLHI))]
7766   "TARGET_MEDIA_FR450"
7767   "mqsllhi %1, %2, %0"
7768   [(set_attr "length" "4")
7769    (set_attr "type" "mqshift")])
7770
7771 (define_insn "mqsrahi"
7772   [(set (match_operand:DI 0 "even_fpr_operand" "=h")
7773         (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
7774                     (match_operand:SI 2 "int6_operand" "I")]
7775                    UNSPEC_MQSRAHI))]
7776   "TARGET_MEDIA_FR450"
7777   "mqsrahi %1, %2, %0"
7778   [(set_attr "length" "4")
7779    (set_attr "type" "mqshift")])
7780
7781 ;; Set hi/lo instructions: type "mset"
7782
7783 (define_insn "mhsetlos"
7784   [(set (match_operand:SI 0 "fpr_operand" "=f")
7785         (unspec:SI [(match_operand:SI 1 "fpr_operand" "0")
7786                     (match_operand:SI 2 "int12_operand" "NOP")]
7787                    UNSPEC_MHSETLOS))]
7788   "TARGET_MEDIA_REV2"
7789   "mhsetlos %2, %0"
7790   [(set_attr "length" "4")
7791    (set_attr "type" "mset")])
7792
7793 (define_insn "mhsetloh"
7794   [(set (match_operand:SI 0 "fpr_operand" "=f")
7795         (unspec:SI [(match_operand:SI 1 "fpr_operand" "0")
7796                     (match_operand:SI 2 "int5_operand" "I")]
7797                    UNSPEC_MHSETLOH))]
7798   "TARGET_MEDIA_REV2"
7799   "mhsetloh %2, %0"
7800   [(set_attr "length" "4")
7801    (set_attr "type" "mset")])
7802
7803 (define_insn "mhsethis"
7804   [(set (match_operand:SI 0 "fpr_operand" "=f")
7805         (unspec:SI [(match_operand:SI 1 "fpr_operand" "0")
7806                     (match_operand:SI 2 "int12_operand" "NOP")]
7807                    UNSPEC_MHSETHIS))]
7808   "TARGET_MEDIA_REV2"
7809   "mhsethis %2, %0"
7810   [(set_attr "length" "4")
7811    (set_attr "type" "mset")])
7812
7813 (define_insn "mhsethih"
7814   [(set (match_operand:SI 0 "fpr_operand" "=f")
7815         (unspec:SI [(match_operand:SI 1 "fpr_operand" "0")
7816                     (match_operand:SI 2 "int5_operand" "I")]
7817                    UNSPEC_MHSETHIH))]
7818   "TARGET_MEDIA_REV2"
7819   "mhsethih %2, %0"
7820   [(set_attr "length" "4")
7821    (set_attr "type" "mset")])
7822
7823 (define_insn "mhdsets"
7824   [(set (match_operand:SI 0 "fpr_operand" "=f")
7825         (unspec:SI [(match_operand:SI 1 "int12_operand" "NOP")]
7826                    UNSPEC_MHDSETS))]
7827   "TARGET_MEDIA_REV2"
7828   "mhdsets %1, %0"
7829   [(set_attr "length" "4")
7830    (set_attr "type" "mset")])
7831
7832 (define_insn "mhdseth"
7833   [(set (match_operand:SI 0 "fpr_operand" "=f")
7834         (unspec:SI [(match_operand:SI 1 "fpr_operand" "0")
7835                     (match_operand:SI 2 "int5_operand" "I")]
7836                    UNSPEC_MHDSETH))]
7837   "TARGET_MEDIA_REV2"
7838   "mhdseth %2, %0"
7839   [(set_attr "length" "4")
7840    (set_attr "type" "mset")])
7841
7842 ;;-----------------------------------------------------------------------------
7843
7844 (define_expand "symGOT2reg"
7845   [(match_operand:SI 0 "" "")
7846    (match_operand:SI 1 "" "")
7847    (match_operand:SI 2 "" "")
7848    (match_operand:SI 3 "" "")]
7849   ""
7850   "
7851 {
7852   rtx insn;
7853
7854   insn = emit_insn (gen_symGOT2reg_i (operands[0], operands[1], operands[2], operands[3]));
7855
7856   MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
7857
7858   set_unique_reg_note (insn, REG_EQUAL, operands[1]);
7859
7860   DONE;
7861 }")
7862
7863 (define_expand "symGOT2reg_i"
7864   [(set (match_operand:SI 0 "" "")
7865         (mem:SI (plus:SI (match_operand:SI 2 "" "")
7866                          (const:SI (unspec:SI [(match_operand:SI 1 "" "")
7867                                                (match_operand:SI 3 "" "")]
7868                                               UNSPEC_GOT)))))]
7869   ""
7870   "")
7871
7872 (define_expand "symGOT2reg_hilo"
7873   [(set (match_dup 6)
7874         (high:SI (const:SI (unspec:SI [(match_operand:SI 1 "" "")
7875                                        (match_dup 4)] UNSPEC_GOT))))
7876    (set (match_dup 5)
7877         (lo_sum:SI (match_dup 6)
7878                    (const:SI (unspec:SI [(match_dup 1)
7879                                          (match_operand:SI 3 "" "")]
7880                                         UNSPEC_GOT))))
7881    (set (match_operand:SI 0 "" "")
7882         (mem:SI (plus:SI (match_dup 5)
7883                          (match_operand:SI 2 "" ""))))
7884    ]
7885   ""
7886   "
7887 {
7888   if (!can_create_pseudo_p ())
7889     operands[6] = operands[5] = operands[0];
7890   else
7891     {
7892       operands[6] = gen_reg_rtx (SImode);
7893       operands[5] = gen_reg_rtx (SImode);
7894     }
7895
7896   operands[4] = GEN_INT (INTVAL (operands[3]) + 1);
7897   operands[3] = GEN_INT (INTVAL (operands[3]) + 2);
7898 }")
7899
7900 (define_expand "symGOTOFF2reg_hilo"
7901   [(set (match_dup 6)
7902         (high:SI (const:SI (unspec:SI [(match_operand:SI 1 "" "")
7903                                        (match_dup 4)] UNSPEC_GOT))))
7904    (set (match_dup 5)
7905         (lo_sum:SI (match_dup 6)
7906                    (const:SI (unspec:SI [(match_dup 1)
7907                                          (match_operand:SI 3 "" "")]
7908                                         UNSPEC_GOT))))
7909    (set (match_operand:SI 0 "" "")
7910         (plus:SI (match_dup 5)
7911                  (match_operand:SI 2 "" "")))
7912    ]
7913   ""
7914   "
7915 {
7916   if (!can_create_pseudo_p ())
7917     operands[6] = operands[5] = operands[0];
7918   else
7919     {
7920       operands[6] = gen_reg_rtx (SImode);
7921       operands[5] = gen_reg_rtx (SImode);
7922     }
7923
7924   operands[4] = GEN_INT (INTVAL (operands[3]) + 1);
7925   operands[3] = GEN_INT (INTVAL (operands[3]) + 2);
7926 }")
7927
7928 (define_expand "symGOTOFF2reg"
7929   [(match_operand:SI 0 "" "")
7930    (match_operand:SI 1 "" "")
7931    (match_operand:SI 2 "" "")
7932    (match_operand:SI 3 "" "")]
7933   ""
7934   "
7935 {
7936   rtx insn = emit_insn (gen_symGOTOFF2reg_i (operands[0], operands[1], operands[2], operands[3]));
7937
7938   set_unique_reg_note (insn, REG_EQUAL, operands[1]);
7939
7940   DONE;
7941 }")
7942
7943 (define_expand "symGOTOFF2reg_i"
7944   [(set (match_operand:SI 0 "" "")
7945         (plus:SI (match_operand:SI 2 "" "")
7946                  (const:SI
7947                   (unspec:SI [(match_operand:SI 1 "" "")
7948                              (match_operand:SI 3 "" "")]
7949                              UNSPEC_GOT))))]
7950   ""
7951   "")
7952
7953 (define_expand "symGPREL2reg"
7954   [(match_operand:SI 0 "" "")
7955    (match_operand:SI 1 "" "")
7956    (match_operand:SI 2 "" "")
7957    (match_operand:SI 3 "" "")
7958    (match_dup 4)]
7959   ""
7960   "
7961 {
7962   rtx insn;
7963
7964   if (!can_create_pseudo_p ())
7965     operands[4] = operands[0];
7966   else
7967     operands[4] = gen_reg_rtx (SImode);
7968
7969   emit_insn (frv_gen_GPsym2reg (operands[4], operands[2]));
7970
7971   insn = emit_insn (gen_symGOTOFF2reg_i (operands[0], operands[1],
7972                                          operands[4], operands[3]));
7973
7974   set_unique_reg_note (insn, REG_EQUAL, operands[1]);
7975
7976   DONE;
7977 }")
7978
7979 (define_expand "symGPREL2reg_hilo"
7980   [(match_operand:SI 0 "" "")
7981    (match_operand:SI 1 "" "")
7982    (match_operand:SI 2 "" "")
7983    (match_operand:SI 3 "" "")
7984    (match_dup 4)]
7985   ""
7986   "
7987 {
7988   rtx insn;
7989
7990   if (!can_create_pseudo_p ())
7991     {
7992       emit_insn (gen_symGOT2reg (operands[0], operands[1], operands[2],
7993                                  GEN_INT (R_FRV_GOT12)));
7994       DONE;
7995     }
7996
7997   operands[4] = gen_reg_rtx (SImode);
7998
7999   emit_insn (frv_gen_GPsym2reg (operands[4], operands[2]));
8000
8001   insn = emit_insn (gen_symGOTOFF2reg_hilo (operands[0], operands[1],
8002                                             operands[4], operands[3]));
8003
8004   set_unique_reg_note (insn, REG_EQUAL, operands[1]);
8005
8006   DONE;
8007 }")
8008 \f
8009 (define_constants
8010   [
8011    (UNSPEC_SMUL                 154)
8012    (UNSPEC_UMUL                 155)
8013    (UNSPEC_SMU                  156)
8014    (UNSPEC_ADDSS                157)
8015    (UNSPEC_SUBSS                158)
8016    (UNSPEC_SLASS                159)
8017    (UNSPEC_SCAN                 160)
8018    (UNSPEC_INTSS                161)
8019    (UNSPEC_SCUTSS               162)
8020    (UNSPEC_PREFETCH0            163)
8021    (UNSPEC_PREFETCH             164)
8022    (UNSPEC_IACCreadll           165)
8023    (UNSPEC_IACCreadl            166)
8024    (UNSPEC_IACCsetll            167)
8025    (UNSPEC_IACCsetl             168)
8026    (UNSPEC_SMASS                169)
8027    (UNSPEC_SMSSS                170)
8028    (UNSPEC_IMUL                 171)
8029
8030    (IACC0_REG                   171)
8031 ])
8032
8033 (define_insn "smul"
8034   [(set (match_operand:DI 0 "integer_register_operand" "=d")
8035         (unspec:DI [(match_operand:SI 1 "integer_register_operand" "d")
8036                     (match_operand:SI 2 "integer_register_operand" "d")]
8037                    UNSPEC_SMUL))]
8038   ""
8039   "smul %1, %2, %0"
8040   [(set_attr "length" "4")
8041    (set_attr "type" "mul")])
8042
8043 (define_insn "umul"
8044   [(set (match_operand:DI 0 "integer_register_operand" "=d")
8045         (unspec:DI [(match_operand:SI 1 "integer_register_operand" "d")
8046                     (match_operand:SI 2 "integer_register_operand" "d")]
8047                    UNSPEC_UMUL))]
8048   ""
8049   "umul %1, %2, %0"
8050   [(set_attr "length" "4")
8051    (set_attr "type" "mul")])
8052
8053 (define_insn "smass"
8054   [(set (reg:DI IACC0_REG)
8055         (unspec:DI [(match_operand:SI 0 "integer_register_operand" "d")
8056                     (match_operand:SI 1 "integer_register_operand" "d")
8057                     (reg:DI IACC0_REG)]
8058                    UNSPEC_SMASS))]
8059   "TARGET_FR405_BUILTINS"
8060   "smass %1, %0"
8061   [(set_attr "length" "4")
8062    (set_attr "type" "macc")])
8063
8064 (define_insn "smsss"
8065   [(set (reg:DI IACC0_REG)
8066         (unspec:DI [(match_operand:SI 0 "integer_register_operand" "d")
8067                     (match_operand:SI 1 "integer_register_operand" "d")
8068                     (reg:DI IACC0_REG)]
8069                    UNSPEC_SMSSS))]
8070   "TARGET_FR405_BUILTINS"
8071   "smsss %1, %0"
8072   [(set_attr "length" "4")
8073    (set_attr "type" "macc")])
8074
8075 (define_insn "smu"
8076   [(set (reg:DI IACC0_REG)
8077         (unspec:DI [(match_operand:SI 0 "integer_register_operand" "d")
8078                     (match_operand:SI 1 "integer_register_operand" "d")]
8079                    UNSPEC_SMU))]
8080   "TARGET_FR405_BUILTINS"
8081   "smu %1, %0"
8082   [(set_attr "length" "4")
8083    (set_attr "type" "macc")])
8084
8085 (define_insn "addss"
8086   [(set (match_operand:SI 0 "integer_register_operand" "=d")
8087         (unspec:SI [(match_operand:SI 1 "integer_register_operand" "d")
8088                     (match_operand:SI 2 "integer_register_operand" "d")]
8089                    UNSPEC_ADDSS))]
8090   "TARGET_FR405_BUILTINS"
8091   "addss %1, %2, %0"
8092   [(set_attr "length" "4")
8093    (set_attr "type" "int")])
8094
8095 (define_insn "subss"
8096   [(set (match_operand:SI 0 "integer_register_operand" "=d")
8097         (unspec:SI [(match_operand:SI 1 "integer_register_operand" "d")
8098                     (match_operand:SI 2 "integer_register_operand" "d")]
8099                    UNSPEC_SUBSS))]
8100   "TARGET_FR405_BUILTINS"
8101   "subss %1, %2, %0"
8102   [(set_attr "length" "4")
8103    (set_attr "type" "int")])
8104
8105 (define_insn "slass"
8106   [(set (match_operand:SI 0 "integer_register_operand" "=d")
8107         (unspec:SI [(match_operand:SI 1 "integer_register_operand" "d")
8108                     (match_operand:SI 2 "integer_register_operand" "d")]
8109                    UNSPEC_SLASS))]
8110   "TARGET_FR405_BUILTINS"
8111   "slass %1, %2, %0"
8112   [(set_attr "length" "4")
8113    (set_attr "type" "int")])
8114
8115 (define_insn "scan"
8116   [(set (match_operand:SI 0 "integer_register_operand" "=d")
8117         (unspec:SI [(match_operand:SI 1 "integer_register_operand" "d")
8118                     (match_operand:SI 2 "integer_register_operand" "d")]
8119                    UNSPEC_SCAN))]
8120   ""
8121   "scan %1, %2, %0"
8122   [(set_attr "length" "4")
8123    (set_attr "type" "scan")])
8124
8125 (define_insn "scutss"
8126   [(set (match_operand:SI 0 "integer_register_operand" "=d")
8127         (unspec:SI [(match_operand:SI 1 "integer_register_operand" "d")
8128                     (reg:DI IACC0_REG)]
8129                    UNSPEC_SCUTSS))]
8130   "TARGET_FR405_BUILTINS"
8131   "scutss %1,%0"
8132   [(set_attr "length" "4")
8133    (set_attr "type" "cut")])
8134
8135 (define_insn "frv_prefetch0"
8136   [(prefetch (unspec:SI [(match_operand:SI 0 "register_operand" "r")]
8137                         UNSPEC_PREFETCH0)
8138              (const_int 0)
8139              (const_int 0))]
8140   ""
8141   "dcpl %0, gr0, #0"
8142   [(set_attr "length" "4")])
8143
8144 (define_insn "frv_prefetch"
8145   [(prefetch (unspec:SI [(match_operand:SI 0 "register_operand" "r")]
8146                         UNSPEC_PREFETCH)
8147              (const_int 0)
8148              (const_int 0))]
8149   "TARGET_FR500_FR550_BUILTINS"
8150   "nop.p\\n\\tnldub @(%0, gr0), gr0"
8151   [(set_attr "length" "8")])
8152
8153 ;; TLS patterns
8154
8155 (define_insn "call_gettlsoff"
8156   [(set (match_operand:SI 0 "register_operand" "=D09")
8157         (unspec:SI
8158          [(match_operand:SI 1 "symbolic_operand" "")]
8159          UNSPEC_GETTLSOFF))
8160    (clobber (reg:SI GR8_REG))
8161    (clobber (reg:SI LRREG))
8162    (use (match_operand:SI 2 "register_operand" "D15"))]
8163   "HAVE_AS_TLS"
8164   "call #gettlsoff(%a1)"
8165   [(set_attr "length" "4")
8166    (set_attr "type" "load_or_call")])
8167
8168 ;; We have to expand this like a libcall (it sort of actually is)
8169 ;; because otherwise sched may move, for example, an insn that sets up
8170 ;; GR8 for a subsequence call before the *tls_indirect_call insn, and
8171 ;; then reload won't be able to fix things up.
8172 (define_expand "tls_indirect_call"
8173   [(set (reg:DI GR8_REG)
8174         (match_operand:DI 2 "register_operand" ""))
8175    (parallel
8176     [(set (reg:SI GR9_REG)
8177           (unspec:SI
8178            [(match_operand:SI 1 "symbolic_operand" "")
8179            (reg:DI GR8_REG)]
8180            UNSPEC_TLS_INDIRECT_CALL))
8181     (clobber (reg:SI GR8_REG))
8182     (clobber (reg:SI LRREG))
8183     (use (match_operand:SI 3 "register_operand" ""))])
8184    (set (match_operand:SI 0 "register_operand" "")
8185         (reg:SI GR9_REG))]
8186   "HAVE_AS_TLS")
8187
8188 (define_insn "*tls_indirect_call"
8189   [(set (reg:SI GR9_REG)
8190         (unspec:SI
8191          [(match_operand:SI 0 "symbolic_operand" "")
8192           (reg:DI GR8_REG)]
8193          UNSPEC_TLS_INDIRECT_CALL))
8194    (clobber (reg:SI GR8_REG))
8195    (clobber (reg:SI LRREG))
8196    ;; If there was a way to represent the fact that we don't need GR9
8197    ;; or GR15 to be set before this instruction (it could be in
8198    ;; parallel), we could use it here.  This change wouldn't apply to
8199    ;; call_gettlsoff, thought, since the linker may turn the latter
8200    ;; into ldi @(gr15,offset),gr9.
8201    (use (match_operand:SI 1 "register_operand" "D15"))]
8202   "HAVE_AS_TLS"
8203   "calll #gettlsoff(%a0)@(gr8,gr0)"
8204   [(set_attr "length" "4")
8205    (set_attr "type" "jumpl")])
8206
8207 (define_insn "tls_load_gottlsoff12"
8208   [(set (match_operand:SI 0 "register_operand" "=r")
8209         (unspec:SI
8210          [(match_operand:SI 1 "symbolic_operand" "")
8211           (match_operand:SI 2 "register_operand" "r")]
8212          UNSPEC_TLS_LOAD_GOTTLSOFF12))]
8213   "HAVE_AS_TLS"
8214   "ldi @(%2, #gottlsoff12(%1)), %0"
8215   [(set_attr "length" "4")])
8216
8217 (define_expand "tlsoff_hilo"
8218   [(set (match_operand:SI 0 "register_operand" "=r")
8219         (high:SI (const:SI (unspec:SI
8220                             [(match_operand:SI 1 "symbolic_operand" "")
8221                              (match_operand:SI 2 "immediate_operand" "n")]
8222                             UNSPEC_GOT))))
8223    (set (match_dup 0)
8224         (lo_sum:SI (match_dup 0)
8225                    (const:SI (unspec:SI [(match_dup 1)
8226                                          (match_dup 3)] UNSPEC_GOT))))]
8227   ""
8228   "
8229 {
8230   operands[3] = GEN_INT (INTVAL (operands[2]) + 1);
8231 }")
8232
8233 ;; Just like movdi_ldd, but with relaxation annotations.
8234 (define_insn "tls_tlsdesc_ldd"
8235   [(set (match_operand:DI 0 "register_operand" "=r")
8236         (unspec:DI [(mem:DI (unspec:SI
8237                              [(match_operand:SI 1 "register_operand" "r")
8238                               (match_operand:SI 2 "register_operand" "r")
8239                               (match_operand:SI 3 "symbolic_operand" "")]
8240                              UNSPEC_TLS_TLSDESC_LDD_AUX))]
8241                    UNSPEC_TLS_TLSDESC_LDD))]
8242   ""
8243   "ldd #tlsdesc(%a3)@(%1,%2), %0"
8244   [(set_attr "length" "4")
8245    (set_attr "type" "gload")])
8246
8247 (define_insn "tls_tlsoff_ld"
8248   [(set (match_operand:SI 0 "register_operand" "=r")
8249         (mem:SI (unspec:SI
8250                  [(match_operand:SI 1 "register_operand" "r")
8251                   (match_operand:SI 2 "register_operand" "r")
8252                   (match_operand:SI 3 "symbolic_operand" "")]
8253                  UNSPEC_TLS_TLSOFF_LD)))]
8254   ""
8255   "ld #tlsoff(%a3)@(%1,%2), %0"
8256   [(set_attr "length" "4")
8257    (set_attr "type" "gload")])
8258
8259 (define_insn "tls_lddi"
8260   [(set (match_operand:DI 0 "register_operand" "=r")
8261         (unspec:DI [(match_operand:SI 1 "symbolic_operand" "")
8262                     (match_operand:SI 2 "register_operand" "d")]
8263                    UNSPEC_TLS_LDDI))]
8264   ""
8265   "lddi @(%2, #gottlsdesc12(%a1)), %0"
8266   [(set_attr "length" "4")
8267    (set_attr "type" "gload")])