OSDN Git Service

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