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