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