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