]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/frv/frv.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / frv / frv.md
1 ;; Frv Machine Description
2 ;; Copyright (C) 1999-2016 Free Software Foundation, Inc.
3 ;; Contributed by Red Hat, Inc.
4
5 ;; This file is part of GCC.
6
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.
11
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.
16
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/>.
20
21 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
22
23 \f
24 ;; ::::::::::::::::::::
25 ;; ::
26 ;; :: Unspec's used
27 ;; ::
28 ;; ::::::::::::::::::::
29
30 ;; GOT constants must go 12/HI/LO for the splitter to work
31
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)
43
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)
52
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)
79
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 ])
87
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")])
91 \f
92 (define_attr "length" "" (const_int 4))
93
94 ;; Processor type -- this attribute must exactly match the processor_type
95 ;; enumeration in frv-protos.h.
96
97 (define_attr "cpu" "generic,fr550,fr500,fr450,fr405,fr400,fr300,simple,tomcat"
98 (const (symbol_ref "(enum attr_cpu) frv_cpu_type")))
99
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.
103
104 (define_attr "far_jump" "yes,no" (const_string "no"))
105
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"))
111
112 (define_attr "acc_group" "none,even,odd"
113 (symbol_ref "(enum attr_acc_group) frv_acc_group (insn)"))
114 \f
115 ;; Scheduling and Packing Overview
116 ;; -------------------------------
117 ;;
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.
123 ;;
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.
130 ;;
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.
137 ;;
138 ;; Having decided which instructions should issue to which units, the packet
139 ;; should be ordered according to the following template:
140 ;;
141 ;; I0 F0/M0 I1 F1/M1 .... B0 B1 ...
142 ;;
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.
149 ;;
150 ;; Three gcc passes are involved in generating VLIW packets:
151 ;;
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.
155 ;;
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.
159 ;;
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.
163 ;;
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:
166 ;;
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.
175 ;;
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).
180 ;;
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.
186 ;;
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.
191 ;;
192 ;; For example, suppose we're compiling for the fr400 and we have:
193 ;;
194 ;; addi gr4,#1,gr5
195 ;; ldi @(gr6,gr0),gr4
196 ;;
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.
203 ;;
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.
208 ;;
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.)
216 ;;
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.
220 ;;
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:
224 ;;
225 ;; 1. Partition the instructions into groups (integer, float/media, etc.)
226 ;;
227 ;; 2. For each group of instructions:
228 ;;
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.
232 ;;
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).
237 ;;
238 ;; (c) If this is the control or branch group, goto (i)
239 ;;
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.
244 ;;
245 ;; (e) If L is the length of S, goto (i)
246 ;;
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.
250 ;;
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).
255 ;;
256 ;; (h) If (g) found no permutation, abort.
257 ;;
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.
260 ;;
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.
267 ;;
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.
275 ;;
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.
282 ;;
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")
288
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")
295
296 ;; Division units.
297 (define_cpu_unit "idiv1,idiv2" "idiv")
298 (define_cpu_unit "div1,div2,root" "div")
299
300 ;; Control instructions cannot be packed with others.
301 (define_reservation "control" "i0+i1+i2+i3+f0+f1+f2+f3+b0+b1")
302
303 ;; Generic reservation for control insns
304 (define_insn_reservation "control" 1
305 (eq_attr "type" "trap,spr,unknown,multi")
306 "c + control")
307
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")
312
313 ;; ::::::::::::::::::::
314 ;; ::
315 ;; :: Generic/FR500 scheduler description
316 ;; ::
317 ;; ::::::::::::::::::::
318
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")
324
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")
330
331 (define_insn_reservation "fr500_i1_setlo" 1
332 (and (eq_attr "cpu" "generic,fr500,tomcat")
333 (eq_attr "type" "setlo"))
334 "i1|i0")
335
336 (define_insn_reservation "fr500_i1_int" 1
337 (and (eq_attr "cpu" "generic,fr500,tomcat")
338 (eq_attr "type" "int"))
339 "i1|i0")
340
341 (define_insn_reservation "fr500_i1_mul" 3
342 (and (eq_attr "cpu" "generic,fr500,tomcat")
343 (eq_attr "type" "mul"))
344 "i1|i0")
345
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)")
350
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)")
355
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")
360
361 (define_insn_reservation "fr500_i4" 3
362 (and (eq_attr "cpu" "generic,fr500,tomcat")
363 (eq_attr "type" "movgf,movfg"))
364 "i0")
365
366 (define_insn_reservation "fr500_i5" 0
367 (and (eq_attr "cpu" "generic,fr500,tomcat")
368 (eq_attr "type" "jumpl"))
369 "i0")
370
371 ;;
372 ;; Branch-instructions
373 ;;
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")
378
379 (define_insn_reservation "fr500_call" 0
380 (and (eq_attr "cpu" "generic,fr500,tomcat")
381 (eq_attr "type" "call"))
382 "b0")
383
384 ;; Floating point insns. The default latencies are for non-media
385 ;; instructions; media instructions incur an extra cycle.
386
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)")
393
394 (define_insn_reservation "fr500_fcmp" 4
395 (and (eq_attr "cpu" "generic,fr500,tomcat")
396 (eq_attr "type" "fscmp,fdcmp"))
397 "(f1|f0)")
398
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)")
405
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")
412
413 ;; Media insns. Conflict table is as follows:
414 ;;
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
422 ;;
423 ;; where X indicates an invalid combination.
424 ;;
425 ;; Target registers are as follows:
426 ;;
427 ;; M1 : FPRs
428 ;; M2 : FPRs
429 ;; M3 : ACCs
430 ;; M4 : ACCs
431 ;; M5 : FPRs
432 ;; M6 : ACCs
433 ;;
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")
443
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")
447
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)")
455
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)")
463
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)")
469
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)")
475
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")
483
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")
489
490 ;; ::::::::::::::::::::
491 ;; ::
492 ;; :: FR400 scheduler description
493 ;; ::
494 ;; ::::::::::::::::::::
495
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.
499
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
514 ;;
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.
518
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.
522
523 (define_automaton "fr400_integer")
524 (define_cpu_unit "fr400_mul" "fr400_integer")
525
526 (define_insn_reservation "fr400_i1_int" 1
527 (and (eq_attr "cpu" "fr400,fr405,fr450")
528 (eq_attr "type" "int"))
529 "i1|i0")
530
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")
536
537 (define_insn_reservation "fr400_i1_setlo" 1
538 (and (eq_attr "cpu" "fr400,fr405,fr450")
539 (eq_attr "type" "setlo"))
540 "i1|i0")
541
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")
547
548 (define_insn_reservation "fr450_i1_mul" 2
549 (and (eq_attr "cpu" "fr450")
550 (eq_attr "type" "mul"))
551 "i0 + fr400_mul")
552
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")
558
559 (define_insn_reservation "fr400_i1_scan" 1
560 (and (eq_attr "cpu" "fr400,fr405,fr450")
561 (eq_attr "type" "scan"))
562 "i0")
563
564 (define_insn_reservation "fr400_i1_cut" 2
565 (and (eq_attr "cpu" "fr405,fr450")
566 (eq_attr "type" "cut"))
567 "i0 + fr400_mul")
568
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")
574
575 (define_insn_reservation "fr450_i1_div" 19
576 (and (eq_attr "cpu" "fr450")
577 (eq_attr "type" "div"))
578 "i0 + idiv1*19")
579
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")
585
586 (define_insn_reservation "fr450_i2_gload" 3
587 (and (eq_attr "cpu" "fr450")
588 (eq_attr "type" "gload"))
589 "i0")
590
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")
596
597 (define_insn_reservation "fr400_i3" 0
598 (and (eq_attr "cpu" "fr400,fr405,fr450")
599 (eq_attr "type" "gstore,fstore"))
600 "i0")
601
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")
607
608 (define_insn_reservation "fr450_i4_movfg" 2
609 (and (eq_attr "cpu" "fr450")
610 (eq_attr "type" "movfg"))
611 "i0")
612
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")
618
619 (define_insn_reservation "fr400_i5" 0
620 (and (eq_attr "cpu" "fr400,fr405,fr450")
621 (eq_attr "type" "jumpl"))
622 "i0")
623
624 ;; The bypass between FPR loads and media instructions, described above.
625
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")
633
634 ;; The branch instructions all use the B unit and produce no result.
635
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")
640
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.
645
646 ;; M1 instructions store their results in FPRs. Any instruction can read
647 ;; the result in the following cycle, so no penalty occurs.
648
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")
652
653 (define_reservation "fr400_m1" "(f1|f0) + (fr400_m1a|fr400_m1b)")
654 (define_reservation "fr400_m2" "f0 + fr400_m2a")
655
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")
660
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")
665
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.
669
670 (define_bypass 1
671 "fr400_m2_1,fr400_m2_2"
672 "fr400_m2_1,fr400_m2_2")
673
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")
678
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")
683
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.
687
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")
692
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")
697
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.
701
702 (define_bypass 1 "fr400_m4_1,fr400_m4_2" "fr400_i3,fr400_i4")
703
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")
708
709 (define_insn_reservation "fr400_m4_2" 2
710 (and (eq_attr "cpu" "fr400,fr405")
711 (eq_attr "type" "mclracca,mdcut"))
712 "fr400_m2")
713
714 ;; M5 instructions always incur a 1-cycle penalty.
715
716 (define_insn_reservation "fr400_m5" 2
717 (and (eq_attr "cpu" "fr400,fr405")
718 (eq_attr "type" "mwtacc"))
719 "fr400_m2")
720
721 ;; ::::::::::::::::::::
722 ;; ::
723 ;; :: FR450 media scheduler description
724 ;; ::
725 ;; ::::::::::::::::::::
726
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:
730 ;;
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
739 ;;
740 ;; where "x" indicates a conflict.
741 ;;
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".
744
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")
749
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")
752
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")
757
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")
763
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.
768 ;;
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")
776
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")
783
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")
791
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")
796
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")
799
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")
805
806 (define_insn_reservation "fr450_md4_4" 3
807 (and (eq_attr "cpu" "fr450")
808 (eq_attr "type" "mclracca"))
809 "fr450_m4")
810
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")
816
817 (define_insn_reservation "fr450_md4_5" 2
818 (and (eq_attr "cpu" "fr450")
819 (eq_attr "type" "mrdacc"))
820 "fr450_m5")
821
822 (define_insn_reservation "fr450_md4_6" 2
823 (and (eq_attr "cpu" "fr450")
824 (eq_attr "type" "mdcut"))
825 "fr450_m6")
826
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")
831
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")
838
839 ;; ::::::::::::::::::::
840 ;; ::
841 ;; :: FR550 scheduler description
842 ;; ::
843 ;; ::::::::::::::::::::
844
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")
851
852 ;; A store can only issue to I1 if one has also been issued to I0.
853 (presence_set "fr550_store1" "fr550_store0")
854
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")
860
861 (define_insn_reservation "fr550_setlo" 1
862 (and (eq_attr "cpu" "fr550")
863 (eq_attr "type" "setlo"))
864 "i3|i2|i1|i0")
865
866 (define_insn_reservation "fr550_int" 1
867 (and (eq_attr "cpu" "fr550")
868 (eq_attr "type" "int"))
869 "i3|i2|i1|i0")
870
871 (define_insn_reservation "fr550_mul" 2
872 (and (eq_attr "cpu" "fr550")
873 (eq_attr "type" "mul"))
874 "i1|i0")
875
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)")
880
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)")
885
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)")
893
894 (define_insn_reservation "fr550_transfer" 2
895 (and (eq_attr "cpu" "fr550")
896 (eq_attr "type" "movgf,movfg"))
897 "i0")
898
899 (define_insn_reservation "fr550_jumpl" 0
900 (and (eq_attr "cpu" "fr550")
901 (eq_attr "type" "jumpl"))
902 "i0")
903
904 (define_cpu_unit "fr550_ccr0,fr550_ccr1" "float_media")
905
906 (define_insn_reservation "fr550_branch" 0
907 (and (eq_attr "cpu" "fr550")
908 (eq_attr "type" "jump,branch"))
909 "b1|b0")
910
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)")
915
916 (define_insn_reservation "fr550_call" 0
917 (and (eq_attr "cpu" "fr550")
918 (eq_attr "type" "call"))
919 "b0")
920
921 (define_automaton "fr550_float_media")
922 (define_cpu_unit "fr550_add0,fr550_add1" "fr550_float_media")
923
924 ;; There are three possible combinations of floating-point/media instructions:
925 ;;
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.
937 ;;
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")
944
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")
947
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")
952
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")
957
958 (define_insn_reservation "fr550_f3_mul" 3
959 (and (eq_attr "cpu" "fr550")
960 (eq_attr "type" "fsmul"))
961 "(f1|f0) + fr550_float")
962
963 (define_insn_reservation "fr550_f3_div" 10
964 (and (eq_attr "cpu" "fr550")
965 (eq_attr "type" "fsdiv"))
966 "(f1|f0) + fr550_float")
967
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")
972
973 ;; Synthetic units for enforcing media issue restrictions. Certain types
974 ;; of insn in M2 conflict with certain types in M0:
975 ;;
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 - -
983 ;;
984 ;; where "x" indicates a conflict. The same restrictions apply to
985 ;; M3 and M1.
986 ;;
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")
998
999 (exclusion_set "fr550_malu0" "fr550_malu2")
1000 (exclusion_set "fr550_malu1" "fr550_malu3")
1001
1002 (exclusion_set "fr550_msft0" "fr550_mset2")
1003 (exclusion_set "fr550_msft1" "fr550_mset3")
1004
1005 (exclusion_set "fr550_mmac0" "fr550_mmac2")
1006 (exclusion_set "fr550_mmac1" "fr550_mmac3")
1007
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.
1012 ;;
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")
1020
1021 (define_reservation "fr550_malu"
1022 "(f3 + fr550_malu3) | (f2 + fr550_malu2)
1023 | (f1 + fr550_malu1) | (f0 + fr550_malu0)")
1024
1025 (define_reservation "fr550_msft_even"
1026 "f0 + fr550_msft0")
1027
1028 (define_reservation "fr550_msft_odd"
1029 "f1 + fr550_msft1")
1030
1031 (define_reservation "fr550_msft_either"
1032 "(f1 + fr550_msft1) | (f0 + fr550_msft0)")
1033
1034 (define_reservation "fr550_mmac_even"
1035 "(f2 + fr550_mmac2) | (f0 + fr550_mmac0)")
1036
1037 (define_reservation "fr550_mmac_odd"
1038 "(f3 + fr550_mmac3) | (f1 + fr550_mmac1)")
1039
1040 (define_reservation "fr550_mset"
1041 "(f3 + fr550_mset3) | (f2 + fr550_mset2)
1042 | (f1 + fr550_mset1) | (f0 + fr550_mset0)")
1043
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)")
1048
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")
1053
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")
1061
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")
1068
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")
1075
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")
1081
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")
1088
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")
1095
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")
1103
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")
1111
1112 (define_insn_reservation "fr550_mset" 1
1113 (and (eq_attr "cpu" "fr550")
1114 (eq_attr "type" "mset"))
1115 "fr550_media + fr550_mset")
1116
1117 ;; ::::::::::::::::::::
1118 ;; ::
1119 ;; :: Simple/FR300 scheduler description
1120 ;; ::
1121 ;; ::::::::::::::::::::
1122
1123 ;; Fr300 or simple processor. To describe it as 1 insn issue
1124 ;; processor, we use control unit.
1125
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")
1130
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")
1135
1136 \f
1137 ;; ::::::::::::::::::::
1138 ;; ::
1139 ;; :: Delay Slots
1140 ;; ::
1141 ;; ::::::::::::::::::::
1142
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.
1149
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.
1155
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.
1161
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:
1164 ;;
1165 ;; (define_delay TEST
1166 ;; [DELAY-1 ANNUL-TRUE-1 ANNUL-FALSE-1
1167 ;; DELAY-2 ANNUL-TRUE-2 ANNUL-FALSE-2
1168 ;; ...])
1169
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.
1178
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:
1182
1183 ;; (define_delay (eq_attr "type" "branch,call")
1184 ;; [(eq_attr "type" "!branch,call") (nil) (nil)])
1185
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.
1189
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:
1194
1195 ;; (define_delay (eq_attr "type" "branch")
1196 ;; [(eq_attr "type" "!branch,call")
1197 ;; (eq_attr "type" "!branch,call")
1198 ;; (nil)])
1199 ;;
1200 ;; (define_delay (eq_attr "type" "call")
1201 ;; [(eq_attr "type" "!branch,call") (nil) (nil)
1202 ;; (eq_attr "type" "!branch,call") (nil) (nil)])
1203
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:
1209 ;;
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")])
1218 ;;
1219 ;; -------------<machine>.h-------------------
1220 ;; #define PRINT_OPERAND_PUNCT_VALID_P(CODE) (CODE == '#')
1221 ;;
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;
1235 \f
1236 ;; ::::::::::::::::::::
1237 ;; ::
1238 ;; :: Notes on Patterns
1239 ;; ::
1240 ;; ::::::::::::::::::::
1241
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.:
1245 ;;
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 ;; )
1255 ;;
1256 ;; Also if there is more than one instruction, they can be separated by \\;
1257 ;; which is a space saving synonym for \\n\\t:
1258 ;;
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 ;; )
1269 ;;
1270
1271 (include "predicates.md")
1272 (include "constraints.md")
1273 \f
1274 ;; ::::::::::::::::::::
1275 ;; ::
1276 ;; :: Moves
1277 ;; ::
1278 ;; ::::::::::::::::::::
1279
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.
1283
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.
1288
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.
1292
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.
1298
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.
1305
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.
1310
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.
1319 ;;
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.
1323 ;;
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.
1329 ;;
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.
1336
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.
1341
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.
1347
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.
1354
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; }")
1360
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")])
1368
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")])
1376
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; }")
1382
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")])
1390
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")])
1398
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 "")
1410
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")])
1418
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")])
1427
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; }")
1433
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).
1439
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.
1448
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.
1456 ;;
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")])
1466
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")])
1474
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")])
1482
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")])
1491
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")])
1499
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")])
1515
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")])
1523
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")])
1532
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; }")
1538
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")])
1548
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")])
1558
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]);")
1565
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]);")
1572
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]);")
1579
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]);")
1586
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 "
1601 {
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);
1608
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. */
1612
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 }
1627 }")
1628
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 "
1636 {
1637 rtx op0 = operands[0];
1638 rtx op1 = operands[1];
1639
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 }
1652 }")
1653
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 "
1661 {
1662 rtx op0 = operands[0];
1663 rtx op1 = operands[1];
1664
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));
1669 }")
1670
1671 ;; Floating Point Moves
1672 ;;
1673 ;; Note - Patterns for SF mode moves are compulsory, but
1674 ;; patterns for DF are optional, as GCC can synthesize them.
1675
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; }")
1681
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 "")
1692
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")])
1700
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")])
1709
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")])
1720
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")])
1728
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")])
1737
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; }")
1743
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")])
1753
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")])
1765
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]);")
1772
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]);")
1779
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]);")
1786
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]);")
1793
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 "
1808 {
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);
1815
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. */
1819
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 }
1834 }")
1835
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 "
1843 {
1844 rtx op0 = operands[0];
1845 rtx op1 = operands[1];
1846
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 }
1861 }")
1862
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 "
1870 {
1871 rtx op0 = operands[0];
1872 rtx op1 = operands[1];
1873 long l[2];
1874
1875 REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (op1), l);
1876
1877 operands[2] = gen_highpart (SImode, op0);
1878 operands[3] = gen_lowpart (SImode, op0);
1879 operands[4] = GEN_INT (l[0]);
1880 operands[5] = GEN_INT (l[1]);
1881 }")
1882
1883 ;; String/block move insn.
1884 ;; Argument 0 is the destination
1885 ;; Argument 1 is the source
1886 ;; Argument 2 is the length
1887 ;; Argument 3 is the alignment
1888
1889 (define_expand "movmemsi"
1890 [(parallel [(set (match_operand:BLK 0 "" "")
1891 (match_operand:BLK 1 "" ""))
1892 (use (match_operand:SI 2 "" ""))
1893 (use (match_operand:SI 3 "" ""))])]
1894 ""
1895 "
1896 {
1897 if (frv_expand_block_move (operands))
1898 DONE;
1899 else
1900 FAIL;
1901 }")
1902
1903 ;; String/block set insn.
1904 ;; Argument 0 is the destination
1905 ;; Argument 1 is the length
1906 ;; Argument 2 is the byte value -- ignore any value but zero
1907 ;; Argument 3 is the alignment
1908
1909 (define_expand "setmemsi"
1910 [(parallel [(set (match_operand:BLK 0 "" "")
1911 (match_operand 2 "" ""))
1912 (use (match_operand:SI 1 "" ""))
1913 (use (match_operand:SI 3 "" ""))])]
1914 ""
1915 "
1916 {
1917 /* If value to set is not zero, use the library routine. */
1918 if (operands[2] != const0_rtx)
1919 FAIL;
1920
1921 if (frv_expand_block_clear (operands))
1922 DONE;
1923 else
1924 FAIL;
1925 }")
1926 \f
1927
1928 ;; The "membar" part of a __builtin_read* or __builtin_write* function.
1929 ;; Operand 0 is a volatile reference to the memory that the function reads
1930 ;; or writes. Operand 1 is the address being accessed, or zero if the
1931 ;; address isn't a known constant. Operand 2 describes the __builtin
1932 ;; function (either FRV_IO_READ or FRV_IO_WRITE).
1933 (define_insn "optional_membar_<mode>"
1934 [(set (match_operand:IMODE 0 "memory_operand" "=m")
1935 (unspec:IMODE [(match_operand 1 "const_int_operand" "")
1936 (match_operand 2 "const_int_operand" "")]
1937 UNSPEC_OPTIONAL_MEMBAR))]
1938 ""
1939 "membar"
1940 [(set_attr "length" "4")])
1941 \f
1942 ;; ::::::::::::::::::::
1943 ;; ::
1944 ;; :: Reload CC registers
1945 ;; ::
1946 ;; ::::::::::::::::::::
1947
1948 ;; Use as a define_expand so that cse/gcse/combine can't accidentally
1949 ;; create movcc insns.
1950
1951 (define_expand "movcc"
1952 [(parallel [(set (match_operand:CC 0 "move_destination_operand" "")
1953 (match_operand:CC 1 "move_source_operand" ""))
1954 (clobber (match_dup 2))])]
1955 ""
1956 "
1957 {
1958 if (! reload_in_progress && ! reload_completed)
1959 FAIL;
1960
1961 operands[2] = gen_rtx_REG (CC_CCRmode, ICR_TEMP);
1962 }")
1963
1964 (define_insn "*internal_movcc"
1965 [(set (match_operand:CC 0 "move_destination_operand" "=t,d,d,m,d")
1966 (match_operand:CC 1 "move_source_operand" "d,d,m,d,t"))
1967 (clobber (match_scratch:CC_CCR 2 "=X,X,X,X,&v"))]
1968 "reload_in_progress || reload_completed"
1969 "@
1970 cmpi %1, #0, %0
1971 mov %1, %0
1972 ld%I1%U1 %M1, %0
1973 st%I0%U0 %1, %M0
1974 #"
1975 [(set_attr "length" "4,4,4,4,20")
1976 (set_attr "type" "int,int,gload,gstore,multi")])
1977
1978 ;; To move an ICC value to a GPR for a signed comparison, we create a value
1979 ;; that when compared to 0, sets the N and Z flags appropriately (we don't care
1980 ;; about the V and C flags, since these comparisons are signed).
1981
1982 (define_split
1983 [(set (match_operand:CC 0 "integer_register_operand" "")
1984 (match_operand:CC 1 "icc_operand" ""))
1985 (clobber (match_operand:CC_CCR 2 "icr_operand" ""))]
1986 "reload_in_progress || reload_completed"
1987 [(match_dup 3)]
1988 "
1989 {
1990 rtx dest = simplify_gen_subreg (SImode, operands[0], CCmode, 0);
1991 rtx icc = operands[1];
1992 rtx icr = operands[2];
1993
1994 start_sequence ();
1995
1996 emit_insn (gen_rtx_SET (icr, gen_rtx_LT (CC_CCRmode, icc, const0_rtx)));
1997
1998 emit_insn (gen_movsi (dest, const1_rtx));
1999
2000 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
2001 gen_rtx_NE (CC_CCRmode, icr, const0_rtx),
2002 gen_rtx_SET (dest,
2003 gen_rtx_NEG (SImode, dest))));
2004
2005 emit_insn (gen_rtx_SET (icr, gen_rtx_EQ (CC_CCRmode, icc, const0_rtx)));
2006
2007 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
2008 gen_rtx_NE (CC_CCRmode, icr, const0_rtx),
2009 gen_rtx_SET (dest, const0_rtx)));
2010
2011 operands[3] = get_insns ();
2012 end_sequence ();
2013 }")
2014
2015 ;; Reload CC_UNSmode for unsigned integer comparisons
2016 ;; Use define_expand so that cse/gcse/combine can't create movcc_uns insns
2017
2018 (define_expand "movcc_uns"
2019 [(parallel [(set (match_operand:CC_UNS 0 "move_destination_operand" "")
2020 (match_operand:CC_UNS 1 "move_source_operand" ""))
2021 (clobber (match_dup 2))])]
2022 ""
2023 "
2024 {
2025 if (! reload_in_progress && ! reload_completed)
2026 FAIL;
2027 operands[2] = gen_rtx_REG (CC_CCRmode, ICR_TEMP);
2028 }")
2029
2030 (define_insn "*internal_movcc_uns"
2031 [(set (match_operand:CC_UNS 0 "move_destination_operand" "=t,d,d,m,d")
2032 (match_operand:CC_UNS 1 "move_source_operand" "d,d,m,d,t"))
2033 (clobber (match_scratch:CC_CCR 2 "=X,X,X,X,&v"))]
2034 "reload_in_progress || reload_completed"
2035 "@
2036 cmpi %1, #1, %0
2037 mov %1, %0
2038 ld%I1%U1 %M1, %0
2039 st%I0%U0 %1, %M0
2040 #"
2041 [(set_attr "length" "4,4,4,4,20")
2042 (set_attr "type" "int,int,gload,gstore,multi")])
2043
2044 ;; To move an ICC value to a GPR for an unsigned comparison, we create a value
2045 ;; that when compared to 1, sets the Z, V, and C flags appropriately (we don't
2046 ;; care about the N flag, since these comparisons are unsigned).
2047
2048 (define_split
2049 [(set (match_operand:CC_UNS 0 "integer_register_operand" "")
2050 (match_operand:CC_UNS 1 "icc_operand" ""))
2051 (clobber (match_operand:CC_CCR 2 "icr_operand" ""))]
2052 "reload_in_progress || reload_completed"
2053 [(match_dup 3)]
2054 "
2055 {
2056 rtx dest = simplify_gen_subreg (SImode, operands[0], CC_UNSmode, 0);
2057 rtx icc = operands[1];
2058 rtx icr = operands[2];
2059
2060 start_sequence ();
2061
2062 emit_insn (gen_rtx_SET (icr, gen_rtx_GTU (CC_CCRmode, icc, const0_rtx)));
2063
2064 emit_insn (gen_movsi (dest, const1_rtx));
2065
2066 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
2067 gen_rtx_NE (CC_CCRmode, icr, const0_rtx),
2068 gen_addsi3 (dest, dest, dest)));
2069
2070 emit_insn (gen_rtx_SET (icr, gen_rtx_LTU (CC_CCRmode, icc, const0_rtx)));
2071
2072 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
2073 gen_rtx_NE (CC_CCRmode, icr, const0_rtx),
2074 gen_rtx_SET (dest, const0_rtx)));
2075
2076 operands[3] = get_insns ();
2077 end_sequence ();
2078 }")
2079
2080 ;; Reload CC_NZmode. This is mostly the same as the CCmode and CC_UNSmode
2081 ;; handling, but it uses different sequences for moving between GPRs and ICCs.
2082
2083 (define_expand "movcc_nz"
2084 [(parallel [(set (match_operand:CC_NZ 0 "move_destination_operand" "")
2085 (match_operand:CC_NZ 1 "move_source_operand" ""))
2086 (clobber (match_dup 2))])]
2087 ""
2088 "
2089 {
2090 if (!reload_in_progress && !reload_completed)
2091 FAIL;
2092 operands[2] = gen_rtx_REG (CC_CCRmode, ICR_TEMP);
2093 }")
2094
2095 (define_insn "*internal_movcc_nz"
2096 [(set (match_operand:CC_NZ 0 "move_destination_operand" "=t,d,d,m,d")
2097 (match_operand:CC_NZ 1 "move_source_operand" "d,d,m,d,t"))
2098 (clobber (match_scratch:CC_CCR 2 "=X,X,X,X,&v"))]
2099 "reload_in_progress || reload_completed"
2100 "@
2101 cmpi %1, #0, %0
2102 mov %1, %0
2103 ld%I1%U1 %M1, %0
2104 st%I0%U0 %1, %M0
2105 #"
2106 [(set_attr "length" "4,4,4,4,20")
2107 (set_attr "type" "int,int,gload,gstore,multi")])
2108
2109 ;; Set the destination to a value that, when compared with zero, will
2110 ;; restore the value of the Z and N flags. The values of the other
2111 ;; flags don't matter. The sequence is:
2112 ;;
2113 ;; setlos op0,#-1
2114 ;; ckp op1,op2
2115 ;; csub gr0,op0,op0,op2
2116 ;; ckeq op1,op2
2117 ;; cmov gr0,op0,op2
2118 (define_split
2119 [(set (match_operand:CC_NZ 0 "integer_register_operand" "")
2120 (match_operand:CC_NZ 1 "icc_operand" ""))
2121 (clobber (match_operand:CC_CCR 2 "icr_operand" ""))]
2122 "reload_in_progress || reload_completed"
2123 [(set (match_dup 3)
2124 (const_int -1))
2125 (set (match_dup 2)
2126 (ge:CC_CCR (match_dup 1)
2127 (const_int 0)))
2128 (cond_exec (ne:CC_CCR (match_dup 2)
2129 (const_int 0))
2130 (set (match_dup 3)
2131 (neg:SI (match_dup 3))))
2132 (set (match_dup 2)
2133 (eq:CC_CCR (match_dup 1)
2134 (const_int 0)))
2135 (cond_exec (ne:CC_CCR (match_dup 2)
2136 (const_int 0))
2137 (set (match_dup 3) (const_int 0)))]
2138 "operands[3] = simplify_gen_subreg (SImode, operands[0], CC_NZmode, 0);")
2139
2140 ;; Reload CC_FPmode for floating point comparisons
2141 ;; We use a define_expand here so that cse/gcse/combine can't accidentally
2142 ;; create movcc insns. If this was a named define_insn, we would not be able
2143 ;; to make it conditional on reload.
2144
2145 (define_expand "movcc_fp"
2146 [(set (match_operand:CC_FP 0 "movcc_fp_destination_operand" "")
2147 (match_operand:CC_FP 1 "move_source_operand" ""))]
2148 "TARGET_HAS_FPRS"
2149 "
2150 {
2151 if (! reload_in_progress && ! reload_completed)
2152 FAIL;
2153 }")
2154
2155 (define_insn "*movcc_fp_internal"
2156 [(set (match_operand:CC_FP 0 "movcc_fp_destination_operand" "=d,d,d,m")
2157 (match_operand:CC_FP 1 "move_source_operand" "u,d,m,d"))]
2158 "TARGET_HAS_FPRS && (reload_in_progress || reload_completed)"
2159 "@
2160 #
2161 mov %1, %0
2162 ld%I1%U1 %M1, %0
2163 st%I0%U0 %1, %M0"
2164 [(set_attr "length" "12,4,4,4")
2165 (set_attr "type" "multi,int,gload,gstore")])
2166
2167
2168 (define_expand "reload_incc_fp"
2169 [(match_operand:CC_FP 0 "fcc_operand" "=u")
2170 (match_operand:CC_FP 1 "gpr_or_memory_operand_with_scratch" "m")
2171 (match_operand:TI 2 "integer_register_operand" "=&d")]
2172 "TARGET_HAS_FPRS"
2173 "
2174 {
2175 rtx cc_op2 = simplify_gen_subreg (CC_FPmode, operands[2], TImode, 0);
2176 rtx int_op2 = simplify_gen_subreg (SImode, operands[2], TImode, 0);
2177 rtx temp1 = simplify_gen_subreg (SImode, operands[2], TImode, 4);
2178 rtx temp2 = simplify_gen_subreg (SImode, operands[2], TImode, 8);
2179 int shift = CC_SHIFT_RIGHT (REGNO (operands[0]));
2180 HOST_WIDE_INT mask;
2181
2182 if (!gpr_or_memory_operand (operands[1], CC_FPmode))
2183 {
2184 rtx addr;
2185 rtx temp3 = simplify_gen_subreg (SImode, operands[2], TImode, 12);
2186
2187 gcc_assert (GET_CODE (operands[1]) == MEM);
2188
2189 addr = XEXP (operands[1], 0);
2190
2191 gcc_assert (GET_CODE (addr) == PLUS);
2192
2193 emit_move_insn (temp3, XEXP (addr, 1));
2194
2195 operands[1] = replace_equiv_address (operands[1],
2196 gen_rtx_PLUS (GET_MODE (addr),
2197 XEXP (addr, 0),
2198 temp3));
2199 }
2200
2201 emit_insn (gen_movcc_fp (cc_op2, operands[1]));
2202 if (shift)
2203 emit_insn (gen_ashlsi3 (int_op2, int_op2, GEN_INT (shift)));
2204
2205 mask = ~ ((HOST_WIDE_INT)CC_MASK << shift);
2206 emit_insn (gen_movsi (temp1, GEN_INT (mask)));
2207 emit_insn (gen_update_fcc (operands[0], int_op2, temp1, temp2));
2208 DONE;
2209 }")
2210
2211 (define_expand "reload_outcc_fp"
2212 [(set (match_operand:CC_FP 2 "integer_register_operand" "=&d")
2213 (match_operand:CC_FP 1 "fcc_operand" "u"))
2214 (set (match_operand:CC_FP 0 "memory_operand" "=m")
2215 (match_dup 2))]
2216 "TARGET_HAS_FPRS"
2217 "")
2218
2219 ;; Convert a FCC value to gpr
2220 (define_insn "read_fcc"
2221 [(set (match_operand:SI 0 "integer_register_operand" "=d")
2222 (unspec:SI [(match_operand:CC_FP 1 "fcc_operand" "u")]
2223 UNSPEC_CC_TO_GPR))]
2224 "TARGET_HAS_FPRS"
2225 "movsg ccr, %0"
2226 [(set_attr "type" "spr")
2227 (set_attr "length" "4")])
2228
2229 (define_split
2230 [(set (match_operand:CC_FP 0 "integer_register_operand" "")
2231 (match_operand:CC_FP 1 "fcc_operand" ""))]
2232 "reload_completed && TARGET_HAS_FPRS"
2233 [(match_dup 2)]
2234 "
2235 {
2236 rtx int_op0 = simplify_gen_subreg (SImode, operands[0], CC_FPmode, 0);
2237 int shift = CC_SHIFT_RIGHT (REGNO (operands[1]));
2238
2239 start_sequence ();
2240
2241 emit_insn (gen_read_fcc (int_op0, operands[1]));
2242 if (shift)
2243 emit_insn (gen_lshrsi3 (int_op0, int_op0, GEN_INT (shift)));
2244
2245 emit_insn (gen_andsi3 (int_op0, int_op0, GEN_INT (CC_MASK)));
2246
2247 operands[2] = get_insns ();
2248 end_sequence ();
2249 }")
2250
2251 ;; Move a gpr value to FCC.
2252 ;; Operand0 = FCC
2253 ;; Operand1 = reloaded value shifted appropriately
2254 ;; Operand2 = mask to eliminate current register
2255 ;; Operand3 = temporary to load/store ccr
2256 (define_insn "update_fcc"
2257 [(set (match_operand:CC_FP 0 "fcc_operand" "=u")
2258 (unspec:CC_FP [(match_operand:SI 1 "integer_register_operand" "d")
2259 (match_operand:SI 2 "integer_register_operand" "d")]
2260 UNSPEC_GPR_TO_CC))
2261 (clobber (match_operand:SI 3 "integer_register_operand" "=&d"))]
2262 "TARGET_HAS_FPRS"
2263 "movsg ccr, %3\;and %2, %3, %3\;or %1, %3, %3\;movgs %3, ccr"
2264 [(set_attr "type" "multi")
2265 (set_attr "length" "16")])
2266
2267 ;; Reload CC_CCRmode for conditional execution registers
2268 (define_insn "movcc_ccr"
2269 [(set (match_operand:CC_CCR 0 "move_destination_operand" "=d,d,d,m,v,?w,C,d")
2270 (match_operand:CC_CCR 1 "move_source_operand" "C,d,m,d,n,n,C,L"))]
2271 ""
2272 "@
2273 #
2274 mov %1, %0
2275 ld%I1%U1 %M1, %0
2276 st%I0%U0 %1, %M0
2277 #
2278 #
2279 orcr %1, %1, %0
2280 setlos #%1, %0"
2281 [(set_attr "length" "8,4,4,4,8,12,4,4")
2282 (set_attr "type" "multi,int,gload,gstore,multi,multi,ccr,int")])
2283
2284 (define_expand "reload_incc_ccr"
2285 [(match_operand:CC_CCR 0 "cr_operand" "=C")
2286 (match_operand:CC_CCR 1 "memory_operand" "m")
2287 (match_operand:CC_CCR 2 "integer_register_operand" "=&d")]
2288 ""
2289 "
2290 {
2291 rtx icc = gen_rtx_REG (CCmode, ICC_TEMP);
2292 rtx int_op2 = simplify_gen_subreg (SImode, operands[2], CC_CCRmode, 0);
2293 rtx icr = (ICR_P (REGNO (operands[0]))
2294 ? operands[0] : gen_rtx_REG (CC_CCRmode, ICR_TEMP));
2295
2296 emit_insn (gen_movcc_ccr (operands[2], operands[1]));
2297 emit_insn (gen_cmpsi_cc (icc, int_op2, const0_rtx));
2298 emit_insn (gen_movcc_ccr (icr, gen_rtx_NE (CC_CCRmode, icc, const0_rtx)));
2299
2300 if (! ICR_P (REGNO (operands[0])))
2301 emit_insn (gen_movcc_ccr (operands[0], icr));
2302
2303 DONE;
2304 }")
2305
2306 (define_expand "reload_outcc_ccr"
2307 [(set (match_operand:CC_CCR 2 "integer_register_operand" "=&d")
2308 (match_operand:CC_CCR 1 "cr_operand" "C"))
2309 (set (match_operand:CC_CCR 0 "memory_operand" "=m")
2310 (match_dup 2))]
2311 ""
2312 "")
2313
2314 (define_split
2315 [(set (match_operand:CC_CCR 0 "integer_register_operand" "")
2316 (match_operand:CC_CCR 1 "cr_operand" ""))]
2317 "reload_completed"
2318 [(match_dup 2)]
2319 "
2320 {
2321 rtx int_op0 = simplify_gen_subreg (SImode, operands[0], CC_CCRmode, 0);
2322
2323 start_sequence ();
2324 emit_move_insn (operands[0], const1_rtx);
2325 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
2326 gen_rtx_EQ (CC_CCRmode,
2327 operands[1],
2328 const0_rtx),
2329 gen_rtx_SET (int_op0, const0_rtx)));
2330
2331 operands[2] = get_insns ();
2332 end_sequence ();
2333 }")
2334
2335 (define_split
2336 [(set (match_operand:CC_CCR 0 "cr_operand" "")
2337 (match_operand:CC_CCR 1 "const_int_operand" ""))]
2338 "reload_completed"
2339 [(match_dup 2)]
2340 "
2341 {
2342 rtx icc = gen_rtx_REG (CCmode, ICC_TEMP);
2343 rtx r0 = gen_rtx_REG (SImode, GPR_FIRST);
2344 rtx icr = (ICR_P (REGNO (operands[0]))
2345 ? operands[0] : gen_rtx_REG (CC_CCRmode, ICR_TEMP));
2346
2347 start_sequence ();
2348
2349 emit_insn (gen_cmpsi_cc (icc, r0, const0_rtx));
2350
2351 emit_insn (gen_movcc_ccr (icr,
2352 gen_rtx_fmt_ee (((INTVAL (operands[1]) == 0)
2353 ? EQ : NE), CC_CCRmode,
2354 r0, const0_rtx)));
2355
2356 if (! ICR_P (REGNO (operands[0])))
2357 emit_insn (gen_movcc_ccr (operands[0], icr));
2358
2359 operands[2] = get_insns ();
2360 end_sequence ();
2361 }")
2362
2363 \f
2364 ;; ::::::::::::::::::::
2365 ;; ::
2366 ;; :: Conversions
2367 ;; ::
2368 ;; ::::::::::::::::::::
2369
2370 ;; Signed conversions from a smaller integer to a larger integer
2371 ;;
2372 ;; These operations are optional. If they are not
2373 ;; present GCC will synthesize them for itself
2374 ;; Even though frv does not provide these instructions, we define them
2375 ;; to allow load + sign extend to be collapsed together
2376 (define_insn "extendqihi2"
2377 [(set (match_operand:HI 0 "integer_register_operand" "=d,d")
2378 (sign_extend:HI (match_operand:QI 1 "gpr_or_memory_operand" "d,m")))]
2379 ""
2380 "@
2381 #
2382 ldsb%I1%U1 %M1,%0"
2383 [(set_attr "length" "8,4")
2384 (set_attr "type" "multi,gload")])
2385
2386 (define_split
2387 [(set (match_operand:HI 0 "integer_register_operand" "")
2388 (sign_extend:HI (match_operand:QI 1 "integer_register_operand" "")))]
2389 "reload_completed"
2390 [(match_dup 2)
2391 (match_dup 3)]
2392 "
2393 {
2394 rtx op0 = gen_lowpart (SImode, operands[0]);
2395 rtx op1 = gen_lowpart (SImode, operands[1]);
2396 rtx shift = GEN_INT (24);
2397
2398 operands[2] = gen_ashlsi3 (op0, op1, shift);
2399 operands[3] = gen_ashrsi3 (op0, op0, shift);
2400 }")
2401
2402 (define_insn "extendqisi2"
2403 [(set (match_operand:SI 0 "integer_register_operand" "=d,d")
2404 (sign_extend:SI (match_operand:QI 1 "gpr_or_memory_operand" "d,m")))]
2405 ""
2406 "@
2407 #
2408 ldsb%I1%U1 %M1,%0"
2409 [(set_attr "length" "8,4")
2410 (set_attr "type" "multi,gload")])
2411
2412 (define_split
2413 [(set (match_operand:SI 0 "integer_register_operand" "")
2414 (sign_extend:SI (match_operand:QI 1 "integer_register_operand" "")))]
2415 "reload_completed"
2416 [(match_dup 2)
2417 (match_dup 3)]
2418 "
2419 {
2420 rtx op0 = gen_lowpart (SImode, operands[0]);
2421 rtx op1 = gen_lowpart (SImode, operands[1]);
2422 rtx shift = GEN_INT (24);
2423
2424 operands[2] = gen_ashlsi3 (op0, op1, shift);
2425 operands[3] = gen_ashrsi3 (op0, op0, shift);
2426 }")
2427
2428 ;;(define_insn "extendqidi2"
2429 ;; [(set (match_operand:DI 0 "register_operand" "=r")
2430 ;; (sign_extend:DI (match_operand:QI 1 "general_operand" "g")))]
2431 ;; ""
2432 ;; "extendqihi2 %0,%1"
2433 ;; [(set_attr "length" "4")])
2434
2435 (define_insn "extendhisi2"
2436 [(set (match_operand:SI 0 "integer_register_operand" "=d,d")
2437 (sign_extend:SI (match_operand:HI 1 "gpr_or_memory_operand" "d,m")))]
2438 ""
2439 "@
2440 #
2441 ldsh%I1%U1 %M1,%0"
2442 [(set_attr "length" "8,4")
2443 (set_attr "type" "multi,gload")])
2444
2445 (define_split
2446 [(set (match_operand:SI 0 "integer_register_operand" "")
2447 (sign_extend:SI (match_operand:HI 1 "integer_register_operand" "")))]
2448 "reload_completed"
2449 [(match_dup 2)
2450 (match_dup 3)]
2451 "
2452 {
2453 rtx op0 = gen_lowpart (SImode, operands[0]);
2454 rtx op1 = gen_lowpart (SImode, operands[1]);
2455 rtx shift = GEN_INT (16);
2456
2457 operands[2] = gen_ashlsi3 (op0, op1, shift);
2458 operands[3] = gen_ashrsi3 (op0, op0, shift);
2459 }")
2460
2461 ;;(define_insn "extendhidi2"
2462 ;; [(set (match_operand:DI 0 "register_operand" "=r")
2463 ;; (sign_extend:DI (match_operand:HI 1 "general_operand" "g")))]
2464 ;; ""
2465 ;; "extendhihi2 %0,%1"
2466 ;; [(set_attr "length" "4")])
2467 ;;
2468 ;;(define_insn "extendsidi2"
2469 ;; [(set (match_operand:DI 0 "register_operand" "=r")
2470 ;; (sign_extend:DI (match_operand:SI 1 "general_operand" "g")))]
2471 ;; ""
2472 ;; "extendsidi2 %0,%1"
2473 ;; [(set_attr "length" "4")])
2474
2475 ;; Unsigned conversions from a smaller integer to a larger integer
2476 (define_insn "zero_extendqihi2"
2477 [(set (match_operand:HI 0 "integer_register_operand" "=d,d,d")
2478 (zero_extend:HI
2479 (match_operand:QI 1 "gpr_or_memory_operand" "d,L,m")))]
2480 ""
2481 "@
2482 andi %1,#0xff,%0
2483 setlos %1,%0
2484 ldub%I1%U1 %M1,%0"
2485 [(set_attr "length" "4")
2486 (set_attr "type" "int,int,gload")])
2487
2488 (define_insn "zero_extendqisi2"
2489 [(set (match_operand:SI 0 "integer_register_operand" "=d,d,d")
2490 (zero_extend:SI
2491 (match_operand:QI 1 "gpr_or_memory_operand" "d,L,m")))]
2492 ""
2493 "@
2494 andi %1,#0xff,%0
2495 setlos %1,%0
2496 ldub%I1%U1 %M1,%0"
2497 [(set_attr "length" "4")
2498 (set_attr "type" "int,int,gload")])
2499
2500 ;;(define_insn "zero_extendqidi2"
2501 ;; [(set (match_operand:DI 0 "register_operand" "=r")
2502 ;; (zero_extend:DI (match_operand:QI 1 "general_operand" "g")))]
2503 ;; ""
2504 ;; "zero_extendqihi2 %0,%1"
2505 ;; [(set_attr "length" "4")])
2506
2507 ;; Do not set the type for the sethi to "sethi", since the scheduler will think
2508 ;; the sethi takes 0 cycles as part of allowing sethi/setlo to be in the same
2509 ;; VLIW instruction.
2510 (define_insn "zero_extendhisi2"
2511 [(set (match_operand:SI 0 "integer_register_operand" "=d,d")
2512 (zero_extend:SI (match_operand:HI 1 "gpr_or_memory_operand" "0,m")))]
2513 ""
2514 "@
2515 sethi #hi(#0),%0
2516 lduh%I1%U1 %M1,%0"
2517 [(set_attr "length" "4")
2518 (set_attr "type" "int,gload")])
2519
2520 ;;(define_insn "zero_extendhidi2"
2521 ;; [(set (match_operand:DI 0 "register_operand" "=r")
2522 ;; (zero_extend:DI (match_operand:HI 1 "general_operand" "g")))]
2523 ;; ""
2524 ;; "zero_extendhihi2 %0,%1"
2525 ;; [(set_attr "length" "4")])
2526 ;;
2527 ;;(define_insn "zero_extendsidi2"
2528 ;; [(set (match_operand:DI 0 "register_operand" "=r")
2529 ;; (zero_extend:DI (match_operand:SI 1 "general_operand" "g")))]
2530 ;; ""
2531 ;; "zero_extendsidi2 %0,%1"
2532 ;; [(set_attr "length" "4")])
2533 ;;
2534 ;;;; Convert between floating point types of different sizes.
2535 ;;
2536 ;;(define_insn "extendsfdf2"
2537 ;; [(set (match_operand:DF 0 "register_operand" "=r")
2538 ;; (float_extend:DF (match_operand:SF 1 "register_operand" "r")))]
2539 ;; ""
2540 ;; "extendsfdf2 %0,%1"
2541 ;; [(set_attr "length" "4")])
2542 ;;
2543 ;;(define_insn "truncdfsf2"
2544 ;; [(set (match_operand:SF 0 "register_operand" "=r")
2545 ;; (float_truncate:SF (match_operand:DF 1 "register_operand" "r")))]
2546 ;; ""
2547 ;; "truncdfsf2 %0,%1"
2548 ;; [(set_attr "length" "4")])
2549
2550 ;;;; Convert between signed integer types and floating point.
2551 (define_insn "floatsisf2"
2552 [(set (match_operand:SF 0 "fpr_operand" "=f")
2553 (float:SF (match_operand:SI 1 "fpr_operand" "f")))]
2554 "TARGET_HARD_FLOAT"
2555 "fitos %1,%0"
2556 [(set_attr "length" "4")
2557 (set_attr "type" "fsconv")])
2558
2559 (define_insn "floatsidf2"
2560 [(set (match_operand:DF 0 "fpr_operand" "=h")
2561 (float:DF (match_operand:SI 1 "fpr_operand" "f")))]
2562 "TARGET_HARD_FLOAT && TARGET_DOUBLE"
2563 "fitod %1,%0"
2564 [(set_attr "length" "4")
2565 (set_attr "type" "fdconv")])
2566
2567 ;;(define_insn "floatdisf2"
2568 ;; [(set (match_operand:SF 0 "register_operand" "=r")
2569 ;; (float:SF (match_operand:DI 1 "register_operand" "r")))]
2570 ;; ""
2571 ;; "floatdisf2 %0,%1"
2572 ;; [(set_attr "length" "4")])
2573 ;;
2574 ;;(define_insn "floatdidf2"
2575 ;; [(set (match_operand:DF 0 "register_operand" "=r")
2576 ;; (float:DF (match_operand:DI 1 "register_operand" "r")))]
2577 ;; ""
2578 ;; "floatdidf2 %0,%1"
2579 ;; [(set_attr "length" "4")])
2580
2581 (define_insn "fix_truncsfsi2"
2582 [(set (match_operand:SI 0 "fpr_operand" "=f")
2583 (fix:SI (match_operand:SF 1 "fpr_operand" "f")))]
2584 "TARGET_HARD_FLOAT"
2585 "fstoi %1,%0"
2586 [(set_attr "length" "4")
2587 (set_attr "type" "fsconv")])
2588
2589 (define_insn "fix_truncdfsi2"
2590 [(set (match_operand:SI 0 "fpr_operand" "=f")
2591 (fix:SI (match_operand:DF 1 "fpr_operand" "h")))]
2592 "TARGET_HARD_FLOAT && TARGET_DOUBLE"
2593 "fdtoi %1,%0"
2594 [(set_attr "length" "4")
2595 (set_attr "type" "fdconv")])
2596
2597 ;;(define_insn "fix_truncsfdi2"
2598 ;; [(set (match_operand:DI 0 "register_operand" "=r")
2599 ;; (fix:DI (match_operand:SF 1 "register_operand" "r")))]
2600 ;; ""
2601 ;; "fix_truncsfdi2 %0,%1"
2602 ;; [(set_attr "length" "4")])
2603 ;;
2604 ;;(define_insn "fix_truncdfdi2"
2605 ;; [(set (match_operand:DI 0 "register_operand" "=r")
2606 ;; (fix:DI (match_operand:DF 1 "register_operand" "r")))]
2607 ;; ""
2608 ;; "fix_truncdfdi2 %0,%1"
2609 ;; [(set_attr "length" "4")])
2610 ;;
2611 ;;;; Convert between unsigned integer types and floating point.
2612 ;;
2613 ;;(define_insn "floatunssisf2"
2614 ;; [(set (match_operand:SF 0 "register_operand" "=r")
2615 ;; (unsigned_float:SF (match_operand:SI 1 "register_operand" "r")))]
2616 ;; ""
2617 ;; "floatunssisf2 %0,%1"
2618 ;; [(set_attr "length" "4")])
2619 ;;
2620 ;;(define_insn "floatunssidf2"
2621 ;; [(set (match_operand:DF 0 "register_operand" "=r")
2622 ;; (unsigned_float:DF (match_operand:SI 1 "register_operand" "r")))]
2623 ;; ""
2624 ;; "floatunssidf2 %0,%1"
2625 ;; [(set_attr "length" "4")])
2626 ;;
2627 ;;(define_insn "floatunsdisf2"
2628 ;; [(set (match_operand:SF 0 "register_operand" "=r")
2629 ;; (unsigned_float:SF (match_operand:DI 1 "register_operand" "r")))]
2630 ;; ""
2631 ;; "floatunsdisf2 %0,%1"
2632 ;; [(set_attr "length" "4")])
2633 ;;
2634 ;;(define_insn "floatunsdidf2"
2635 ;; [(set (match_operand:DF 0 "register_operand" "=r")
2636 ;; (unsigned_float:DF (match_operand:DI 1 "register_operand" "r")))]
2637 ;; ""
2638 ;; "floatunsdidf2 %0,%1"
2639 ;; [(set_attr "length" "4")])
2640 ;;
2641 ;;(define_insn "fixuns_truncsfsi2"
2642 ;; [(set (match_operand:SI 0 "register_operand" "=r")
2643 ;; (unsigned_fix:SI (match_operand:SF 1 "register_operand" "r")))]
2644 ;; ""
2645 ;; "fixuns_truncsfsi2 %0,%1"
2646 ;; [(set_attr "length" "4")])
2647 ;;
2648 ;;(define_insn "fixuns_truncdfsi2"
2649 ;; [(set (match_operand:SI 0 "register_operand" "=r")
2650 ;; (unsigned_fix:SI (match_operand:DF 1 "register_operand" "r")))]
2651 ;; ""
2652 ;; "fixuns_truncdfsi2 %0,%1"
2653 ;; [(set_attr "length" "4")])
2654 ;;
2655 ;;(define_insn "fixuns_truncsfdi2"
2656 ;; [(set (match_operand:DI 0 "register_operand" "=r")
2657 ;; (unsigned_fix:DI (match_operand:SF 1 "register_operand" "r")))]
2658 ;; ""
2659 ;; "fixuns_truncsfdi2 %0,%1"
2660 ;; [(set_attr "length" "4")])
2661 ;;
2662 ;;(define_insn "fixuns_truncdfdi2"
2663 ;; [(set (match_operand:DI 0 "register_operand" "=r")
2664 ;; (unsigned_fix:DI (match_operand:DF 1 "register_operand" "r")))]
2665 ;; ""
2666 ;; "fixuns_truncdfdi2 %0,%1"
2667 ;; [(set_attr "length" "4")])
2668
2669 \f
2670 ;; ::::::::::::::::::::
2671 ;; ::
2672 ;; :: 32-bit Integer arithmetic
2673 ;; ::
2674 ;; ::::::::::::::::::::
2675
2676 ;; Addition
2677 (define_insn "addsi3"
2678 [(set (match_operand:SI 0 "integer_register_operand" "=d")
2679 (plus:SI (match_operand:SI 1 "integer_register_operand" "%d")
2680 (match_operand:SI 2 "gpr_or_int12_operand" "dNOPQ")))]
2681 ""
2682 "add%I2 %1,%2,%0"
2683 [(set_attr "length" "4")
2684 (set_attr "type" "int")])
2685
2686 ;; Subtraction. No need to worry about constants, since the compiler
2687 ;; canonicalizes them into addsi3's. We prevent SUBREG's here to work around a
2688 ;; combine bug, that combines the 32x32->upper 32 bit multiply that uses a
2689 ;; SUBREG with a minus that shows up in modulus by constants.
2690 (define_insn "subsi3"
2691 [(set (match_operand:SI 0 "integer_register_operand" "=d")
2692 (minus:SI (match_operand:SI 1 "gpr_no_subreg_operand" "d")
2693 (match_operand:SI 2 "gpr_no_subreg_operand" "d")))]
2694 ""
2695 "sub %1,%2,%0"
2696 [(set_attr "length" "4")
2697 (set_attr "type" "int")])
2698
2699 ;; Signed multiplication producing 64-bit results from 32-bit inputs
2700 ;; Note, frv doesn't have a 32x32->32 bit multiply, but the compiler
2701 ;; will do the 32x32->64 bit multiply and use the bottom word.
2702 (define_expand "mulsidi3"
2703 [(set (match_operand:DI 0 "integer_register_operand" "")
2704 (mult:DI (sign_extend:DI (match_operand:SI 1 "integer_register_operand" ""))
2705 (sign_extend:DI (match_operand:SI 2 "gpr_or_int12_operand" ""))))]
2706 ""
2707 "
2708 {
2709 if (GET_CODE (operands[2]) == CONST_INT)
2710 {
2711 emit_insn (gen_mulsidi3_const (operands[0], operands[1], operands[2]));
2712 DONE;
2713 }
2714 }")
2715
2716 (define_insn "*mulsidi3_reg"
2717 [(set (match_operand:DI 0 "even_gpr_operand" "=e")
2718 (mult:DI (sign_extend:DI (match_operand:SI 1 "integer_register_operand" "%d"))
2719 (sign_extend:DI (match_operand:SI 2 "integer_register_operand" "d"))))]
2720 ""
2721 "smul %1,%2,%0"
2722 [(set_attr "length" "4")
2723 (set_attr "type" "mul")])
2724
2725 (define_insn "mulsidi3_const"
2726 [(set (match_operand:DI 0 "even_gpr_operand" "=e")
2727 (mult:DI (sign_extend:DI (match_operand:SI 1 "integer_register_operand" "d"))
2728 (match_operand:SI 2 "int12_operand" "NOP")))]
2729 ""
2730 "smuli %1,%2,%0"
2731 [(set_attr "length" "4")
2732 (set_attr "type" "mul")])
2733
2734 ;; Unsigned multiplication producing 64-bit results from 32-bit inputs
2735 (define_expand "umulsidi3"
2736 [(set (match_operand:DI 0 "even_gpr_operand" "")
2737 (mult:DI (zero_extend:DI (match_operand:SI 1 "integer_register_operand" ""))
2738 (zero_extend:DI (match_operand:SI 2 "gpr_or_int12_operand" ""))))]
2739 ""
2740 "
2741 {
2742 if (GET_CODE (operands[2]) == CONST_INT)
2743 {
2744 emit_insn (gen_umulsidi3_const (operands[0], operands[1], operands[2]));
2745 DONE;
2746 }
2747 }")
2748
2749 (define_insn "*mulsidi3_reg"
2750 [(set (match_operand:DI 0 "even_gpr_operand" "=e")
2751 (mult:DI (zero_extend:DI (match_operand:SI 1 "integer_register_operand" "%d"))
2752 (zero_extend:DI (match_operand:SI 2 "integer_register_operand" "d"))))]
2753 ""
2754 "umul %1,%2,%0"
2755 [(set_attr "length" "4")
2756 (set_attr "type" "mul")])
2757
2758 (define_insn "umulsidi3_const"
2759 [(set (match_operand:DI 0 "even_gpr_operand" "=e")
2760 (mult:DI (zero_extend:DI (match_operand:SI 1 "integer_register_operand" "d"))
2761 (match_operand:SI 2 "int12_operand" "NOP")))]
2762 ""
2763 "umuli %1,%2,%0"
2764 [(set_attr "length" "4")
2765 (set_attr "type" "mul")])
2766
2767 ;; Signed Division
2768 (define_insn "divsi3"
2769 [(set (match_operand:SI 0 "register_operand" "=d,d")
2770 (div:SI (match_operand:SI 1 "register_operand" "d,d")
2771 (match_operand:SI 2 "gpr_or_int12_operand" "d,NOP")))]
2772 ""
2773 "sdiv%I2 %1,%2,%0"
2774 [(set_attr "length" "4")
2775 (set_attr "type" "div")])
2776
2777 ;; Unsigned Division
2778 (define_insn "udivsi3"
2779 [(set (match_operand:SI 0 "register_operand" "=d,d")
2780 (udiv:SI (match_operand:SI 1 "register_operand" "d,d")
2781 (match_operand:SI 2 "gpr_or_int12_operand" "d,NOP")))]
2782 ""
2783 "udiv%I2 %1,%2,%0"
2784 [(set_attr "length" "4")
2785 (set_attr "type" "div")])
2786
2787 ;; Negation
2788 (define_insn "negsi2"
2789 [(set (match_operand:SI 0 "integer_register_operand" "=d")
2790 (neg:SI (match_operand:SI 1 "integer_register_operand" "d")))]
2791 ""
2792 "sub %.,%1,%0"
2793 [(set_attr "length" "4")
2794 (set_attr "type" "int")])
2795
2796 ;; Find first one bit
2797 ;; (define_insn "ffssi2"
2798 ;; [(set (match_operand:SI 0 "register_operand" "=r")
2799 ;; (ffs:SI (match_operand:SI 1 "register_operand" "r")))]
2800 ;; ""
2801 ;; "ffssi2 %0,%1"
2802 ;; [(set_attr "length" "4")])
2803
2804 \f
2805 ;; ::::::::::::::::::::
2806 ;; ::
2807 ;; :: 64-bit Integer arithmetic
2808 ;; ::
2809 ;; ::::::::::::::::::::
2810
2811 ;; Addition
2812 (define_insn_and_split "adddi3"
2813 [(set (match_operand:DI 0 "integer_register_operand" "=&e,e")
2814 (plus:DI (match_operand:DI 1 "integer_register_operand" "%e,0")
2815 (match_operand:DI 2 "gpr_or_int10_operand" "eJ,eJ")))
2816 (clobber (match_scratch:CC 3 "=t,t"))]
2817 ""
2818 "#"
2819 "reload_completed"
2820 [(match_dup 4)
2821 (match_dup 5)]
2822 "
2823 {
2824 rtx parts[3][2];
2825 int op, part;
2826
2827 for (op = 0; op < 3; op++)
2828 for (part = 0; part < 2; part++)
2829 parts[op][part] = simplify_gen_subreg (SImode, operands[op],
2830 DImode, part * UNITS_PER_WORD);
2831
2832 operands[4] = gen_adddi3_lower (parts[0][1], parts[1][1], parts[2][1],
2833 operands[3]);
2834 operands[5] = gen_adddi3_upper (parts[0][0], parts[1][0], parts[2][0],
2835 copy_rtx (operands[3]));
2836 }"
2837 [(set_attr "length" "8")
2838 (set_attr "type" "multi")])
2839
2840 ;; Subtraction No need to worry about constants, since the compiler
2841 ;; canonicalizes them into adddi3's.
2842 (define_insn_and_split "subdi3"
2843 [(set (match_operand:DI 0 "integer_register_operand" "=&e,e,e")
2844 (minus:DI (match_operand:DI 1 "integer_register_operand" "e,0,e")
2845 (match_operand:DI 2 "integer_register_operand" "e,e,0")))
2846 (clobber (match_scratch:CC 3 "=t,t,t"))]
2847 ""
2848 "#"
2849 "reload_completed"
2850 [(match_dup 4)
2851 (match_dup 5)]
2852 "
2853 {
2854 rtx op0_high = gen_highpart (SImode, operands[0]);
2855 rtx op1_high = gen_highpart (SImode, operands[1]);
2856 rtx op2_high = gen_highpart (SImode, operands[2]);
2857 rtx op0_low = gen_lowpart (SImode, operands[0]);
2858 rtx op1_low = gen_lowpart (SImode, operands[1]);
2859 rtx op2_low = gen_lowpart (SImode, operands[2]);
2860 rtx op3 = operands[3];
2861
2862 operands[4] = gen_subdi3_lower (op0_low, op1_low, op2_low, op3);
2863 operands[5] = gen_subdi3_upper (op0_high, op1_high, op2_high, op3);
2864 }"
2865 [(set_attr "length" "8")
2866 (set_attr "type" "multi")])
2867
2868 ;; Patterns for addsi3/subdi3 after splitting
2869 (define_insn "adddi3_lower"
2870 [(set (match_operand:SI 0 "integer_register_operand" "=d")
2871 (plus:SI (match_operand:SI 1 "integer_register_operand" "d")
2872 (match_operand:SI 2 "gpr_or_int10_operand" "dJ")))
2873 (set (match_operand:CC 3 "icc_operand" "=t")
2874 (compare:CC (plus:SI (match_dup 1)
2875 (match_dup 2))
2876 (const_int 0)))]
2877 ""
2878 "add%I2cc %1,%2,%0,%3"
2879 [(set_attr "length" "4")
2880 (set_attr "type" "int")])
2881
2882 (define_insn "adddi3_upper"
2883 [(set (match_operand:SI 0 "integer_register_operand" "=d")
2884 (plus:SI (match_operand:SI 1 "integer_register_operand" "d")
2885 (plus:SI (match_operand:SI 2 "gpr_or_int10_operand" "dJ")
2886 (match_operand:CC 3 "icc_operand" "t"))))]
2887 ""
2888 "addx%I2 %1,%2,%0,%3"
2889 [(set_attr "length" "4")
2890 (set_attr "type" "int")])
2891
2892 (define_insn "subdi3_lower"
2893 [(set (match_operand:SI 0 "integer_register_operand" "=d")
2894 (minus:SI (match_operand:SI 1 "integer_register_operand" "d")
2895 (match_operand:SI 2 "integer_register_operand" "d")))
2896 (set (match_operand:CC 3 "icc_operand" "=t")
2897 (compare:CC (plus:SI (match_dup 1)
2898 (match_dup 2))
2899 (const_int 0)))]
2900 ""
2901 "subcc %1,%2,%0,%3"
2902 [(set_attr "length" "4")
2903 (set_attr "type" "int")])
2904
2905 (define_insn "subdi3_upper"
2906 [(set (match_operand:SI 0 "integer_register_operand" "=d")
2907 (minus:SI (match_operand:SI 1 "integer_register_operand" "d")
2908 (minus:SI (match_operand:SI 2 "integer_register_operand" "d")
2909 (match_operand:CC 3 "icc_operand" "t"))))]
2910 ""
2911 "subx %1,%2,%0,%3"
2912 [(set_attr "length" "4")
2913 (set_attr "type" "int")])
2914
2915 (define_insn_and_split "negdi2"
2916 [(set (match_operand:DI 0 "integer_register_operand" "=&e,e")
2917 (neg:DI (match_operand:DI 1 "integer_register_operand" "e,0")))
2918 (clobber (match_scratch:CC 2 "=t,t"))]
2919 ""
2920 "#"
2921 "reload_completed"
2922 [(match_dup 3)
2923 (match_dup 4)]
2924 "
2925 {
2926 rtx op0_high = gen_highpart (SImode, operands[0]);
2927 rtx op1_high = gen_rtx_REG (SImode, GPR_FIRST);
2928 rtx op2_high = gen_highpart (SImode, operands[1]);
2929 rtx op0_low = gen_lowpart (SImode, operands[0]);
2930 rtx op1_low = op1_high;
2931 rtx op2_low = gen_lowpart (SImode, operands[1]);
2932 rtx op3 = operands[2];
2933
2934 operands[3] = gen_subdi3_lower (op0_low, op1_low, op2_low, op3);
2935 operands[4] = gen_subdi3_upper (op0_high, op1_high, op2_high, op3);
2936 }"
2937 [(set_attr "length" "8")
2938 (set_attr "type" "multi")])
2939
2940 ;; Multiplication (same size)
2941 ;; (define_insn "muldi3"
2942 ;; [(set (match_operand:DI 0 "register_operand" "=r")
2943 ;; (mult:DI (match_operand:DI 1 "register_operand" "%r")
2944 ;; (match_operand:DI 2 "nonmemory_operand" "ri")))]
2945 ;; ""
2946 ;; "muldi3 %0,%1,%2"
2947 ;; [(set_attr "length" "4")])
2948
2949 ;; Signed Division
2950 ;; (define_insn "divdi3"
2951 ;; [(set (match_operand:DI 0 "register_operand" "=r")
2952 ;; (div:DI (match_operand:DI 1 "register_operand" "r")
2953 ;; (match_operand:DI 2 "nonmemory_operand" "ri")))]
2954 ;; ""
2955 ;; "divdi3 %0,%1,%2"
2956 ;; [(set_attr "length" "4")])
2957
2958 ;; Undsgned Division
2959 ;; (define_insn "udivdi3"
2960 ;; [(set (match_operand:DI 0 "register_operand" "=r")
2961 ;; (udiv:DI (match_operand:DI 1 "register_operand" "r")
2962 ;; (match_operand:DI 2 "nonmemory_operand" "ri")))]
2963 ;; ""
2964 ;; "udivdi3 %0,%1,%2"
2965 ;; [(set_attr "length" "4")])
2966
2967 ;; Negation
2968 ;; (define_insn "negdi2"
2969 ;; [(set (match_operand:DI 0 "register_operand" "=r")
2970 ;; (neg:DI (match_operand:DI 1 "register_operand" "r")))]
2971 ;; ""
2972 ;; "negdi2 %0,%1"
2973 ;; [(set_attr "length" "4")])
2974
2975 ;; Find first one bit
2976 ;; (define_insn "ffsdi2"
2977 ;; [(set (match_operand:DI 0 "register_operand" "=r")
2978 ;; (ffs:DI (match_operand:DI 1 "register_operand" "r")))]
2979 ;; ""
2980 ;; "ffsdi2 %0,%1"
2981 ;; [(set_attr "length" "4")])
2982
2983 \f
2984 ;; ::::::::::::::::::::
2985 ;; ::
2986 ;; :: 32-bit floating point arithmetic
2987 ;; ::
2988 ;; ::::::::::::::::::::
2989
2990 ;; Addition
2991 (define_insn "addsf3"
2992 [(set (match_operand:SF 0 "fpr_operand" "=f")
2993 (plus:SF (match_operand:SF 1 "fpr_operand" "%f")
2994 (match_operand:SF 2 "fpr_operand" "f")))]
2995 "TARGET_HARD_FLOAT"
2996 "fadds %1,%2,%0"
2997 [(set_attr "length" "4")
2998 (set_attr "type" "fsadd")])
2999
3000 ;; Subtraction
3001 (define_insn "subsf3"
3002 [(set (match_operand:SF 0 "fpr_operand" "=f")
3003 (minus:SF (match_operand:SF 1 "fpr_operand" "f")
3004 (match_operand:SF 2 "fpr_operand" "f")))]
3005 "TARGET_HARD_FLOAT"
3006 "fsubs %1,%2,%0"
3007 [(set_attr "length" "4")
3008 (set_attr "type" "fsadd")])
3009
3010 ;; Multiplication
3011 (define_insn "mulsf3"
3012 [(set (match_operand:SF 0 "fpr_operand" "=f")
3013 (mult:SF (match_operand:SF 1 "fpr_operand" "%f")
3014 (match_operand:SF 2 "fpr_operand" "f")))]
3015 "TARGET_HARD_FLOAT"
3016 "fmuls %1,%2,%0"
3017 [(set_attr "length" "4")
3018 (set_attr "type" "fsmul")])
3019
3020 ;; Multiplication with addition/subtraction
3021 (define_insn "fmasf4"
3022 [(set (match_operand:SF 0 "fpr_operand" "=f")
3023 (fma:SF (match_operand:SF 1 "fpr_operand" "f")
3024 (match_operand:SF 2 "fpr_operand" "f")
3025 (match_operand:SF 3 "fpr_operand" "0")))]
3026 "TARGET_HARD_FLOAT && TARGET_MULADD"
3027 "fmadds %1,%2,%0"
3028 [(set_attr "length" "4")
3029 (set_attr "type" "fsmadd")])
3030
3031 (define_insn "fmssf4"
3032 [(set (match_operand:SF 0 "fpr_operand" "=f")
3033 (fma:SF (match_operand:SF 1 "fpr_operand" "f")
3034 (match_operand:SF 2 "fpr_operand" "f")
3035 (neg:SF (match_operand:SF 3 "fpr_operand" "0"))))]
3036 "TARGET_HARD_FLOAT && TARGET_MULADD"
3037 "fmsubs %1,%2,%0"
3038 [(set_attr "length" "4")
3039 (set_attr "type" "fsmadd")])
3040
3041 ;; Division
3042 (define_insn "divsf3"
3043 [(set (match_operand:SF 0 "fpr_operand" "=f")
3044 (div:SF (match_operand:SF 1 "fpr_operand" "f")
3045 (match_operand:SF 2 "fpr_operand" "f")))]
3046 "TARGET_HARD_FLOAT"
3047 "fdivs %1,%2,%0"
3048 [(set_attr "length" "4")
3049 (set_attr "type" "fsdiv")])
3050
3051 ;; Negation
3052 (define_insn "negsf2"
3053 [(set (match_operand:SF 0 "fpr_operand" "=f")
3054 (neg:SF (match_operand:SF 1 "fpr_operand" "f")))]
3055 "TARGET_HARD_FLOAT"
3056 "fnegs %1,%0"
3057 [(set_attr "length" "4")
3058 (set_attr "type" "fsconv")])
3059
3060 ;; Absolute value
3061 (define_insn "abssf2"
3062 [(set (match_operand:SF 0 "fpr_operand" "=f")
3063 (abs:SF (match_operand:SF 1 "fpr_operand" "f")))]
3064 "TARGET_HARD_FLOAT"
3065 "fabss %1,%0"
3066 [(set_attr "length" "4")
3067 (set_attr "type" "fsconv")])
3068
3069 ;; Square root
3070 (define_insn "sqrtsf2"
3071 [(set (match_operand:SF 0 "fpr_operand" "=f")
3072 (sqrt:SF (match_operand:SF 1 "fpr_operand" "f")))]
3073 "TARGET_HARD_FLOAT"
3074 "fsqrts %1,%0"
3075 [(set_attr "length" "4")
3076 (set_attr "type" "sqrt_single")])
3077
3078 \f
3079 ;; ::::::::::::::::::::
3080 ;; ::
3081 ;; :: 64-bit floating point arithmetic
3082 ;; ::
3083 ;; ::::::::::::::::::::
3084
3085 ;; Addition
3086 (define_insn "adddf3"
3087 [(set (match_operand:DF 0 "even_fpr_operand" "=h")
3088 (plus:DF (match_operand:DF 1 "fpr_operand" "%h")
3089 (match_operand:DF 2 "fpr_operand" "h")))]
3090 "TARGET_HARD_FLOAT && TARGET_DOUBLE"
3091 "faddd %1,%2,%0"
3092 [(set_attr "length" "4")
3093 (set_attr "type" "fdadd")])
3094
3095 ;; Subtraction
3096 (define_insn "subdf3"
3097 [(set (match_operand:DF 0 "even_fpr_operand" "=h")
3098 (minus:DF (match_operand:DF 1 "fpr_operand" "h")
3099 (match_operand:DF 2 "fpr_operand" "h")))]
3100 "TARGET_HARD_FLOAT && TARGET_DOUBLE"
3101 "fsubd %1,%2,%0"
3102 [(set_attr "length" "4")
3103 (set_attr "type" "fdadd")])
3104
3105 ;; Multiplication
3106 (define_insn "muldf3"
3107 [(set (match_operand:DF 0 "even_fpr_operand" "=h")
3108 (mult:DF (match_operand:DF 1 "fpr_operand" "%h")
3109 (match_operand:DF 2 "fpr_operand" "h")))]
3110 "TARGET_HARD_FLOAT && TARGET_DOUBLE"
3111 "fmuld %1,%2,%0"
3112 [(set_attr "length" "4")
3113 (set_attr "type" "fdmul")])
3114
3115 ;; Multiplication with addition/subtraction
3116 (define_insn "*muladddf4"
3117 [(set (match_operand:DF 0 "fpr_operand" "=f")
3118 (plus:DF (mult:DF (match_operand:DF 1 "fpr_operand" "%f")
3119 (match_operand:DF 2 "fpr_operand" "f"))
3120 (match_operand:DF 3 "fpr_operand" "0")))]
3121 "TARGET_HARD_FLOAT && TARGET_DOUBLE && TARGET_MULADD"
3122 "fmaddd %1,%2,%0"
3123 [(set_attr "length" "4")
3124 (set_attr "type" "fdmadd")])
3125
3126 (define_insn "*mulsubdf4"
3127 [(set (match_operand:DF 0 "fpr_operand" "=f")
3128 (minus:DF (mult:DF (match_operand:DF 1 "fpr_operand" "%f")
3129 (match_operand:DF 2 "fpr_operand" "f"))
3130 (match_operand:DF 3 "fpr_operand" "0")))]
3131 "TARGET_HARD_FLOAT && TARGET_DOUBLE && TARGET_MULADD"
3132 "fmsubd %1,%2,%0"
3133 [(set_attr "length" "4")
3134 (set_attr "type" "fdmadd")])
3135
3136 ;; Division
3137 (define_insn "divdf3"
3138 [(set (match_operand:DF 0 "even_fpr_operand" "=h")
3139 (div:DF (match_operand:DF 1 "fpr_operand" "h")
3140 (match_operand:DF 2 "fpr_operand" "h")))]
3141 "TARGET_HARD_FLOAT && TARGET_DOUBLE"
3142 "fdivd %1,%2,%0"
3143 [(set_attr "length" "4")
3144 (set_attr "type" "fddiv")])
3145
3146 ;; Negation
3147 (define_insn "negdf2"
3148 [(set (match_operand:DF 0 "even_fpr_operand" "=h")
3149 (neg:DF (match_operand:DF 1 "fpr_operand" "h")))]
3150 "TARGET_HARD_FLOAT && TARGET_DOUBLE"
3151 "fnegd %1,%0"
3152 [(set_attr "length" "4")
3153 (set_attr "type" "fdconv")])
3154
3155 ;; Absolute value
3156 (define_insn "absdf2"
3157 [(set (match_operand:DF 0 "even_fpr_operand" "=h")
3158 (abs:DF (match_operand:DF 1 "fpr_operand" "h")))]
3159 "TARGET_HARD_FLOAT && TARGET_DOUBLE"
3160 "fabsd %1,%0"
3161 [(set_attr "length" "4")
3162 (set_attr "type" "fdconv")])
3163
3164 ;; Square root
3165 (define_insn "sqrtdf2"
3166 [(set (match_operand:DF 0 "even_fpr_operand" "=h")
3167 (sqrt:DF (match_operand:DF 1 "fpr_operand" "h")))]
3168 "TARGET_HARD_FLOAT && TARGET_DOUBLE"
3169 "fsqrtd %1,%0"
3170 [(set_attr "length" "4")
3171 (set_attr "type" "sqrt_double")])
3172
3173 \f
3174 ;; ::::::::::::::::::::
3175 ;; ::
3176 ;; :: 32-bit Integer Shifts and Rotates
3177 ;; ::
3178 ;; ::::::::::::::::::::
3179
3180 ;; Arithmetic Shift Left
3181 (define_insn "ashlsi3"
3182 [(set (match_operand:SI 0 "integer_register_operand" "=d,d")
3183 (ashift:SI (match_operand:SI 1 "integer_register_operand" "d,d")
3184 (match_operand:SI 2 "gpr_or_int12_operand" "d,NOP")))]
3185 ""
3186 "sll%I2 %1,%2,%0"
3187 [(set_attr "length" "4")
3188 (set_attr "type" "int")])
3189
3190 ;; Arithmetic Shift Right
3191 (define_insn "ashrsi3"
3192 [(set (match_operand:SI 0 "integer_register_operand" "=d,d")
3193 (ashiftrt:SI (match_operand:SI 1 "integer_register_operand" "d,d")
3194 (match_operand:SI 2 "gpr_or_int12_operand" "d,NOP")))]
3195 ""
3196 "sra%I2 %1, %2, %0"
3197 [(set_attr "length" "4")
3198 (set_attr "type" "int")])
3199
3200 ;; Logical Shift Right
3201 (define_insn "lshrsi3"
3202 [(set (match_operand:SI 0 "integer_register_operand" "=d,d")
3203 (lshiftrt:SI (match_operand:SI 1 "integer_register_operand" "d,d")
3204 (match_operand:SI 2 "gpr_or_int12_operand" "d,NOP")))]
3205 ""
3206 "srl%I2 %1, %2, %0"
3207 [(set_attr "length" "4")
3208 (set_attr "type" "int")])
3209
3210 ;; Rotate Left
3211 ;; (define_insn "rotlsi3"
3212 ;; [(set (match_operand:SI 0 "register_operand" "=r")
3213 ;; (rotate:SI (match_operand:SI 1 "register_operand" "r")
3214 ;; (match_operand:SI 2 "nonmemory_operand" "ri")))]
3215 ;; ""
3216 ;; "rotlsi3 %0,%1,%2"
3217 ;; [(set_attr "length" "4")])
3218
3219 ;; Rotate Right
3220 ;; (define_insn "rotrsi3"
3221 ;; [(set (match_operand:SI 0 "register_operand" "=r")
3222 ;; (rotatert:SI (match_operand:SI 1 "register_operand" "r")
3223 ;; (match_operand:SI 2 "nonmemory_operand" "ri")))]
3224 ;; ""
3225 ;; "rotrsi3 %0,%1,%2"
3226 ;; [(set_attr "length" "4")])
3227
3228 \f
3229 ;; ::::::::::::::::::::
3230 ;; ::
3231 ;; :: 64-bit Integer Shifts and Rotates
3232 ;; ::
3233 ;; ::::::::::::::::::::
3234
3235 ;; Arithmetic Shift Left
3236 ;; (define_insn "ashldi3"
3237 ;; [(set (match_operand:DI 0 "register_operand" "=r")
3238 ;; (ashift:DI (match_operand:DI 1 "register_operand" "r")
3239 ;; (match_operand:SI 2 "nonmemory_operand" "ri")))]
3240 ;; ""
3241 ;; "ashldi3 %0,%1,%2"
3242 ;; [(set_attr "length" "4")])
3243
3244 ;; Arithmetic Shift Right
3245 ;; (define_insn "ashrdi3"
3246 ;; [(set (match_operand:DI 0 "register_operand" "=r")
3247 ;; (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
3248 ;; (match_operand:SI 2 "nonmemory_operand" "ri")))]
3249 ;; ""
3250 ;; "ashrdi3 %0,%1,%2"
3251 ;; [(set_attr "length" "4")])
3252
3253 ;; Logical Shift Right
3254 ;; (define_insn "lshrdi3"
3255 ;; [(set (match_operand:DI 0 "register_operand" "=r")
3256 ;; (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
3257 ;; (match_operand:SI 2 "nonmemory_operand" "ri")))]
3258 ;; ""
3259 ;; "lshrdi3 %0,%1,%2"
3260 ;; [(set_attr "length" "4")])
3261
3262 ;; Rotate Left
3263 ;; (define_insn "rotldi3"
3264 ;; [(set (match_operand:DI 0 "register_operand" "=r")
3265 ;; (rotate:DI (match_operand:DI 1 "register_operand" "r")
3266 ;; (match_operand:SI 2 "nonmemory_operand" "ri")))]
3267 ;; ""
3268 ;; "rotldi3 %0,%1,%2"
3269 ;; [(set_attr "length" "4")])
3270
3271 ;; Rotate Right
3272 ;; (define_insn "rotrdi3"
3273 ;; [(set (match_operand:DI 0 "register_operand" "=r")
3274 ;; (rotatert:DI (match_operand:DI 1 "register_operand" "r")
3275 ;; (match_operand:SI 2 "nonmemory_operand" "ri")))]
3276 ;; ""
3277 ;; "rotrdi3 %0,%1,%2"
3278 ;; [(set_attr "length" "4")])
3279
3280 \f
3281 ;; ::::::::::::::::::::
3282 ;; ::
3283 ;; :: 32-Bit Integer Logical operations
3284 ;; ::
3285 ;; ::::::::::::::::::::
3286
3287 ;; Logical AND, 32-bit integers
3288 (define_insn "andsi3_media"
3289 [(set (match_operand:SI 0 "gpr_or_fpr_operand" "=d,f")
3290 (and:SI (match_operand:SI 1 "gpr_or_fpr_operand" "%d,f")
3291 (match_operand:SI 2 "gpr_fpr_or_int12_operand" "dNOP,f")))]
3292 "TARGET_MEDIA"
3293 "@
3294 and%I2 %1, %2, %0
3295 mand %1, %2, %0"
3296 [(set_attr "length" "4")
3297 (set_attr "type" "int,mlogic")])
3298
3299 (define_insn "andsi3_nomedia"
3300 [(set (match_operand:SI 0 "integer_register_operand" "=d")
3301 (and:SI (match_operand:SI 1 "integer_register_operand" "%d")
3302 (match_operand:SI 2 "gpr_or_int12_operand" "dNOP")))]
3303 "!TARGET_MEDIA"
3304 "and%I2 %1, %2, %0"
3305 [(set_attr "length" "4")
3306 (set_attr "type" "int")])
3307
3308 (define_expand "andsi3"
3309 [(set (match_operand:SI 0 "gpr_or_fpr_operand" "")
3310 (and:SI (match_operand:SI 1 "gpr_or_fpr_operand" "")
3311 (match_operand:SI 2 "gpr_fpr_or_int12_operand" "")))]
3312 ""
3313 "")
3314
3315 ;; Inclusive OR, 32-bit integers
3316 (define_insn "iorsi3_media"
3317 [(set (match_operand:SI 0 "gpr_or_fpr_operand" "=d,f")
3318 (ior:SI (match_operand:SI 1 "gpr_or_fpr_operand" "%d,f")
3319 (match_operand:SI 2 "gpr_fpr_or_int12_operand" "dNOP,f")))]
3320 "TARGET_MEDIA"
3321 "@
3322 or%I2 %1, %2, %0
3323 mor %1, %2, %0"
3324 [(set_attr "length" "4")
3325 (set_attr "type" "int,mlogic")])
3326
3327 (define_insn "iorsi3_nomedia"
3328 [(set (match_operand:SI 0 "integer_register_operand" "=d")
3329 (ior:SI (match_operand:SI 1 "integer_register_operand" "%d")
3330 (match_operand:SI 2 "gpr_or_int12_operand" "dNOP")))]
3331 "!TARGET_MEDIA"
3332 "or%I2 %1, %2, %0"
3333 [(set_attr "length" "4")
3334 (set_attr "type" "int")])
3335
3336 (define_expand "iorsi3"
3337 [(set (match_operand:SI 0 "gpr_or_fpr_operand" "")
3338 (ior:SI (match_operand:SI 1 "gpr_or_fpr_operand" "")
3339 (match_operand:SI 2 "gpr_fpr_or_int12_operand" "")))]
3340 ""
3341 "")
3342
3343 ;; Exclusive OR, 32-bit integers
3344 (define_insn "xorsi3_media"
3345 [(set (match_operand:SI 0 "gpr_or_fpr_operand" "=d,f")
3346 (xor:SI (match_operand:SI 1 "gpr_or_fpr_operand" "%d,f")
3347 (match_operand:SI 2 "gpr_fpr_or_int12_operand" "dNOP,f")))]
3348 "TARGET_MEDIA"
3349 "@
3350 xor%I2 %1, %2, %0
3351 mxor %1, %2, %0"
3352 [(set_attr "length" "4")
3353 (set_attr "type" "int,mlogic")])
3354
3355 (define_insn "xorsi3_nomedia"
3356 [(set (match_operand:SI 0 "integer_register_operand" "=d")
3357 (xor:SI (match_operand:SI 1 "integer_register_operand" "%d")
3358 (match_operand:SI 2 "gpr_or_int12_operand" "dNOP")))]
3359 "!TARGET_MEDIA"
3360 "xor%I2 %1, %2, %0"
3361 [(set_attr "length" "4")
3362 (set_attr "type" "int")])
3363
3364 (define_expand "xorsi3"
3365 [(set (match_operand:SI 0 "gpr_or_fpr_operand" "")
3366 (xor:SI (match_operand:SI 1 "gpr_or_fpr_operand" "")
3367 (match_operand:SI 2 "gpr_fpr_or_int12_operand" "")))]
3368 ""
3369 "")
3370
3371 ;; One's complement, 32-bit integers
3372 (define_insn "one_cmplsi2_media"
3373 [(set (match_operand:SI 0 "gpr_or_fpr_operand" "=d,f")
3374 (not:SI (match_operand:SI 1 "gpr_or_fpr_operand" "d,f")))]
3375 "TARGET_MEDIA"
3376 "@
3377 not %1, %0
3378 mnot %1, %0"
3379 [(set_attr "length" "4")
3380 (set_attr "type" "int,mlogic")])
3381
3382 (define_insn "one_cmplsi2_nomedia"
3383 [(set (match_operand:SI 0 "integer_register_operand" "=d")
3384 (not:SI (match_operand:SI 1 "integer_register_operand" "d")))]
3385 "!TARGET_MEDIA"
3386 "not %1,%0"
3387 [(set_attr "length" "4")
3388 (set_attr "type" "int")])
3389
3390 (define_expand "one_cmplsi2"
3391 [(set (match_operand:SI 0 "gpr_or_fpr_operand" "")
3392 (not:SI (match_operand:SI 1 "gpr_or_fpr_operand" "")))]
3393 ""
3394 "")
3395
3396 \f
3397 ;; ::::::::::::::::::::
3398 ;; ::
3399 ;; :: 64-Bit Integer Logical operations
3400 ;; ::
3401 ;; ::::::::::::::::::::
3402
3403 ;; Logical AND, 64-bit integers
3404 ;; (define_insn "anddi3"
3405 ;; [(set (match_operand:DI 0 "register_operand" "=r")
3406 ;; (and:DI (match_operand:DI 1 "register_operand" "%r")
3407 ;; (match_operand:DI 2 "nonmemory_operand" "ri")))]
3408 ;; ""
3409 ;; "anddi3 %0,%1,%2"
3410 ;; [(set_attr "length" "4")])
3411
3412 ;; Inclusive OR, 64-bit integers
3413 ;; (define_insn "iordi3"
3414 ;; [(set (match_operand:DI 0 "register_operand" "=r")
3415 ;; (ior:DI (match_operand:DI 1 "register_operand" "%r")
3416 ;; (match_operand:DI 2 "nonmemory_operand" "ri")))]
3417 ;; ""
3418 ;; "iordi3 %0,%1,%2"
3419 ;; [(set_attr "length" "4")])
3420
3421 ;; Exclusive OR, 64-bit integers
3422 ;; (define_insn "xordi3"
3423 ;; [(set (match_operand:DI 0 "register_operand" "=r")
3424 ;; (xor:DI (match_operand:DI 1 "register_operand" "%r")
3425 ;; (match_operand:DI 2 "nonmemory_operand" "ri")))]
3426 ;; ""
3427 ;; "xordi3 %0,%1,%2"
3428 ;; [(set_attr "length" "4")])
3429
3430 ;; One's complement, 64-bit integers
3431 ;; (define_insn "one_cmpldi2"
3432 ;; [(set (match_operand:DI 0 "register_operand" "=r")
3433 ;; (not:DI (match_operand:DI 1 "register_operand" "r")))]
3434 ;; ""
3435 ;; "notdi3 %0,%1"
3436 ;; [(set_attr "length" "4")])
3437
3438 \f
3439 ;; ::::::::::::::::::::
3440 ;; ::
3441 ;; :: Combination of integer operation with comparison
3442 ;; ::
3443 ;; ::::::::::::::::::::
3444
3445 (define_insn "*combo_intop_compare1"
3446 [(set (match_operand:CC_NZ 0 "icc_operand" "=t")
3447 (compare:CC_NZ
3448 (match_operator:SI 1 "intop_compare_operator"
3449 [(match_operand:SI 2 "integer_register_operand" "d")
3450 (match_operand:SI 3 "gpr_or_int10_operand" "dJ")])
3451 (const_int 0)))]
3452 ""
3453 "%O1%I3cc %2, %3, %., %0"
3454 [(set_attr "type" "int")
3455 (set_attr "length" "4")])
3456
3457 (define_insn "*combo_intop_compare2"
3458 [(set (match_operand:CC_NZ 0 "icc_operand" "=t")
3459 (compare:CC_NZ
3460 (match_operator:SI 1 "intop_compare_operator"
3461 [(match_operand:SI 2 "integer_register_operand" "d")
3462 (match_operand:SI 3 "gpr_or_int10_operand" "dJ")])
3463 (const_int 0)))
3464 (set (match_operand:SI 4 "integer_register_operand" "=d")
3465 (match_operator:SI 5 "intop_compare_operator"
3466 [(match_dup 2)
3467 (match_dup 3)]))]
3468 "GET_CODE (operands[1]) == GET_CODE (operands[5])"
3469 "%O1%I3cc %2, %3, %4, %0"
3470 [(set_attr "type" "int")
3471 (set_attr "length" "4")])
3472 \f
3473 ;; ::::::::::::::::::::
3474 ;; ::
3475 ;; :: Comparisons
3476 ;; ::
3477 ;; ::::::::::::::::::::
3478
3479 ;; The comparisons are generated by the branch and/or scc operations
3480
3481 (define_insn "cmpsi_cc"
3482 [(set (match_operand:CC 0 "icc_operand" "=t,t")
3483 (compare:CC (match_operand:SI 1 "integer_register_operand" "d,d")
3484 (match_operand:SI 2 "gpr_or_int10_operand" "d,J")))]
3485 ""
3486 "cmp%I2 %1,%2,%0"
3487 [(set_attr "length" "4")
3488 (set_attr "type" "int")])
3489
3490 (define_insn "*cmpsi_cc_uns"
3491 [(set (match_operand:CC_UNS 0 "icc_operand" "=t,t")
3492 (compare:CC_UNS (match_operand:SI 1 "integer_register_operand" "d,d")
3493 (match_operand:SI 2 "gpr_or_int10_operand" "d,J")))]
3494 ""
3495 "cmp%I2 %1,%2,%0"
3496 [(set_attr "length" "4")
3497 (set_attr "type" "int")])
3498
3499 ;; The only requirement for a CC_NZmode GPR or memory value is that
3500 ;; comparing it against zero must set the Z and N flags appropriately.
3501 ;; The source operand is therefore a valid CC_NZmode value.
3502 (define_insn "*cmpsi_cc_nz"
3503 [(set (match_operand:CC_NZ 0 "nonimmediate_operand" "=t,d,m")
3504 (compare:CC_NZ (match_operand:SI 1 "integer_register_operand" "d,d,d")
3505 (const_int 0)))]
3506 ""
3507 "@
3508 cmpi %1, #0, %0
3509 mov %1, %0
3510 st%I0%U0 %1, %M0"
3511 [(set_attr "length" "4,4,4")
3512 (set_attr "type" "int,int,gstore")])
3513
3514 (define_insn "*cmpsf_cc_fp"
3515 [(set (match_operand:CC_FP 0 "fcc_operand" "=u")
3516 (compare:CC_FP (match_operand:SF 1 "fpr_operand" "f")
3517 (match_operand:SF 2 "fpr_operand" "f")))]
3518 "TARGET_HARD_FLOAT"
3519 "fcmps %1,%2,%0"
3520 [(set_attr "length" "4")
3521 (set_attr "type" "fscmp")])
3522
3523 (define_insn "*cmpdf_cc_fp"
3524 [(set (match_operand:CC_FP 0 "fcc_operand" "=u")
3525 (compare:CC_FP (match_operand:DF 1 "even_fpr_operand" "h")
3526 (match_operand:DF 2 "even_fpr_operand" "h")))]
3527 "TARGET_HARD_FLOAT && TARGET_DOUBLE"
3528 "fcmpd %1,%2,%0"
3529 [(set_attr "length" "4")
3530 (set_attr "type" "fdcmp")])
3531
3532 \f
3533 ;; ::::::::::::::::::::
3534 ;; ::
3535 ;; :: Branches
3536 ;; ::
3537 ;; ::::::::::::::::::::
3538
3539 ;; Define_expands called by the machine independent part of the compiler
3540 ;; to allocate a new comparison register.
3541
3542 (define_expand "cbranchdf4"
3543 [(use (match_operator 0 "ordered_comparison_operator"
3544 [(match_operand:DF 1 "fpr_operand" "")
3545 (match_operand:DF 2 "fpr_operand" "")]))
3546 (use (match_operand 3 ""))]
3547 "TARGET_HARD_FLOAT && TARGET_DOUBLE"
3548 { if (frv_emit_cond_branch (operands)) DONE; gcc_unreachable (); })
3549
3550 (define_expand "cbranchsf4"
3551 [(use (match_operator 0 "ordered_comparison_operator"
3552 [(match_operand:SF 1 "fpr_operand" "")
3553 (match_operand:SF 2 "fpr_operand" "")]))
3554 (use (match_operand 3 ""))]
3555 "TARGET_HARD_FLOAT"
3556 { if (frv_emit_cond_branch (operands)) DONE; gcc_unreachable (); })
3557
3558 (define_expand "cbranchsi4"
3559 [(use (match_operator 0 "ordered_comparison_operator"
3560 [(match_operand:SI 1 "integer_register_operand" "")
3561 (match_operand:SI 2 "gpr_or_int10_operand" "")]))
3562 (use (match_operand 3 ""))]
3563 ""
3564 { if (frv_emit_cond_branch (operands)) DONE; gcc_unreachable (); })
3565
3566 ;; Actual branches. We must allow for the (label_ref) and the (pc) to be
3567 ;; swapped. If they are swapped, it reverses the sense of the branch.
3568 ;;
3569 ;; Note - unlike the define expands above, these patterns can be amalgamated
3570 ;; into one pattern for branch-if-true and one for branch-if-false. This does
3571 ;; require an operand operator to select the correct branch mnemonic.
3572 ;;
3573 ;; If a fixed condition code register is being used, (as opposed to, say,
3574 ;; using cc0), then the expands could look like this:
3575 ;;
3576 ;; (define_insn "*branch_true"
3577 ;; [(set (pc)
3578 ;; (if_then_else (match_operator:CC 0 "comparison_operator"
3579 ;; [(reg:CC <number_of_CC_register>)
3580 ;; (const_int 0)])
3581 ;; (label_ref (match_operand 1 "" ""))
3582 ;; (pc)))]
3583 ;; ""
3584 ;; "b%B0 %1"
3585 ;; [(set_attr "length" "4")]
3586 ;; )
3587 ;;
3588 ;; In the above example the %B is a directive to frv_print_operand()
3589 ;; to decode and print the correct branch mnemonic.
3590
3591 (define_insn "*branch_int_true"
3592 [(set (pc)
3593 (if_then_else (match_operator 0 "integer_relational_operator"
3594 [(match_operand 1 "icc_operand" "t")
3595 (const_int 0)])
3596 (label_ref (match_operand 2 "" ""))
3597 (pc)))]
3598 ""
3599 "*
3600 {
3601 if (get_attr_length (insn) == 4)
3602 return \"b%c0 %1,%#,%l2\";
3603 else
3604 return \"b%C0 %1,%#,1f\;call %l2\\n1:\";
3605 }"
3606 [(set (attr "length")
3607 (if_then_else
3608 (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
3609 (le (minus (match_dup 2) (pc)) (const_int 32764)))
3610 (const_int 4)
3611 (const_int 8)))
3612 (set (attr "far_jump")
3613 (if_then_else
3614 (eq_attr "length" "4")
3615 (const_string "no")
3616 (const_string "yes")))
3617 (set (attr "type")
3618 (if_then_else
3619 (eq_attr "length" "4")
3620 (const_string "branch")
3621 (const_string "multi")))])
3622
3623 (define_insn "*branch_int_false"
3624 [(set (pc)
3625 (if_then_else (match_operator 0 "integer_relational_operator"
3626 [(match_operand 1 "icc_operand" "t")
3627 (const_int 0)])
3628 (pc)
3629 (label_ref (match_operand 2 "" ""))))]
3630 ""
3631 "*
3632 {
3633 if (get_attr_length (insn) == 4)
3634 return \"b%C0 %1,%#,%l2\";
3635 else
3636 return \"b%c0 %1,%#,1f\;call %l2\\n1:\";
3637 }"
3638 [(set (attr "length")
3639 (if_then_else
3640 (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
3641 (le (minus (match_dup 2) (pc)) (const_int 32764)))
3642 (const_int 4)
3643 (const_int 8)))
3644 (set (attr "far_jump")
3645 (if_then_else
3646 (eq_attr "length" "4")
3647 (const_string "no")
3648 (const_string "yes")))
3649 (set (attr "type")
3650 (if_then_else
3651 (eq_attr "length" "4")
3652 (const_string "branch")
3653 (const_string "multi")))])
3654
3655 (define_insn "*branch_fp_true"
3656 [(set (pc)
3657 (if_then_else (match_operator:CC_FP 0 "float_relational_operator"
3658 [(match_operand 1 "fcc_operand" "u")
3659 (const_int 0)])
3660 (label_ref (match_operand 2 "" ""))
3661 (pc)))]
3662 ""
3663 "*
3664 {
3665 if (get_attr_length (insn) == 4)
3666 return \"fb%f0 %1,%#,%l2\";
3667 else
3668 return \"fb%F0 %1,%#,1f\;call %l2\\n1:\";
3669 }"
3670 [(set (attr "length")
3671 (if_then_else
3672 (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
3673 (le (minus (match_dup 2) (pc)) (const_int 32764)))
3674 (const_int 4)
3675 (const_int 8)))
3676 (set (attr "far_jump")
3677 (if_then_else
3678 (eq_attr "length" "4")
3679 (const_string "no")
3680 (const_string "yes")))
3681 (set (attr "type")
3682 (if_then_else
3683 (eq_attr "length" "4")
3684 (const_string "branch")
3685 (const_string "multi")))])
3686
3687 (define_insn "*branch_fp_false"
3688 [(set (pc)
3689 (if_then_else (match_operator:CC_FP 0 "float_relational_operator"
3690 [(match_operand 1 "fcc_operand" "u")
3691 (const_int 0)])
3692 (pc)
3693 (label_ref (match_operand 2 "" ""))))]
3694 ""
3695 "*
3696 {
3697 if (get_attr_length (insn) == 4)
3698 return \"fb%F0 %1,%#,%l2\";
3699 else
3700 return \"fb%f0 %1,%#,1f\;call %l2\\n1:\";
3701 }"
3702 [(set (attr "length")
3703 (if_then_else
3704 (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
3705 (le (minus (match_dup 2) (pc)) (const_int 32764)))
3706 (const_int 4)
3707 (const_int 8)))
3708 (set (attr "far_jump")
3709 (if_then_else
3710 (eq_attr "length" "4")
3711 (const_string "no")
3712 (const_string "yes")))
3713 (set (attr "type")
3714 (if_then_else
3715 (eq_attr "length" "4")
3716 (const_string "branch")
3717 (const_string "multi")))])
3718
3719 \f
3720 ;; ::::::::::::::::::::
3721 ;; ::
3722 ;; :: Set flag operations
3723 ;; ::
3724 ;; ::::::::::::::::::::
3725
3726 ;; Define_expands called by the machine independent part of the compiler
3727 ;; to allocate a new comparison register
3728
3729 (define_expand "cstoredf4"
3730 [(use (match_operator:SI 1 "ordered_comparison_operator"
3731 [(match_operand:DF 2 "fpr_operand")
3732 (match_operand:DF 3 "fpr_operand")]))
3733 (clobber (match_operand:SI 0 "register_operand"))]
3734 "TARGET_HARD_FLOAT && TARGET_DOUBLE"
3735 { if (frv_emit_scc (operands)) DONE; else FAIL; })
3736
3737 (define_expand "cstoresf4"
3738 [(use (match_operator:SI 1 "ordered_comparison_operator"
3739 [(match_operand:SF 2 "fpr_operand")
3740 (match_operand:SF 3 "fpr_operand")]))
3741 (clobber (match_operand:SI 0 "register_operand"))]
3742 "TARGET_HARD_FLOAT"
3743 { if (frv_emit_scc (operands)) DONE; else FAIL; })
3744
3745 (define_expand "cstoresi4"
3746 [(use (match_operator:SI 1 "ordered_comparison_operator"
3747 [(match_operand:SI 2 "integer_register_operand")
3748 (match_operand:SI 3 "gpr_or_int10_operand")]))
3749 (clobber (match_operand:SI 0 "register_operand"))]
3750 ""
3751 { if (frv_emit_scc (operands)) DONE; else FAIL; })
3752
3753 (define_insn "*scc_int"
3754 [(set (match_operand:SI 0 "integer_register_operand" "=d")
3755 (match_operator:SI 1 "integer_relational_operator"
3756 [(match_operand 2 "icc_operand" "t")
3757 (const_int 0)]))
3758 (clobber (match_operand:CC_CCR 3 "icr_operand" "=v"))]
3759 ""
3760 "#"
3761 [(set_attr "length" "12")
3762 (set_attr "type" "multi")])
3763
3764 (define_insn "*scc_float"
3765 [(set (match_operand:SI 0 "integer_register_operand" "=d")
3766 (match_operator:SI 1 "float_relational_operator"
3767 [(match_operand:CC_FP 2 "fcc_operand" "u")
3768 (const_int 0)]))
3769 (clobber (match_operand:CC_CCR 3 "fcr_operand" "=w"))]
3770 ""
3771 "#"
3772 [(set_attr "length" "12")
3773 (set_attr "type" "multi")])
3774
3775 ;; XXX -- add reload_completed to the splits, because register allocation
3776 ;; currently isn't ready to see cond_exec packets.
3777 (define_split
3778 [(set (match_operand:SI 0 "integer_register_operand" "")
3779 (match_operator:SI 1 "relational_operator"
3780 [(match_operand 2 "cc_operand" "")
3781 (const_int 0)]))
3782 (clobber (match_operand 3 "cr_operand" ""))]
3783 "reload_completed"
3784 [(match_dup 4)]
3785 "operands[4] = frv_split_scc (operands[0], operands[1], operands[2],
3786 operands[3], (HOST_WIDE_INT) 1);")
3787
3788 (define_insn "*scc_neg1_int"
3789 [(set (match_operand:SI 0 "integer_register_operand" "=d")
3790 (neg:SI (match_operator:SI 1 "integer_relational_operator"
3791 [(match_operand 2 "icc_operand" "t")
3792 (const_int 0)])))
3793 (clobber (match_operand:CC_CCR 3 "icr_operand" "=v"))]
3794 ""
3795 "#"
3796 [(set_attr "length" "12")
3797 (set_attr "type" "multi")])
3798
3799 (define_insn "*scc_neg1_float"
3800 [(set (match_operand:SI 0 "integer_register_operand" "=d")
3801 (neg:SI (match_operator:SI 1 "float_relational_operator"
3802 [(match_operand:CC_FP 2 "fcc_operand" "u")
3803 (const_int 0)])))
3804 (clobber (match_operand:CC_CCR 3 "fcr_operand" "=w"))]
3805 ""
3806 "#"
3807 [(set_attr "length" "12")
3808 (set_attr "type" "multi")])
3809
3810 (define_split
3811 [(set (match_operand:SI 0 "integer_register_operand" "")
3812 (neg:SI (match_operator:SI 1 "relational_operator"
3813 [(match_operand 2 "cc_operand" "")
3814 (const_int 0)])))
3815 (clobber (match_operand 3 "cr_operand" ""))]
3816 "reload_completed"
3817 [(match_dup 4)]
3818 "operands[4] = frv_split_scc (operands[0], operands[1], operands[2],
3819 operands[3], (HOST_WIDE_INT) -1);")
3820
3821 \f
3822 ;; ::::::::::::::::::::
3823 ;; ::
3824 ;; :: Conditionally executed instructions
3825 ;; ::
3826 ;; ::::::::::::::::::::
3827
3828 ;; Convert ICC/FCC comparison into CCR bits so we can do conditional execution
3829 (define_insn "*ck_signed"
3830 [(set (match_operand:CC_CCR 0 "icr_operand" "=v")
3831 (match_operator:CC_CCR 1 "integer_relational_operator"
3832 [(match_operand 2 "icc_operand" "t")
3833 (const_int 0)]))]
3834 ""
3835 "ck%c1 %2, %0"
3836 [(set_attr "length" "4")
3837 (set_attr "type" "ccr")])
3838
3839 (define_insn "*fck_float"
3840 [(set (match_operand:CC_CCR 0 "fcr_operand" "=w")
3841 (match_operator:CC_CCR 1 "float_relational_operator"
3842 [(match_operand:CC_FP 2 "fcc_operand" "u")
3843 (const_int 0)]))]
3844 "TARGET_HAS_FPRS"
3845 "fck%c1 %2, %0"
3846 [(set_attr "length" "4")
3847 (set_attr "type" "ccr")])
3848
3849 ;; Conditionally convert ICC/FCC comparison into CCR bits to provide && and ||
3850 ;; tests in conditional execution
3851 (define_insn "cond_exec_ck"
3852 [(set (match_operand:CC_CCR 0 "cr_operand" "=v,w")
3853 (if_then_else:CC_CCR (match_operator 1 "ccr_eqne_operator"
3854 [(match_operand 2 "cr_operand" "C,C")
3855 (const_int 0)])
3856 (match_operator 3 "relational_operator"
3857 [(match_operand 4 "cc_operand" "t,u")
3858 (const_int 0)])
3859 (const_int 0)))]
3860 ""
3861 "@
3862 cck%c3 %4, %0, %2, %e1
3863 cfck%f3 %4, %0, %2, %e1"
3864 [(set_attr "length" "4")
3865 (set_attr "type" "ccr")])
3866
3867 ;; Conditionally set a register to either 0 or another register
3868 (define_insn "*cond_exec_movqi"
3869 [(cond_exec
3870 (match_operator 0 "ccr_eqne_operator"
3871 [(match_operand 1 "cr_operand" "C,C,C,C,C,C")
3872 (const_int 0)])
3873 (set (match_operand:QI 2 "condexec_dest_operand" "=d,d,U,?f,?f,?d")
3874 (match_operand:QI 3 "condexec_source_operand" "dO,U,dO,f,d,f")))]
3875 "register_operand(operands[2], QImode) || reg_or_0_operand (operands[3], QImode)"
3876 "* return output_condmove_single (operands, insn);"
3877 [(set_attr "length" "4")
3878 (set_attr "type" "int,gload,gstore,fsconv,movgf,movfg")])
3879
3880 (define_insn "*cond_exec_movhi"
3881 [(cond_exec
3882 (match_operator 0 "ccr_eqne_operator"
3883 [(match_operand 1 "cr_operand" "C,C,C,C,C,C")
3884 (const_int 0)])
3885 (set (match_operand:HI 2 "condexec_dest_operand" "=d,d,U,?f,?f,?d")
3886 (match_operand:HI 3 "condexec_source_operand" "dO,U,dO,f,d,f")))]
3887 "register_operand(operands[2], HImode) || reg_or_0_operand (operands[3], HImode)"
3888 "* return output_condmove_single (operands, insn);"
3889 [(set_attr "length" "4")
3890 (set_attr "type" "int,gload,gstore,fsconv,movgf,movfg")])
3891
3892 (define_insn "*cond_exec_movsi"
3893 [(cond_exec
3894 (match_operator 0 "ccr_eqne_operator"
3895 [(match_operand 1 "cr_operand" "C,C,C,C,C,C,C,C")
3896 (const_int 0)])
3897 (set (match_operand:SI 2 "condexec_dest_operand" "=d,d,U,?f,?f,?d,?f,?m")
3898 (match_operand:SI 3 "condexec_source_operand" "dO,U,dO,f,d,f,m,f")))]
3899 "register_operand(operands[2], SImode) || reg_or_0_operand (operands[3], SImode)"
3900 "* return output_condmove_single (operands, insn);"
3901 [(set_attr "length" "4")
3902 (set_attr "type" "int,gload,gstore,fsconv,movgf,movfg,fload,fstore")])
3903
3904
3905 (define_insn "*cond_exec_movsf_has_fprs"
3906 [(cond_exec
3907 (match_operator 0 "ccr_eqne_operator"
3908 [(match_operand 1 "cr_operand" "C,C,C,C,C,C,C,C,C,C")
3909 (const_int 0)])
3910 (set (match_operand:SF 2 "condexec_dest_operand" "=f,?d,?d,?f,f,f,?d,U,?U,U")
3911 (match_operand:SF 3 "condexec_source_operand" "f,d,f,d,G,U,U,f,d,G")))]
3912 "TARGET_HAS_FPRS"
3913 "* return output_condmove_single (operands, insn);"
3914 [(set_attr "length" "4")
3915 (set_attr "type" "fsconv,int,movgf,movfg,movgf,fload,gload,fstore,gstore,gstore")])
3916
3917 (define_insn "*cond_exec_movsf_no_fprs"
3918 [(cond_exec
3919 (match_operator 0 "ccr_eqne_operator"
3920 [(match_operand 1 "cr_operand" "C,C,C")
3921 (const_int 0)])
3922 (set (match_operand:SF 2 "condexec_dest_operand" "=d,d,U")
3923 (match_operand:SF 3 "condexec_source_operand" "d,U,dG")))]
3924 "! TARGET_HAS_FPRS"
3925 "* return output_condmove_single (operands, insn);"
3926 [(set_attr "length" "4")
3927 (set_attr "type" "int,gload,gstore")])
3928
3929 (define_insn "*cond_exec_si_binary1"
3930 [(cond_exec
3931 (match_operator 0 "ccr_eqne_operator"
3932 [(match_operand 1 "cr_operand" "C")
3933 (const_int 0)])
3934 (set (match_operand:SI 2 "integer_register_operand" "=d")
3935 (match_operator:SI 3 "condexec_si_binary_operator"
3936 [(match_operand:SI 4 "integer_register_operand" "d")
3937 (match_operand:SI 5 "integer_register_operand" "d")])))]
3938 ""
3939 "*
3940 {
3941 switch (GET_CODE (operands[3]))
3942 {
3943 case PLUS: return \"cadd %4, %z5, %2, %1, %e0\";
3944 case MINUS: return \"csub %4, %z5, %2, %1, %e0\";
3945 case AND: return \"cand %4, %z5, %2, %1, %e0\";
3946 case IOR: return \"cor %4, %z5, %2, %1, %e0\";
3947 case XOR: return \"cxor %4, %z5, %2, %1, %e0\";
3948 case ASHIFT: return \"csll %4, %z5, %2, %1, %e0\";
3949 case ASHIFTRT: return \"csra %4, %z5, %2, %1, %e0\";
3950 case LSHIFTRT: return \"csrl %4, %z5, %2, %1, %e0\";
3951 default: gcc_unreachable ();
3952 }
3953 }"
3954 [(set_attr "length" "4")
3955 (set_attr "type" "int")])
3956
3957 (define_insn "*cond_exec_si_binary2"
3958 [(cond_exec
3959 (match_operator 0 "ccr_eqne_operator"
3960 [(match_operand 1 "cr_operand" "C")
3961 (const_int 0)])
3962 (set (match_operand:SI 2 "fpr_operand" "=f")
3963 (match_operator:SI 3 "condexec_si_media_operator"
3964 [(match_operand:SI 4 "fpr_operand" "f")
3965 (match_operand:SI 5 "fpr_operand" "f")])))]
3966 "TARGET_MEDIA"
3967 "*
3968 {
3969 switch (GET_CODE (operands[3]))
3970 {
3971 case AND: return \"cmand %4, %5, %2, %1, %e0\";
3972 case IOR: return \"cmor %4, %5, %2, %1, %e0\";
3973 case XOR: return \"cmxor %4, %5, %2, %1, %e0\";
3974 default: gcc_unreachable ();
3975 }
3976 }"
3977 [(set_attr "length" "4")
3978 (set_attr "type" "mlogic")])
3979
3980 ;; Note, flow does not (currently) know how to handle an operation that uses
3981 ;; only part of the hard registers allocated for a multiregister value, such as
3982 ;; DImode in this case if the user is only interested in the lower 32-bits. So
3983 ;; we emit a USE of the entire register after the csmul instruction so it won't
3984 ;; get confused. See frv_ifcvt_modify_insn for more details.
3985
3986 (define_insn "*cond_exec_si_smul"
3987 [(cond_exec
3988 (match_operator 0 "ccr_eqne_operator"
3989 [(match_operand 1 "cr_operand" "C")
3990 (const_int 0)])
3991 (set (match_operand:DI 2 "even_gpr_operand" "=e")
3992 (mult:DI (sign_extend:DI (match_operand:SI 3 "integer_register_operand" "%d"))
3993 (sign_extend:DI (match_operand:SI 4 "integer_register_operand" "d")))))]
3994 ""
3995 "csmul %3, %4, %2, %1, %e0"
3996 [(set_attr "length" "4")
3997 (set_attr "type" "mul")])
3998
3999 (define_insn "*cond_exec_si_divide"
4000 [(cond_exec
4001 (match_operator 0 "ccr_eqne_operator"
4002 [(match_operand 1 "cr_operand" "C")
4003 (const_int 0)])
4004 (set (match_operand:SI 2 "integer_register_operand" "=d")
4005 (match_operator:SI 3 "condexec_si_divide_operator"
4006 [(match_operand:SI 4 "integer_register_operand" "d")
4007 (match_operand:SI 5 "integer_register_operand" "d")])))]
4008 ""
4009 "*
4010 {
4011 switch (GET_CODE (operands[3]))
4012 {
4013 case DIV: return \"csdiv %4, %z5, %2, %1, %e0\";
4014 case UDIV: return \"cudiv %4, %z5, %2, %1, %e0\";
4015 default: gcc_unreachable ();
4016 }
4017 }"
4018 [(set_attr "length" "4")
4019 (set_attr "type" "div")])
4020
4021 (define_insn "*cond_exec_si_unary1"
4022 [(cond_exec
4023 (match_operator 0 "ccr_eqne_operator"
4024 [(match_operand 1 "cr_operand" "C")
4025 (const_int 0)])
4026 (set (match_operand:SI 2 "integer_register_operand" "=d")
4027 (match_operator:SI 3 "condexec_si_unary_operator"
4028 [(match_operand:SI 4 "integer_register_operand" "d")])))]
4029 ""
4030 "*
4031 {
4032 switch (GET_CODE (operands[3]))
4033 {
4034 case NOT: return \"cnot %4, %2, %1, %e0\";
4035 case NEG: return \"csub %., %4, %2, %1, %e0\";
4036 default: gcc_unreachable ();
4037 }
4038 }"
4039 [(set_attr "length" "4")
4040 (set_attr "type" "int")])
4041
4042 (define_insn "*cond_exec_si_unary2"
4043 [(cond_exec
4044 (match_operator 0 "ccr_eqne_operator"
4045 [(match_operand 1 "cr_operand" "C")
4046 (const_int 0)])
4047 (set (match_operand:SI 2 "fpr_operand" "=f")
4048 (not:SI (match_operand:SI 3 "fpr_operand" "f"))))]
4049 "TARGET_MEDIA"
4050 "cmnot %3, %2, %1, %e0"
4051 [(set_attr "length" "4")
4052 (set_attr "type" "mlogic")])
4053
4054 (define_insn "*cond_exec_cmpsi_cc"
4055 [(cond_exec
4056 (match_operator 0 "ccr_eqne_operator"
4057 [(match_operand 1 "cr_operand" "C")
4058 (const_int 0)])
4059 (set (match_operand:CC 2 "icc_operand" "=t")
4060 (compare:CC (match_operand:SI 3 "integer_register_operand" "d")
4061 (match_operand:SI 4 "reg_or_0_operand" "dO"))))]
4062 "reload_completed
4063 && REGNO (operands[1]) == REGNO (operands[2]) - ICC_FIRST + ICR_FIRST"
4064 "ccmp %3, %z4, %1, %e0"
4065 [(set_attr "length" "4")
4066 (set_attr "type" "int")])
4067
4068 (define_insn "*cond_exec_cmpsi_cc_uns"
4069 [(cond_exec
4070 (match_operator 0 "ccr_eqne_operator"
4071 [(match_operand 1 "cr_operand" "C")
4072 (const_int 0)])
4073 (set (match_operand:CC_UNS 2 "icc_operand" "=t")
4074 (compare:CC_UNS (match_operand:SI 3 "integer_register_operand" "d")
4075 (match_operand:SI 4 "reg_or_0_operand" "dO"))))]
4076 "reload_completed
4077 && REGNO (operands[1]) == REGNO (operands[2]) - ICC_FIRST + ICR_FIRST"
4078 "ccmp %3, %z4, %1, %e0"
4079 [(set_attr "length" "4")
4080 (set_attr "type" "int")])
4081
4082 (define_insn "*cond_exec_cmpsi_cc_nz"
4083 [(cond_exec
4084 (match_operator 0 "ccr_eqne_operator"
4085 [(match_operand 1 "cr_operand" "C")
4086 (const_int 0)])
4087 (set (match_operand:CC_NZ 2 "icc_operand" "=t")
4088 (compare:CC_NZ (match_operand:SI 3 "integer_register_operand" "d")
4089 (const_int 0))))]
4090 "reload_completed
4091 && REGNO (operands[1]) == REGNO (operands[2]) - ICC_FIRST + ICR_FIRST"
4092 "ccmp %3, %., %1, %e0"
4093 [(set_attr "length" "4")
4094 (set_attr "type" "int")])
4095
4096 (define_insn "*cond_exec_sf_conv"
4097 [(cond_exec
4098 (match_operator 0 "ccr_eqne_operator"
4099 [(match_operand 1 "cr_operand" "C")
4100 (const_int 0)])
4101 (set (match_operand:SF 2 "fpr_operand" "=f")
4102 (match_operator:SF 3 "condexec_sf_conv_operator"
4103 [(match_operand:SF 4 "fpr_operand" "f")])))]
4104 "TARGET_HARD_FLOAT"
4105 "*
4106 {
4107 switch (GET_CODE (operands[3]))
4108 {
4109 case ABS: return \"cfabss %4, %2, %1, %e0\";
4110 case NEG: return \"cfnegs %4, %2, %1, %e0\";
4111 default: gcc_unreachable ();
4112 }
4113 }"
4114 [(set_attr "length" "4")
4115 (set_attr "type" "fsconv")])
4116
4117 (define_insn "*cond_exec_sf_add"
4118 [(cond_exec
4119 (match_operator 0 "ccr_eqne_operator"
4120 [(match_operand 1 "cr_operand" "C")
4121 (const_int 0)])
4122 (set (match_operand:SF 2 "fpr_operand" "=f")
4123 (match_operator:SF 3 "condexec_sf_add_operator"
4124 [(match_operand:SF 4 "fpr_operand" "f")
4125 (match_operand:SF 5 "fpr_operand" "f")])))]
4126 "TARGET_HARD_FLOAT"
4127 "*
4128 {
4129 switch (GET_CODE (operands[3]))
4130 {
4131 case PLUS: return \"cfadds %4, %5, %2, %1, %e0\";
4132 case MINUS: return \"cfsubs %4, %5, %2, %1, %e0\";
4133 default: gcc_unreachable ();
4134 }
4135 }"
4136 [(set_attr "length" "4")
4137 (set_attr "type" "fsadd")])
4138
4139 (define_insn "*cond_exec_sf_mul"
4140 [(cond_exec
4141 (match_operator 0 "ccr_eqne_operator"
4142 [(match_operand 1 "cr_operand" "C")
4143 (const_int 0)])
4144 (set (match_operand:SF 2 "fpr_operand" "=f")
4145 (mult:SF (match_operand:SF 3 "fpr_operand" "f")
4146 (match_operand:SF 4 "fpr_operand" "f"))))]
4147 "TARGET_HARD_FLOAT"
4148 "cfmuls %3, %4, %2, %1, %e0"
4149 [(set_attr "length" "4")
4150 (set_attr "type" "fsmul")])
4151
4152 (define_insn "*cond_exec_sf_div"
4153 [(cond_exec
4154 (match_operator 0 "ccr_eqne_operator"
4155 [(match_operand 1 "cr_operand" "C")
4156 (const_int 0)])
4157 (set (match_operand:SF 2 "fpr_operand" "=f")
4158 (div:SF (match_operand:SF 3 "fpr_operand" "f")
4159 (match_operand:SF 4 "fpr_operand" "f"))))]
4160 "TARGET_HARD_FLOAT"
4161 "cfdivs %3, %4, %2, %1, %e0"
4162 [(set_attr "length" "4")
4163 (set_attr "type" "fsdiv")])
4164
4165 (define_insn "*cond_exec_sf_sqrt"
4166 [(cond_exec
4167 (match_operator 0 "ccr_eqne_operator"
4168 [(match_operand 1 "cr_operand" "C")
4169 (const_int 0)])
4170 (set (match_operand:SF 2 "fpr_operand" "=f")
4171 (sqrt:SF (match_operand:SF 3 "fpr_operand" "f"))))]
4172 "TARGET_HARD_FLOAT"
4173 "cfsqrts %3, %2, %1, %e0"
4174 [(set_attr "length" "4")
4175 (set_attr "type" "fsdiv")])
4176
4177 (define_insn "*cond_exec_cmpsi_cc_fp"
4178 [(cond_exec
4179 (match_operator 0 "ccr_eqne_operator"
4180 [(match_operand 1 "cr_operand" "C")
4181 (const_int 0)])
4182 (set (match_operand:CC_FP 2 "fcc_operand" "=u")
4183 (compare:CC_FP (match_operand:SF 3 "fpr_operand" "f")
4184 (match_operand:SF 4 "fpr_operand" "f"))))]
4185 "reload_completed && TARGET_HARD_FLOAT
4186 && REGNO (operands[1]) == REGNO (operands[2]) - FCC_FIRST + FCR_FIRST"
4187 "cfcmps %3, %4, %2, %1, %e0"
4188 [(set_attr "length" "4")
4189 (set_attr "type" "fsconv")])
4190
4191 \f
4192 ;; ::::::::::::::::::::
4193 ;; ::
4194 ;; :: Logical operations on CR registers
4195 ;; ::
4196 ;; ::::::::::::::::::::
4197
4198 ;; We use UNSPEC to encode andcr/iorcr/etc. rather than the normal RTL
4199 ;; operations, since the RTL operations only have an idea of TRUE and FALSE,
4200 ;; while the CRs have TRUE, FALSE, and UNDEFINED.
4201
4202 (define_expand "andcr"
4203 [(set (match_operand:CC_CCR 0 "cr_operand" "")
4204 (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "")
4205 (match_operand:CC_CCR 2 "cr_operand" "")
4206 (const_int 0)] UNSPEC_CR_LOGIC))]
4207 ""
4208 "")
4209
4210 (define_expand "orcr"
4211 [(set (match_operand:CC_CCR 0 "cr_operand" "")
4212 (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "")
4213 (match_operand:CC_CCR 2 "cr_operand" "")
4214 (const_int 1)] UNSPEC_CR_LOGIC))]
4215 ""
4216 "")
4217
4218 (define_expand "xorcr"
4219 [(set (match_operand:CC_CCR 0 "cr_operand" "")
4220 (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "")
4221 (match_operand:CC_CCR 2 "cr_operand" "")
4222 (const_int 2)] UNSPEC_CR_LOGIC))]
4223 ""
4224 "")
4225
4226 (define_expand "nandcr"
4227 [(set (match_operand:CC_CCR 0 "cr_operand" "")
4228 (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "")
4229 (match_operand:CC_CCR 2 "cr_operand" "")
4230 (const_int 3)] UNSPEC_CR_LOGIC))]
4231 ""
4232 "")
4233
4234 (define_expand "norcr"
4235 [(set (match_operand:CC_CCR 0 "cr_operand" "")
4236 (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "")
4237 (match_operand:CC_CCR 2 "cr_operand" "")
4238 (const_int 4)] UNSPEC_CR_LOGIC))]
4239 ""
4240 "")
4241
4242 (define_expand "andncr"
4243 [(set (match_operand:CC_CCR 0 "cr_operand" "")
4244 (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "")
4245 (match_operand:CC_CCR 2 "cr_operand" "")
4246 (const_int 5)] UNSPEC_CR_LOGIC))]
4247 ""
4248 "")
4249
4250 (define_expand "orncr"
4251 [(set (match_operand:CC_CCR 0 "cr_operand" "")
4252 (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "")
4253 (match_operand:CC_CCR 2 "cr_operand" "")
4254 (const_int 6)] UNSPEC_CR_LOGIC))]
4255 ""
4256 "")
4257
4258 (define_expand "nandncr"
4259 [(set (match_operand:CC_CCR 0 "cr_operand" "")
4260 (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "")
4261 (match_operand:CC_CCR 2 "cr_operand" "")
4262 (const_int 7)] UNSPEC_CR_LOGIC))]
4263 ""
4264 "")
4265
4266 (define_expand "norncr"
4267 [(set (match_operand:CC_CCR 0 "cr_operand" "")
4268 (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "")
4269 (match_operand:CC_CCR 2 "cr_operand" "")
4270 (const_int 8)] UNSPEC_CR_LOGIC))]
4271 ""
4272 "")
4273
4274 (define_expand "notcr"
4275 [(set (match_operand:CC_CCR 0 "cr_operand" "")
4276 (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "")
4277 (match_dup 1)
4278 (const_int 9)] UNSPEC_CR_LOGIC))]
4279 ""
4280 "")
4281
4282 (define_insn "*logical_cr"
4283 [(set (match_operand:CC_CCR 0 "cr_operand" "=C")
4284 (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "C")
4285 (match_operand:CC_CCR 2 "cr_operand" "C")
4286 (match_operand:SI 3 "const_int_operand" "n")]
4287 UNSPEC_CR_LOGIC))]
4288 ""
4289 "*
4290 {
4291 switch (INTVAL (operands[3]))
4292 {
4293 default: break;
4294 case 0: return \"andcr %1, %2, %0\";
4295 case 1: return \"orcr %1, %2, %0\";
4296 case 2: return \"xorcr %1, %2, %0\";
4297 case 3: return \"nandcr %1, %2, %0\";
4298 case 4: return \"norcr %1, %2, %0\";
4299 case 5: return \"andncr %1, %2, %0\";
4300 case 6: return \"orncr %1, %2, %0\";
4301 case 7: return \"nandncr %1, %2, %0\";
4302 case 8: return \"norncr %1, %2, %0\";
4303 case 9: return \"notcr %1, %0\";
4304 }
4305
4306 fatal_insn (\"logical_cr\", insn);
4307 }"
4308 [(set_attr "length" "4")
4309 (set_attr "type" "ccr")])
4310
4311 \f
4312 ;; ::::::::::::::::::::
4313 ;; ::
4314 ;; :: Conditional move instructions
4315 ;; ::
4316 ;; ::::::::::::::::::::
4317
4318
4319 ;; - conditional moves based on floating-point comparisons require
4320 ;; TARGET_HARD_FLOAT, because an FPU is required to do the comparison.
4321
4322 ;; - conditional moves between FPRs based on integer comparisons
4323 ;; require TARGET_HAS_FPRS.
4324
4325 (define_expand "movqicc"
4326 [(set (match_operand:QI 0 "integer_register_operand" "")
4327 (if_then_else:QI (match_operand 1 "" "")
4328 (match_operand:QI 2 "gpr_or_int_operand" "")
4329 (match_operand:QI 3 "gpr_or_int_operand" "")))]
4330 "TARGET_COND_MOVE"
4331 "
4332 {
4333 if (!frv_emit_cond_move (operands[0], operands[1], operands[2], operands[3]))
4334 FAIL;
4335
4336 DONE;
4337 }")
4338
4339 (define_insn "*movqicc_internal1_int"
4340 [(set (match_operand:QI 0 "integer_register_operand" "=d,d,d")
4341 (if_then_else:QI (match_operator 1 "integer_relational_operator"
4342 [(match_operand 2 "icc_operand" "t,t,t")
4343 (const_int 0)])
4344 (match_operand:QI 3 "reg_or_0_operand" "0,dO,dO")
4345 (match_operand:QI 4 "reg_or_0_operand" "dO,0,dO")))
4346 (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v"))]
4347 ""
4348 "#"
4349 [(set_attr "length" "8,8,12")
4350 (set_attr "type" "multi")])
4351
4352 (define_insn "*movqicc_internal1_float"
4353 [(set (match_operand:QI 0 "integer_register_operand" "=d,d,d")
4354 (if_then_else:QI (match_operator:CC_FP 1 "float_relational_operator"
4355 [(match_operand:CC_FP 2 "fcc_operand" "u,u,u")
4356 (const_int 0)])
4357 (match_operand:QI 3 "reg_or_0_operand" "0,dO,dO")
4358 (match_operand:QI 4 "reg_or_0_operand" "dO,0,dO")))
4359 (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w"))]
4360 "TARGET_HARD_FLOAT"
4361 "#"
4362 [(set_attr "length" "8,8,12")
4363 (set_attr "type" "multi")])
4364
4365 (define_insn "*movqicc_internal2_int"
4366 [(set (match_operand:QI 0 "integer_register_operand" "=d,d,d,d,d")
4367 (if_then_else:QI (match_operator 1 "integer_relational_operator"
4368 [(match_operand 2 "icc_operand" "t,t,t,t,t")
4369 (const_int 0)])
4370 (match_operand:QI 3 "const_int_operand" "O,O,L,n,n")
4371 (match_operand:QI 4 "const_int_operand" "L,n,O,O,n")))
4372 (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v,v,v"))]
4373 "(INTVAL (operands[3]) == 0
4374 || INTVAL (operands[4]) == 0
4375 || (IN_RANGE (INTVAL (operands[3]), -2048, 2047)
4376 && IN_RANGE (INTVAL (operands[4]) - INTVAL (operands[3]), -2048, 2047)))"
4377 "#"
4378 [(set_attr "length" "8,12,8,12,12")
4379 (set_attr "type" "multi")])
4380
4381 (define_insn "*movqicc_internal2_float"
4382 [(set (match_operand:QI 0 "integer_register_operand" "=d,d,d,d,d")
4383 (if_then_else:QI (match_operator:CC_FP 1 "float_relational_operator"
4384 [(match_operand:CC_FP 2 "fcc_operand" "u,u,u,u,u")
4385 (const_int 0)])
4386 (match_operand:QI 3 "const_int_operand" "O,O,L,n,n")
4387 (match_operand:QI 4 "const_int_operand" "L,n,O,O,n")))
4388 (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w,w,w"))]
4389 "TARGET_HARD_FLOAT
4390 && (INTVAL (operands[3]) == 0
4391 || INTVAL (operands[4]) == 0
4392 || (IN_RANGE (INTVAL (operands[3]), -2048, 2047)
4393 && IN_RANGE (INTVAL (operands[4]) - INTVAL (operands[3]), -2048, 2047)))"
4394 "#"
4395 [(set_attr "length" "8,12,8,12,12")
4396 (set_attr "type" "multi")])
4397
4398 (define_split
4399 [(set (match_operand:QI 0 "integer_register_operand" "")
4400 (if_then_else:QI (match_operator 1 "relational_operator"
4401 [(match_operand 2 "cc_operand" "")
4402 (const_int 0)])
4403 (match_operand:QI 3 "gpr_or_int_operand" "")
4404 (match_operand:QI 4 "gpr_or_int_operand" "")))
4405 (clobber (match_operand:CC_CCR 5 "cr_operand" ""))]
4406 "reload_completed"
4407 [(match_dup 6)]
4408 "operands[6] = frv_split_cond_move (operands);")
4409
4410 (define_expand "movhicc"
4411 [(set (match_operand:HI 0 "integer_register_operand" "")
4412 (if_then_else:HI (match_operand 1 "" "")
4413 (match_operand:HI 2 "gpr_or_int_operand" "")
4414 (match_operand:HI 3 "gpr_or_int_operand" "")))]
4415 "TARGET_COND_MOVE"
4416 "
4417 {
4418 if (!frv_emit_cond_move (operands[0], operands[1], operands[2], operands[3]))
4419 FAIL;
4420
4421 DONE;
4422 }")
4423
4424 (define_insn "*movhicc_internal1_int"
4425 [(set (match_operand:HI 0 "integer_register_operand" "=d,d,d")
4426 (if_then_else:HI (match_operator 1 "integer_relational_operator"
4427 [(match_operand 2 "icc_operand" "t,t,t")
4428 (const_int 0)])
4429 (match_operand:HI 3 "reg_or_0_operand" "0,dO,dO")
4430 (match_operand:HI 4 "reg_or_0_operand" "dO,0,dO")))
4431 (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v"))]
4432 ""
4433 "#"
4434 [(set_attr "length" "8,8,12")
4435 (set_attr "type" "multi")])
4436
4437 (define_insn "*movhicc_internal1_float"
4438 [(set (match_operand:HI 0 "integer_register_operand" "=d,d,d")
4439 (if_then_else:HI (match_operator:CC_FP 1 "float_relational_operator"
4440 [(match_operand:CC_FP 2 "fcc_operand" "u,u,u")
4441 (const_int 0)])
4442 (match_operand:HI 3 "reg_or_0_operand" "0,dO,dO")
4443 (match_operand:HI 4 "reg_or_0_operand" "dO,0,dO")))
4444 (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w"))]
4445 "TARGET_HARD_FLOAT"
4446 "#"
4447 [(set_attr "length" "8,8,12")
4448 (set_attr "type" "multi")])
4449
4450 (define_insn "*movhicc_internal2_int"
4451 [(set (match_operand:HI 0 "integer_register_operand" "=d,d,d,d,d")
4452 (if_then_else:HI (match_operator 1 "integer_relational_operator"
4453 [(match_operand 2 "icc_operand" "t,t,t,t,t")
4454 (const_int 0)])
4455 (match_operand:HI 3 "const_int_operand" "O,O,L,n,n")
4456 (match_operand:HI 4 "const_int_operand" "L,n,O,O,n")))
4457 (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v,v,v"))]
4458 "(INTVAL (operands[3]) == 0
4459 || INTVAL (operands[4]) == 0
4460 || (IN_RANGE (INTVAL (operands[3]), -2048, 2047)
4461 && IN_RANGE (INTVAL (operands[4]) - INTVAL (operands[3]), -2048, 2047)))"
4462 "#"
4463 [(set_attr "length" "8,12,8,12,12")
4464 (set_attr "type" "multi")])
4465
4466 (define_insn "*movhicc_internal2_float"
4467 [(set (match_operand:HI 0 "integer_register_operand" "=d,d,d,d,d")
4468 (if_then_else:HI (match_operator:CC_FP 1 "float_relational_operator"
4469 [(match_operand:CC_FP 2 "fcc_operand" "u,u,u,u,u")
4470 (const_int 0)])
4471 (match_operand:HI 3 "const_int_operand" "O,O,L,n,n")
4472 (match_operand:HI 4 "const_int_operand" "L,n,O,O,n")))
4473 (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w,w,w"))]
4474 "TARGET_HARD_FLOAT
4475 && (INTVAL (operands[3]) == 0
4476 || INTVAL (operands[4]) == 0
4477 || (IN_RANGE (INTVAL (operands[3]), -2048, 2047)
4478 && IN_RANGE (INTVAL (operands[4]) - INTVAL (operands[3]), -2048, 2047)))"
4479 "#"
4480 [(set_attr "length" "8,12,8,12,12")
4481 (set_attr "type" "multi")])
4482
4483 (define_split
4484 [(set (match_operand:HI 0 "integer_register_operand" "")
4485 (if_then_else:HI (match_operator 1 "relational_operator"
4486 [(match_operand 2 "cc_operand" "")
4487 (const_int 0)])
4488 (match_operand:HI 3 "gpr_or_int_operand" "")
4489 (match_operand:HI 4 "gpr_or_int_operand" "")))
4490 (clobber (match_operand:CC_CCR 5 "cr_operand" ""))]
4491 "reload_completed"
4492 [(match_dup 6)]
4493 "operands[6] = frv_split_cond_move (operands);")
4494
4495 (define_expand "movsicc"
4496 [(set (match_operand:SI 0 "integer_register_operand" "")
4497 (if_then_else:SI (match_operand 1 "" "")
4498 (match_operand:SI 2 "gpr_or_int_operand" "")
4499 (match_operand:SI 3 "gpr_or_int_operand" "")))]
4500 "TARGET_COND_MOVE"
4501 "
4502 {
4503 if (!frv_emit_cond_move (operands[0], operands[1], operands[2], operands[3]))
4504 FAIL;
4505
4506 DONE;
4507 }")
4508
4509 (define_insn "*movsicc_internal1_int"
4510 [(set (match_operand:SI 0 "integer_register_operand" "=d,d,d")
4511 (if_then_else:SI (match_operator 1 "integer_relational_operator"
4512 [(match_operand 2 "icc_operand" "t,t,t")
4513 (const_int 0)])
4514 (match_operand:SI 3 "reg_or_0_operand" "0,dO,dO")
4515 (match_operand:SI 4 "reg_or_0_operand" "dO,0,dO")))
4516 (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v"))]
4517 ""
4518 "#"
4519 [(set_attr "length" "8,8,12")
4520 (set_attr "type" "multi")])
4521
4522 (define_insn "*movsicc_internal1_float"
4523 [(set (match_operand:SI 0 "integer_register_operand" "=d,d,d")
4524 (if_then_else:SI (match_operator:CC_FP 1 "float_relational_operator"
4525 [(match_operand:CC_FP 2 "fcc_operand" "u,u,u")
4526 (const_int 0)])
4527 (match_operand:SI 3 "reg_or_0_operand" "0,dO,dO")
4528 (match_operand:SI 4 "reg_or_0_operand" "dO,0,dO")))
4529 (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w"))]
4530 "TARGET_HARD_FLOAT"
4531 "#"
4532 [(set_attr "length" "8,8,12")
4533 (set_attr "type" "multi")])
4534
4535 (define_insn "*movsicc_internal2_int"
4536 [(set (match_operand:SI 0 "integer_register_operand" "=d,d,d,d,d")
4537 (if_then_else:SI (match_operator 1 "integer_relational_operator"
4538 [(match_operand 2 "icc_operand" "t,t,t,t,t")
4539 (const_int 0)])
4540 (match_operand:SI 3 "const_int_operand" "O,O,L,n,n")
4541 (match_operand:SI 4 "const_int_operand" "L,n,O,O,n")))
4542 (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v,v,v"))]
4543 "(INTVAL (operands[3]) == 0
4544 || INTVAL (operands[4]) == 0
4545 || (IN_RANGE (INTVAL (operands[3]), -2048, 2047)
4546 && IN_RANGE (INTVAL (operands[4]) - INTVAL (operands[3]), -2048, 2047)))"
4547 "#"
4548 [(set_attr "length" "8,12,8,12,12")
4549 (set_attr "type" "multi")])
4550
4551 (define_insn "*movsicc_internal2_float"
4552 [(set (match_operand:SI 0 "integer_register_operand" "=d,d,d,d,d")
4553 (if_then_else:SI (match_operator:CC_FP 1 "float_relational_operator"
4554 [(match_operand:CC_FP 2 "fcc_operand" "u,u,u,u,u")
4555 (const_int 0)])
4556 (match_operand:SI 3 "const_int_operand" "O,O,L,n,n")
4557 (match_operand:SI 4 "const_int_operand" "L,n,O,O,n")))
4558 (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w,w,w"))]
4559 "TARGET_HARD_FLOAT
4560 && (INTVAL (operands[3]) == 0
4561 || INTVAL (operands[4]) == 0
4562 || (IN_RANGE (INTVAL (operands[3]), -2048, 2047)
4563 && IN_RANGE (INTVAL (operands[4]) - INTVAL (operands[3]), -2048, 2047)))"
4564 "#"
4565 [(set_attr "length" "8,12,8,12,12")
4566 (set_attr "type" "multi")])
4567
4568 (define_split
4569 [(set (match_operand:SI 0 "integer_register_operand" "")
4570 (if_then_else:SI (match_operator 1 "relational_operator"
4571 [(match_operand 2 "cc_operand" "")
4572 (const_int 0)])
4573 (match_operand:SI 3 "gpr_or_int_operand" "")
4574 (match_operand:SI 4 "gpr_or_int_operand" "")))
4575 (clobber (match_operand:CC_CCR 5 "cr_operand" ""))]
4576 "reload_completed"
4577 [(match_dup 6)]
4578 "operands[6] = frv_split_cond_move (operands);")
4579
4580 (define_expand "movsfcc"
4581 [(set (match_operand:SF 0 "register_operand" "")
4582 (if_then_else:SF (match_operand 1 "" "")
4583 (match_operand:SF 2 "register_operand" "")
4584 (match_operand:SF 3 "register_operand" "")))]
4585 "TARGET_COND_MOVE"
4586 "
4587 {
4588 if (!frv_emit_cond_move (operands[0], operands[1], operands[2], operands[3]))
4589 FAIL;
4590
4591 DONE;
4592 }")
4593
4594 (define_insn "*movsfcc_has_fprs_int"
4595 [(set (match_operand:SF 0 "register_operand" "=f,f,f,?f,?f,?d")
4596 (if_then_else:SF (match_operator 1 "integer_relational_operator"
4597 [(match_operand 2 "icc_operand" "t,t,t,t,t,t")
4598 (const_int 0)])
4599 (match_operand:SF 3 "register_operand" "0,f,f,f,d,fd")
4600 (match_operand:SF 4 "register_operand" "f,0,f,d,fd,fd")))
4601 (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v,v,v,v"))]
4602 "TARGET_HAS_FPRS"
4603 "#"
4604 [(set_attr "length" "8,8,12,12,12,12")
4605 (set_attr "type" "multi")])
4606
4607 (define_insn "*movsfcc_hardfloat_float"
4608 [(set (match_operand:SF 0 "register_operand" "=f,f,f,?f,?f,?d")
4609 (if_then_else:SF (match_operator:CC_FP 1 "float_relational_operator"
4610 [(match_operand:CC_FP 2 "fcc_operand" "u,u,u,u,u,u")
4611 (const_int 0)])
4612 (match_operand:SF 3 "register_operand" "0,f,f,f,d,fd")
4613 (match_operand:SF 4 "register_operand" "f,0,f,d,fd,fd")))
4614 (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w,w,w,w"))]
4615 "TARGET_HARD_FLOAT"
4616 "#"
4617 [(set_attr "length" "8,8,12,12,12,12")
4618 (set_attr "type" "multi")])
4619
4620 (define_insn "*movsfcc_no_fprs_int"
4621 [(set (match_operand:SF 0 "integer_register_operand" "=d,d,d")
4622 (if_then_else:SF (match_operator 1 "integer_relational_operator"
4623 [(match_operand 2 "icc_operand" "t,t,t")
4624 (const_int 0)])
4625 (match_operand:SF 3 "integer_register_operand" "0,d,d")
4626 (match_operand:SF 4 "integer_register_operand" "d,0,d")))
4627 (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v"))]
4628 "! TARGET_HAS_FPRS"
4629 "#"
4630 [(set_attr "length" "8,8,12")
4631 (set_attr "type" "multi")])
4632
4633 (define_split
4634 [(set (match_operand:SF 0 "register_operand" "")
4635 (if_then_else:SF (match_operator 1 "relational_operator"
4636 [(match_operand 2 "cc_operand" "")
4637 (const_int 0)])
4638 (match_operand:SF 3 "register_operand" "")
4639 (match_operand:SF 4 "register_operand" "")))
4640 (clobber (match_operand:CC_CCR 5 "cr_operand" ""))]
4641 "reload_completed"
4642 [(match_dup 6)]
4643 "operands[6] = frv_split_cond_move (operands);")
4644
4645 \f
4646 ;; ::::::::::::::::::::
4647 ;; ::
4648 ;; :: Minimum, maximum, and integer absolute value
4649 ;; ::
4650 ;; ::::::::::::::::::::
4651
4652 ;; These 'instructions' are provided to give the compiler a slightly better
4653 ;; nudge at register allocation, then it would if it constructed the
4654 ;; instructions from basic building blocks (since it indicates it prefers one
4655 ;; of the operands to be the same as the destination. It also helps the
4656 ;; earlier passes of the compiler, by not breaking things into small basic
4657 ;; blocks.
4658
4659 (define_expand "abssi2"
4660 [(parallel [(set (match_operand:SI 0 "integer_register_operand" "")
4661 (abs:SI (match_operand:SI 1 "integer_register_operand" "")))
4662 (clobber (match_dup 2))
4663 (clobber (match_dup 3))])]
4664 "TARGET_COND_MOVE"
4665 "
4666 {
4667 operands[2] = gen_reg_rtx (CCmode);
4668 operands[3] = gen_reg_rtx (CC_CCRmode);
4669 }")
4670
4671 (define_insn_and_split "*abssi2_internal"
4672 [(set (match_operand:SI 0 "integer_register_operand" "=d,d")
4673 (abs:SI (match_operand:SI 1 "integer_register_operand" "0,d")))
4674 (clobber (match_operand:CC 2 "icc_operand" "=t,t"))
4675 (clobber (match_operand:CC_CCR 3 "icr_operand" "=v,v"))]
4676 "TARGET_COND_MOVE"
4677 "#"
4678 "reload_completed"
4679 [(match_dup 4)]
4680 "operands[4] = frv_split_abs (operands);"
4681 [(set_attr "length" "12,16")
4682 (set_attr "type" "multi")])
4683
4684 (define_expand "sminsi3"
4685 [(parallel [(set (match_operand:SI 0 "integer_register_operand" "")
4686 (smin:SI (match_operand:SI 1 "integer_register_operand" "")
4687 (match_operand:SI 2 "gpr_or_int10_operand" "")))
4688 (clobber (match_dup 3))
4689 (clobber (match_dup 4))])]
4690 "TARGET_COND_MOVE"
4691 "
4692 {
4693 operands[3] = gen_reg_rtx (CCmode);
4694 operands[4] = gen_reg_rtx (CC_CCRmode);
4695 }")
4696
4697 (define_expand "smaxsi3"
4698 [(parallel [(set (match_operand:SI 0 "integer_register_operand" "")
4699 (smax:SI (match_operand:SI 1 "integer_register_operand" "")
4700 (match_operand:SI 2 "gpr_or_int10_operand" "")))
4701 (clobber (match_dup 3))
4702 (clobber (match_dup 4))])]
4703 "TARGET_COND_MOVE"
4704 "
4705 {
4706 operands[3] = gen_reg_rtx (CCmode);
4707 operands[4] = gen_reg_rtx (CC_CCRmode);
4708 }")
4709
4710 (define_insn_and_split "*minmax_si_signed"
4711 [(set (match_operand:SI 0 "integer_register_operand" "=d,d,&d")
4712 (match_operator:SI 1 "minmax_operator"
4713 [(match_operand:SI 2 "integer_register_operand" "%0,dO,d")
4714 (match_operand:SI 3 "gpr_or_int10_operand" "dO,0,dJ")]))
4715 (clobber (match_operand:CC 4 "icc_operand" "=t,t,t"))
4716 (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v"))]
4717 "TARGET_COND_MOVE"
4718 "#"
4719 "reload_completed"
4720 [(match_dup 6)]
4721 "operands[6] = frv_split_minmax (operands);"
4722 [(set_attr "length" "12,12,16")
4723 (set_attr "type" "multi")])
4724
4725 (define_expand "uminsi3"
4726 [(parallel [(set (match_operand:SI 0 "integer_register_operand" "")
4727 (umin:SI (match_operand:SI 1 "integer_register_operand" "")
4728 (match_operand:SI 2 "gpr_or_int10_operand" "")))
4729 (clobber (match_dup 3))
4730 (clobber (match_dup 4))])]
4731 "TARGET_COND_MOVE"
4732 "
4733 {
4734 operands[3] = gen_reg_rtx (CC_UNSmode);
4735 operands[4] = gen_reg_rtx (CC_CCRmode);
4736 }")
4737
4738 (define_expand "umaxsi3"
4739 [(parallel [(set (match_operand:SI 0 "integer_register_operand" "")
4740 (umax:SI (match_operand:SI 1 "integer_register_operand" "")
4741 (match_operand:SI 2 "gpr_or_int10_operand" "")))
4742 (clobber (match_dup 3))
4743 (clobber (match_dup 4))])]
4744 "TARGET_COND_MOVE"
4745 "
4746 {
4747 operands[3] = gen_reg_rtx (CC_UNSmode);
4748 operands[4] = gen_reg_rtx (CC_CCRmode);
4749 }")
4750
4751 (define_insn_and_split "*minmax_si_unsigned"
4752 [(set (match_operand:SI 0 "integer_register_operand" "=d,d,&d")
4753 (match_operator:SI 1 "minmax_operator"
4754 [(match_operand:SI 2 "integer_register_operand" "%0,dO,d")
4755 (match_operand:SI 3 "gpr_or_int10_operand" "dO,0,dJ")]))
4756 (clobber (match_operand:CC_UNS 4 "icc_operand" "=t,t,t"))
4757 (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v"))]
4758 "TARGET_COND_MOVE"
4759 "#"
4760 "reload_completed"
4761 [(match_dup 6)]
4762 "operands[6] = frv_split_minmax (operands);"
4763 [(set_attr "length" "12,12,16")
4764 (set_attr "type" "multi")])
4765
4766 (define_expand "sminsf3"
4767 [(parallel [(set (match_operand:SF 0 "fpr_operand" "")
4768 (smin:SF (match_operand:SF 1 "fpr_operand" "")
4769 (match_operand:SF 2 "fpr_operand" "")))
4770 (clobber (match_dup 3))
4771 (clobber (match_dup 4))])]
4772 "TARGET_COND_MOVE && TARGET_HARD_FLOAT"
4773 "
4774 {
4775 operands[3] = gen_reg_rtx (CC_FPmode);
4776 operands[4] = gen_reg_rtx (CC_CCRmode);
4777 }")
4778
4779 (define_expand "smaxsf3"
4780 [(parallel [(set (match_operand:SF 0 "fpr_operand" "")
4781 (smax:SF (match_operand:SF 1 "fpr_operand" "")
4782 (match_operand:SF 2 "fpr_operand" "")))
4783 (clobber (match_dup 3))
4784 (clobber (match_dup 4))])]
4785 "TARGET_COND_MOVE && TARGET_HARD_FLOAT"
4786 "
4787 {
4788 operands[3] = gen_reg_rtx (CC_FPmode);
4789 operands[4] = gen_reg_rtx (CC_CCRmode);
4790 }")
4791
4792 (define_insn_and_split "*minmax_sf"
4793 [(set (match_operand:SF 0 "fpr_operand" "=f,f,f")
4794 (match_operator:SF 1 "minmax_operator"
4795 [(match_operand:SF 2 "fpr_operand" "%0,f,f")
4796 (match_operand:SF 3 "fpr_operand" "f,0,f")]))
4797 (clobber (match_operand:CC_FP 4 "fcc_operand" "=u,u,u"))
4798 (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w"))]
4799 "TARGET_COND_MOVE && TARGET_HARD_FLOAT"
4800 "#"
4801 "reload_completed"
4802 [(match_dup 6)]
4803 "operands[6] = frv_split_minmax (operands);"
4804 [(set_attr "length" "12,12,16")
4805 (set_attr "type" "multi")])
4806
4807 (define_expand "smindf3"
4808 [(parallel [(set (match_operand:DF 0 "fpr_operand" "")
4809 (smin:DF (match_operand:DF 1 "fpr_operand" "")
4810 (match_operand:DF 2 "fpr_operand" "")))
4811 (clobber (match_dup 3))
4812 (clobber (match_dup 4))])]
4813 "TARGET_COND_MOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE"
4814 "
4815 {
4816 operands[3] = gen_reg_rtx (CC_FPmode);
4817 operands[4] = gen_reg_rtx (CC_CCRmode);
4818 }")
4819
4820 (define_expand "smaxdf3"
4821 [(parallel [(set (match_operand:DF 0 "fpr_operand" "")
4822 (smax:DF (match_operand:DF 1 "fpr_operand" "")
4823 (match_operand:DF 2 "fpr_operand" "")))
4824 (clobber (match_dup 3))
4825 (clobber (match_dup 4))])]
4826 "TARGET_COND_MOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE"
4827 "
4828 {
4829 operands[3] = gen_reg_rtx (CC_FPmode);
4830 operands[4] = gen_reg_rtx (CC_CCRmode);
4831 }")
4832
4833 (define_insn_and_split "*minmax_df"
4834 [(set (match_operand:DF 0 "fpr_operand" "=f,f,f")
4835 (match_operator:DF 1 "minmax_operator"
4836 [(match_operand:DF 2 "fpr_operand" "%0,f,f")
4837 (match_operand:DF 3 "fpr_operand" "f,0,f")]))
4838 (clobber (match_operand:CC_FP 4 "fcc_operand" "=u,u,u"))
4839 (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w"))]
4840 "TARGET_COND_MOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE"
4841 "#"
4842 "reload_completed"
4843 [(match_dup 6)]
4844 "operands[6] = frv_split_minmax (operands);"
4845 [(set_attr "length" "12,12,16")
4846 (set_attr "type" "multi")])
4847
4848 \f
4849 ;; ::::::::::::::::::::
4850 ;; ::
4851 ;; :: Call and branch instructions
4852 ;; ::
4853 ;; ::::::::::::::::::::
4854
4855 ;; Subroutine call instruction returning no value. Operand 0 is the function
4856 ;; to call; operand 1 is the number of bytes of arguments pushed (in mode
4857 ;; `SImode', except it is normally a `const_int'); operand 2 is the number of
4858 ;; registers used as operands.
4859
4860 ;; On most machines, operand 2 is not actually stored into the RTL pattern. It
4861 ;; is supplied for the sake of some RISC machines which need to put this
4862 ;; information into the assembler code; they can put it in the RTL instead of
4863 ;; operand 1.
4864
4865 (define_expand "call"
4866 [(use (match_operand:QI 0 "" ""))
4867 (use (match_operand 1 "" ""))
4868 (use (match_operand 2 "" ""))
4869 (use (match_operand 3 "" ""))]
4870 ""
4871 "
4872 {
4873 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
4874 rtx addr;
4875
4876 gcc_assert (GET_CODE (operands[0]) == MEM);
4877
4878 addr = XEXP (operands[0], 0);
4879 if (! call_operand (addr, Pmode))
4880 addr = force_reg (Pmode, addr);
4881
4882 if (! operands[2])
4883 operands[2] = const0_rtx;
4884
4885 if (TARGET_FDPIC)
4886 frv_expand_fdpic_call (operands, false, false);
4887 else
4888 emit_call_insn (gen_call_internal (addr, operands[1], operands[2], lr));
4889
4890 DONE;
4891 }")
4892
4893 (define_insn "call_internal"
4894 [(call (mem:QI (match_operand:SI 0 "call_operand" "S,dNOP"))
4895 (match_operand 1 "" ""))
4896 (use (match_operand 2 "" ""))
4897 (clobber (match_operand:SI 3 "lr_operand" "=l,l"))]
4898 "! TARGET_FDPIC"
4899 "@
4900 call %0
4901 call%i0l %M0"
4902 [(set_attr "length" "4")
4903 (set_attr "type" "call,jumpl")])
4904
4905 ;; The odd use of GR0 within the UNSPEC below prevents cseing or
4906 ;; hoisting function descriptor loads out of loops. This is almost
4907 ;; never desirable, since if we preserve the function descriptor in a
4908 ;; pair of registers, it takes two insns to move it to gr14/gr15, and
4909 ;; if it's in the stack, we just waste space with the store, since
4910 ;; we'll have to load back from memory anyway. And, in the worst
4911 ;; case, we may end up reusing a function descriptor still pointing at
4912 ;; a PLT entry, instead of to the resolved function, which means going
4913 ;; through the resolver for every call that uses the outdated value.
4914 ;; Bad!
4915
4916 ;; The explicit MEM inside the SPEC prevents the compiler from moving
4917 ;; the load before a branch after a NULL test, or before a store that
4918 ;; initializes a function descriptor.
4919
4920 (define_insn "movdi_ldd"
4921 [(set (match_operand:DI 0 "fdpic_fptr_operand" "=e")
4922 (unspec:DI [(mem:DI (match_operand:SI 1 "ldd_address_operand" "p"))
4923 (reg:SI 0)] UNSPEC_LDD))]
4924 ""
4925 "ldd%I1 %M1, %0"
4926 [(set_attr "length" "4")
4927 (set_attr "type" "gload")])
4928
4929 (define_insn "call_fdpicdi"
4930 [(call (mem:QI (match_operand:DI 0 "fdpic_fptr_operand" "W"))
4931 (match_operand 1 "" ""))
4932 (clobber (match_operand:SI 2 "lr_operand" "=l"))]
4933 "TARGET_FDPIC"
4934 "call%i0l %M0"
4935 [(set_attr "length" "4")
4936 (set_attr "type" "jumpl")])
4937
4938 (define_insn "call_fdpicsi"
4939 [(call (mem:QI (match_operand:SI 0 "call_operand" "S,dNOP"))
4940 (match_operand 1 "" ""))
4941 (use (match_operand 2 "" ""))
4942 (use (match_operand:SI 3 "fdpic_operand" "Z,Z"))
4943 (clobber (match_operand:SI 4 "lr_operand" "=l,l"))]
4944 "TARGET_FDPIC"
4945 "@
4946 call %0
4947 call%i0l %M0"
4948 [(set_attr "length" "4")
4949 (set_attr "type" "call,jumpl")])
4950
4951 (define_expand "sibcall"
4952 [(use (match_operand:QI 0 "" ""))
4953 (use (match_operand 1 "" ""))
4954 (use (match_operand 2 "" ""))
4955 (use (match_operand 3 "" ""))]
4956 ""
4957 "
4958 {
4959 rtx addr;
4960
4961 gcc_assert (GET_CODE (operands[0]) == MEM);
4962
4963 addr = XEXP (operands[0], 0);
4964 if (! sibcall_operand (addr, Pmode))
4965 addr = force_reg (Pmode, addr);
4966
4967 if (! operands[2])
4968 operands[2] = const0_rtx;
4969
4970 if (TARGET_FDPIC)
4971 frv_expand_fdpic_call (operands, false, true);
4972 else
4973 emit_call_insn (gen_sibcall_internal (addr, operands[1], operands[2]));
4974
4975 DONE;
4976 }")
4977
4978 ;; It might seem that these sibcall patterns are missing references to
4979 ;; LR, but they're not necessary because sibcall_epilogue will make
4980 ;; sure LR is restored, and having LR here will set
4981 ;; regs_ever_used[REG_LR], forcing it to be saved on the stack, and
4982 ;; then restored in sibcalls and regular return code paths, even if
4983 ;; the function becomes a leaf function after tail-call elimination.
4984
4985 ;; We must not use a call-saved register here. `W' limits ourselves
4986 ;; to gr14 or gr15, but since we're almost running out of constraint
4987 ;; letters, and most other call-clobbered registers are often used for
4988 ;; argument-passing, this will do.
4989 (define_insn "sibcall_internal"
4990 [(call (mem:QI (match_operand:SI 0 "sibcall_operand" "WNOP"))
4991 (match_operand 1 "" ""))
4992 (use (match_operand 2 "" ""))
4993 (return)]
4994 "! TARGET_FDPIC"
4995 "jmp%i0l %M0"
4996 [(set_attr "length" "4")
4997 (set_attr "type" "jumpl")])
4998
4999 (define_insn "sibcall_fdpicdi"
5000 [(call (mem:QI (match_operand:DI 0 "fdpic_fptr_operand" "W"))
5001 (match_operand 1 "" ""))
5002 (return)]
5003 "TARGET_FDPIC"
5004 "jmp%i0l %M0"
5005 [(set_attr "length" "4")
5006 (set_attr "type" "jumpl")])
5007
5008
5009 ;; Subroutine call instruction returning a value. Operand 0 is the hard
5010 ;; register in which the value is returned. There are three more operands, the
5011 ;; same as the three operands of the `call' instruction (but with numbers
5012 ;; increased by one).
5013
5014 ;; Subroutines that return `BLKmode' objects use the `call' insn.
5015
5016 (define_expand "call_value"
5017 [(use (match_operand 0 "" ""))
5018 (use (match_operand:QI 1 "" ""))
5019 (use (match_operand 2 "" ""))
5020 (use (match_operand 3 "" ""))
5021 (use (match_operand 4 "" ""))]
5022 ""
5023 "
5024 {
5025 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
5026 rtx addr;
5027
5028 gcc_assert (GET_CODE (operands[1]) == MEM);
5029
5030 addr = XEXP (operands[1], 0);
5031 if (! call_operand (addr, Pmode))
5032 addr = force_reg (Pmode, addr);
5033
5034 if (! operands[3])
5035 operands[3] = const0_rtx;
5036
5037 if (TARGET_FDPIC)
5038 frv_expand_fdpic_call (operands, true, false);
5039 else
5040 emit_call_insn (gen_call_value_internal (operands[0], addr, operands[2],
5041 operands[3], lr));
5042
5043 DONE;
5044 }")
5045
5046 (define_insn "call_value_internal"
5047 [(set (match_operand 0 "register_operand" "=d,d")
5048 (call (mem:QI (match_operand:SI 1 "call_operand" "S,dNOP"))
5049 (match_operand 2 "" "")))
5050 (use (match_operand 3 "" ""))
5051 (clobber (match_operand:SI 4 "lr_operand" "=l,l"))]
5052 "! TARGET_FDPIC"
5053 "@
5054 call %1
5055 call%i1l %M1"
5056 [(set_attr "length" "4")
5057 (set_attr "type" "call,jumpl")])
5058
5059 (define_insn "call_value_fdpicdi"
5060 [(set (match_operand 0 "register_operand" "=d")
5061 (call (mem:QI (match_operand:DI 1 "fdpic_fptr_operand" "W"))
5062 (match_operand 2 "" "")))
5063 (clobber (match_operand:SI 3 "lr_operand" "=l"))]
5064 "TARGET_FDPIC"
5065 "call%i1l %M1"
5066 [(set_attr "length" "4")
5067 (set_attr "type" "jumpl")])
5068
5069 (define_insn "call_value_fdpicsi"
5070 [(set (match_operand 0 "register_operand" "=d,d")
5071 (call (mem:QI (match_operand:SI 1 "call_operand" "S,dNOP"))
5072 (match_operand 2 "" "")))
5073 (use (match_operand 3 "" ""))
5074 (use (match_operand:SI 4 "fdpic_operand" "Z,Z"))
5075 (clobber (match_operand:SI 5 "lr_operand" "=l,l"))]
5076 "TARGET_FDPIC"
5077 "@
5078 call %1
5079 call%i1l %M1"
5080 [(set_attr "length" "4")
5081 (set_attr "type" "call,jumpl")])
5082
5083 (define_expand "sibcall_value"
5084 [(use (match_operand 0 "" ""))
5085 (use (match_operand:QI 1 "" ""))
5086 (use (match_operand 2 "" ""))
5087 (use (match_operand 3 "" ""))
5088 (use (match_operand 4 "" ""))]
5089 ""
5090 "
5091 {
5092 rtx addr;
5093
5094 gcc_assert (GET_CODE (operands[1]) == MEM);
5095
5096 addr = XEXP (operands[1], 0);
5097 if (! sibcall_operand (addr, Pmode))
5098 addr = force_reg (Pmode, addr);
5099
5100 if (! operands[3])
5101 operands[3] = const0_rtx;
5102
5103 if (TARGET_FDPIC)
5104 frv_expand_fdpic_call (operands, true, true);
5105 else
5106 emit_call_insn (gen_sibcall_value_internal (operands[0], addr, operands[2],
5107 operands[3]));
5108 DONE;
5109 }")
5110
5111 (define_insn "sibcall_value_internal"
5112 [(set (match_operand 0 "register_operand" "=d")
5113 (call (mem:QI (match_operand:SI 1 "sibcall_operand" "WNOP"))
5114 (match_operand 2 "" "")))
5115 (use (match_operand 3 "" ""))
5116 (return)]
5117 "! TARGET_FDPIC"
5118 "jmp%i1l %M1"
5119 [(set_attr "length" "4")
5120 (set_attr "type" "jumpl")])
5121
5122 (define_insn "sibcall_value_fdpicdi"
5123 [(set (match_operand 0 "register_operand" "=d")
5124 (call (mem:QI (match_operand:DI 1 "fdpic_fptr_operand" "W"))
5125 (match_operand 2 "" "")))
5126 (return)]
5127 "TARGET_FDPIC"
5128 "jmp%i1l %M1"
5129 [(set_attr "length" "4")
5130 (set_attr "type" "jumpl")])
5131
5132 ;; return instruction generated instead of jmp to epilog
5133 (define_expand "return"
5134 [(parallel [(return)
5135 (use (match_dup 0))
5136 (use (const_int 1))])]
5137 "direct_return_p ()"
5138 "
5139 {
5140 operands[0] = gen_rtx_REG (Pmode, LR_REGNO);
5141 }")
5142
5143 ;; return instruction generated by the epilogue
5144 (define_expand "epilogue_return"
5145 [(parallel [(return)
5146 (use (match_operand:SI 0 "register_operand" ""))
5147 (use (const_int 0))])]
5148 ""
5149 "")
5150
5151 (define_insn "*return_internal"
5152 [(return)
5153 (use (match_operand:SI 0 "register_operand" "l,d"))
5154 (use (match_operand:SI 1 "immediate_operand" "n,n"))]
5155 ""
5156 "@
5157 ret
5158 jmpl @(%0,%.)"
5159 [(set_attr "length" "4")
5160 (set_attr "type" "jump,jumpl")])
5161
5162 (define_insn "*return_true"
5163 [(set (pc)
5164 (if_then_else (match_operator 0 "integer_relational_operator"
5165 [(match_operand 1 "icc_operand" "t")
5166 (const_int 0)])
5167 (return)
5168 (pc)))]
5169 "direct_return_p ()"
5170 "b%c0lr %1,%#"
5171 [(set_attr "length" "4")
5172 (set_attr "type" "jump")])
5173
5174 (define_insn "*return_false"
5175 [(set (pc)
5176 (if_then_else (match_operator 0 "integer_relational_operator"
5177 [(match_operand 1 "icc_operand" "t")
5178 (const_int 0)])
5179 (pc)
5180 (return)))]
5181 "direct_return_p ()"
5182 "b%C0lr %1,%#"
5183 [(set_attr "length" "4")
5184 (set_attr "type" "jump")])
5185
5186 ;; A version of addsi3 for deallocating stack space at the end of the
5187 ;; epilogue. The addition is done in parallel with an (unspec_volatile),
5188 ;; which represents the clobbering of the deallocated space.
5189 (define_insn "stack_adjust"
5190 [(set (match_operand:SI 0 "register_operand" "=d")
5191 (plus:SI (match_operand:SI 1 "register_operand" "d")
5192 (match_operand:SI 2 "general_operand" "dNOP")))
5193 (unspec_volatile [(const_int 0)] UNSPEC_STACK_ADJUST)]
5194 ""
5195 "add%I2 %1,%2,%0"
5196 [(set_attr "length" "4")
5197 (set_attr "type" "int")])
5198
5199 ;; Normal unconditional jump
5200
5201 ;; Use the "call" instruction for long branches, but prefer to use "bra" for
5202 ;; short ones since it does not force us to save the link register.
5203
5204 ;; This define_insn uses the branch-shortening code to decide which
5205 ;; instruction it emits. Since the main branch-shortening interface is
5206 ;; through get_attr_length(), the two alternatives must be given different
5207 ;; lengths. Here we pretend that the far jump is 8 rather than 4 bytes
5208 ;; long, though both alternatives are really the same size.
5209 (define_insn "jump"
5210 [(set (pc) (label_ref (match_operand 0 "" "")))]
5211 ""
5212 "*
5213 {
5214 if (get_attr_length (insn) == 4)
5215 return \"bra %l0\";
5216 else
5217 return \"call %l0\";
5218 }"
5219 [(set (attr "length")
5220 (if_then_else
5221 (and (ge (minus (match_dup 0) (pc)) (const_int -32768))
5222 (le (minus (match_dup 0) (pc)) (const_int 32764)))
5223 (const_int 4)
5224 (const_int 8)))
5225 (set (attr "far_jump")
5226 (if_then_else
5227 (eq_attr "length" "4")
5228 (const_string "no")
5229 (const_string "yes")))
5230 (set (attr "type")
5231 (if_then_else
5232 (eq_attr "length" "4")
5233 (const_string "jump")
5234 (const_string "call")))])
5235
5236 ;; Indirect jump through a register
5237 (define_insn "indirect_jump"
5238 [(set (pc) (match_operand:SI 0 "register_operand" "d,l"))]
5239 ""
5240 "@
5241 jmpl @(%0,%.)
5242 bralr"
5243 [(set_attr "length" "4")
5244 (set_attr "type" "jumpl,branch")])
5245
5246 ;; Instruction to jump to a variable address. This is a low-level capability
5247 ;; which can be used to implement a dispatch table when there is no `casesi'
5248 ;; pattern. Either the 'casesi' pattern or the 'tablejump' pattern, or both,
5249 ;; MUST be present in this file.
5250
5251 ;; This pattern requires two operands: the address or offset, and a label which
5252 ;; should immediately precede the jump table. If the macro
5253 ;; `CASE_VECTOR_PC_RELATIVE' is defined then the first operand is an offset
5254 ;; which counts from the address of the table; otherwise, it is an absolute
5255 ;; address to jump to. In either case, the first operand has mode `Pmode'.
5256
5257 ;; The `tablejump' insn is always the last insn before the jump table it uses.
5258 ;; Its assembler code normally has no need to use the second operand, but you
5259 ;; should incorporate it in the RTL pattern so that the jump optimizer will not
5260 ;; delete the table as unreachable code.
5261
5262 (define_expand "tablejump"
5263 [(parallel [(set (pc) (match_operand:SI 0 "address_operand" "p"))
5264 (use (label_ref (match_operand 1 "" "")))])]
5265 "!flag_pic"
5266 "")
5267
5268 (define_insn "tablejump_insn"
5269 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
5270 (use (label_ref (match_operand 1 "" "")))]
5271 ""
5272 "jmp%I0l %M0"
5273 [(set_attr "length" "4")
5274 (set_attr "type" "jumpl")])
5275
5276 ;; Implement switch statements when generating PIC code. Switches are
5277 ;; implemented by `tablejump' when not using -fpic.
5278
5279 ;; Emit code here to do the range checking and make the index zero based.
5280 ;; operand 0 is the index
5281 ;; operand 1 is the lower bound
5282 ;; operand 2 is the range of indices (highest - lowest + 1)
5283 ;; operand 3 is the label that precedes the table itself
5284 ;; operand 4 is the fall through label
5285
5286 (define_expand "casesi"
5287 [(use (match_operand:SI 0 "integer_register_operand" ""))
5288 (use (match_operand:SI 1 "const_int_operand" ""))
5289 (use (match_operand:SI 2 "const_int_operand" ""))
5290 (use (match_operand 3 "" ""))
5291 (use (match_operand 4 "" ""))]
5292 "flag_pic"
5293 "
5294 {
5295 rtx indx;
5296 rtx scale;
5297 rtx low = operands[1];
5298 rtx range = operands[2];
5299 rtx table = operands[3];
5300 rtx treg;
5301 rtx fail = operands[4];
5302 rtx mem;
5303 rtx reg2;
5304 rtx reg3;
5305
5306 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
5307
5308 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
5309
5310 /* If we can't generate an immediate instruction, promote to register. */
5311 if (! IN_RANGE (INTVAL (range), -2048, 2047))
5312 range = force_reg (SImode, range);
5313
5314 /* If low bound is 0, we don't have to subtract it. */
5315 if (INTVAL (operands[1]) == 0)
5316 indx = operands[0];
5317 else
5318 {
5319 indx = gen_reg_rtx (SImode);
5320 if (IN_RANGE (INTVAL (low), -2047, 2048))
5321 emit_insn (gen_addsi3 (indx, operands[0], GEN_INT (- INTVAL (low))));
5322 else
5323 emit_insn (gen_subsi3 (indx, operands[0], force_reg (SImode, low)));
5324 }
5325
5326 /* Do an unsigned comparison (in the proper mode) between the index
5327 expression and the value which represents the length of the range.
5328 Since we just finished subtracting the lower bound of the range
5329 from the index expression, this comparison allows us to simultaneously
5330 check that the original index expression value is both greater than
5331 or equal to the minimum value of the range and less than or equal to
5332 the maximum value of the range. */
5333
5334 emit_cmp_and_jump_insns (indx, range, GTU, NULL_RTX, SImode, 1, fail);
5335
5336 /* Move the table address to a register. */
5337 treg = gen_reg_rtx (Pmode);
5338 emit_insn (gen_movsi (treg, gen_rtx_LABEL_REF (VOIDmode, table)));
5339
5340 /* Scale index-low by wordsize. */
5341 scale = gen_reg_rtx (SImode);
5342 emit_insn (gen_ashlsi3 (scale, indx, const2_rtx));
5343
5344 /* Load the address, add the start of the table back in,
5345 and jump to it. */
5346 mem = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, scale, treg));
5347 reg2 = gen_reg_rtx (SImode);
5348 reg3 = gen_reg_rtx (SImode);
5349 emit_insn (gen_movsi (reg2, mem));
5350 emit_insn (gen_addsi3 (reg3, reg2, treg));
5351 emit_jump_insn (gen_tablejump_insn (reg3, table));
5352 DONE;
5353 }")
5354
5355 \f
5356 ;; ::::::::::::::::::::
5357 ;; ::
5358 ;; :: Prologue and Epilogue instructions
5359 ;; ::
5360 ;; ::::::::::::::::::::
5361
5362 ;; Called after register allocation to add any instructions needed for the
5363 ;; prologue. Using a prologue insn is favored compared to putting all of the
5364 ;; instructions in the FUNCTION_PROLOGUE macro, since it allows the scheduler
5365 ;; to intermix instructions with the saves of the caller saved registers. In
5366 ;; some cases, it might be necessary to emit a barrier instruction as the last
5367 ;; insn to prevent such scheduling.
5368 (define_expand "prologue"
5369 [(const_int 1)]
5370 ""
5371 "
5372 {
5373 frv_expand_prologue ();
5374 DONE;
5375 }")
5376
5377 ;; Called after register allocation to add any instructions needed for the
5378 ;; epilogue. Using an epilogue insn is favored compared to putting all of the
5379 ;; instructions in the FUNCTION_EPILOGUE macro, since it allows the scheduler
5380 ;; to intermix instructions with the restores of the caller saved registers.
5381 ;; In some cases, it might be necessary to emit a barrier instruction as the
5382 ;; first insn to prevent such scheduling.
5383 (define_expand "epilogue"
5384 [(const_int 2)]
5385 ""
5386 "
5387 {
5388 frv_expand_epilogue (true);
5389 DONE;
5390 }")
5391
5392 ;; This pattern, if defined, emits RTL for exit from a function without the final
5393 ;; branch back to the calling function. This pattern will be emitted before any
5394 ;; sibling call (aka tail call) sites.
5395 ;;
5396 ;; The sibcall_epilogue pattern must not clobber any arguments used for
5397 ;; parameter passing or any stack slots for arguments passed to the current
5398 ;; function.
5399 (define_expand "sibcall_epilogue"
5400 [(const_int 3)]
5401 ""
5402 "
5403 {
5404 frv_expand_epilogue (false);
5405 DONE;
5406 }")
5407
5408 ;; Set up the pic register to hold the address of the pic table
5409 (define_insn "pic_prologue"
5410 [(set (match_operand:SI 0 "integer_register_operand" "=d")
5411 (unspec_volatile:SI [(const_int 0)] UNSPEC_PIC_PROLOGUE))
5412 (clobber (match_operand:SI 1 "lr_operand" "=l"))
5413 (clobber (match_operand:SI 2 "integer_register_operand" "=d"))]
5414 ""
5415 "*
5416 {
5417 static int frv_pic_labelno = 0;
5418
5419 operands[3] = GEN_INT (frv_pic_labelno++);
5420 return \"call %P3\\n%P3:\;movsg %1, %0\;sethi #gprelhi(%P3), %2\;setlo #gprello(%P3), %2\;sub %0,%2,%0\";
5421 }"
5422 [(set_attr "length" "16")
5423 (set_attr "type" "multi")])
5424 \f
5425 ;; ::::::::::::::::::::
5426 ;; ::
5427 ;; :: Miscellaneous instructions
5428 ;; ::
5429 ;; ::::::::::::::::::::
5430
5431 ;; No operation, needed in case the user uses -g but not -O.
5432 (define_insn "nop"
5433 [(const_int 0)]
5434 ""
5435 "nop"
5436 [(set_attr "length" "4")
5437 (set_attr "type" "int")])
5438
5439 (define_insn "fnop"
5440 [(const_int 1)]
5441 ""
5442 "fnop"
5443 [(set_attr "length" "4")
5444 (set_attr "type" "fnop")])
5445
5446 (define_insn "mnop"
5447 [(const_int 2)]
5448 ""
5449 "mnop"
5450 [(set_attr "length" "4")
5451 (set_attr "type" "mnop")])
5452
5453 ;; Pseudo instruction that prevents the scheduler from moving code above this
5454 ;; point. Note, type unknown is used to make sure the VLIW instructions are
5455 ;; not continued past this point.
5456 (define_insn "blockage"
5457 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
5458 ""
5459 "# blockage"
5460 [(set_attr "length" "0")
5461 (set_attr "type" "unknown")])
5462 \f
5463 ;; ::::::::::::::::::::
5464 ;; ::
5465 ;; :: Media instructions
5466 ;; ::
5467 ;; ::::::::::::::::::::
5468
5469 ;; Unimplemented instructions:
5470 ;; - MCMPSH, MCMPUH
5471
5472 (define_constants
5473 [(UNSPEC_MLOGIC 100)
5474 (UNSPEC_MNOT 101)
5475 (UNSPEC_MAVEH 102)
5476 (UNSPEC_MSATH 103)
5477 (UNSPEC_MADDH 104)
5478 (UNSPEC_MQADDH 105)
5479 (UNSPEC_MPACKH 106)
5480 (UNSPEC_MUNPACKH 107)
5481 (UNSPEC_MDPACKH 108)
5482 (UNSPEC_MBTOH 109)
5483 (UNSPEC_MHTOB 110)
5484 (UNSPEC_MROT 111)
5485 (UNSPEC_MSHIFT 112)
5486 (UNSPEC_MEXPDHW 113)
5487 (UNSPEC_MEXPDHD 114)
5488 (UNSPEC_MWCUT 115)
5489 (UNSPEC_MMULH 116)
5490 (UNSPEC_MMULXH 117)
5491 (UNSPEC_MMACH 118)
5492 (UNSPEC_MMRDH 119)
5493 (UNSPEC_MQMULH 120)
5494 (UNSPEC_MQMULXH 121)
5495 (UNSPEC_MQMACH 122)
5496 (UNSPEC_MCPX 123)
5497 (UNSPEC_MQCPX 124)
5498 (UNSPEC_MCUT 125)
5499 (UNSPEC_MRDACC 126)
5500 (UNSPEC_MRDACCG 127)
5501 (UNSPEC_MWTACC 128)
5502 (UNSPEC_MWTACCG 129)
5503 (UNSPEC_MTRAP 130)
5504 (UNSPEC_MCLRACC 131)
5505 (UNSPEC_MCLRACCA 132)
5506 (UNSPEC_MCOP1 133)
5507 (UNSPEC_MCOP2 134)
5508 (UNSPEC_MDUNPACKH 135)
5509 (UNSPEC_MDUNPACKH_INTERNAL 136)
5510 (UNSPEC_MBTOHE 137)
5511 (UNSPEC_MBTOHE_INTERNAL 138)
5512 (UNSPEC_MBTOHE 137)
5513 (UNSPEC_MBTOHE_INTERNAL 138)
5514 (UNSPEC_MQMACH2 139)
5515 (UNSPEC_MADDACC 140)
5516 (UNSPEC_MDADDACC 141)
5517 (UNSPEC_MABSHS 142)
5518 (UNSPEC_MDROTLI 143)
5519 (UNSPEC_MCPLHI 144)
5520 (UNSPEC_MCPLI 145)
5521 (UNSPEC_MDCUTSSI 146)
5522 (UNSPEC_MQSATHS 147)
5523 (UNSPEC_MHSETLOS 148)
5524 (UNSPEC_MHSETLOH 149)
5525 (UNSPEC_MHSETHIS 150)
5526 (UNSPEC_MHSETHIH 151)
5527 (UNSPEC_MHDSETS 152)
5528 (UNSPEC_MHDSETH 153)
5529 (UNSPEC_MQLCLRHS 154)
5530 (UNSPEC_MQLMTHS 155)
5531 (UNSPEC_MQSLLHI 156)
5532 (UNSPEC_MQSRAHI 157)
5533 (UNSPEC_MASACCS 158)
5534 (UNSPEC_MDASACCS 159)
5535 ])
5536
5537 ;; Logic operations: type "mlogic"
5538
5539 (define_expand "mand"
5540 [(set (match_operand:SI 0 "fpr_operand" "")
5541 (unspec:SI [(match_operand:SI 1 "fpr_operand" "")
5542 (match_operand:SI 2 "fpr_operand" "")
5543 (match_dup 3)]
5544 UNSPEC_MLOGIC))]
5545 "TARGET_MEDIA"
5546 "operands[3] = GEN_INT (FRV_BUILTIN_MAND);")
5547
5548 (define_expand "mor"
5549 [(set (match_operand:SI 0 "fpr_operand" "")
5550 (unspec:SI [(match_operand:SI 1 "fpr_operand" "")
5551 (match_operand:SI 2 "fpr_operand" "")
5552 (match_dup 3)]
5553 UNSPEC_MLOGIC))]
5554 "TARGET_MEDIA"
5555 "operands[3] = GEN_INT (FRV_BUILTIN_MOR);")
5556
5557 (define_expand "mxor"
5558 [(set (match_operand:SI 0 "fpr_operand" "")
5559 (unspec:SI [(match_operand:SI 1 "fpr_operand" "")
5560 (match_operand:SI 2 "fpr_operand" "")
5561 (match_dup 3)]
5562 UNSPEC_MLOGIC))]
5563 "TARGET_MEDIA"
5564 "operands[3] = GEN_INT (FRV_BUILTIN_MXOR);")
5565
5566 (define_insn "*mlogic"
5567 [(set (match_operand:SI 0 "fpr_operand" "=f")
5568 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
5569 (match_operand:SI 2 "fpr_operand" "f")
5570 (match_operand:SI 3 "const_int_operand" "n")]
5571 UNSPEC_MLOGIC))]
5572 "TARGET_MEDIA"
5573 "*
5574 {
5575 switch (INTVAL (operands[3]))
5576 {
5577 default: break;
5578 case FRV_BUILTIN_MAND: return \"mand %1, %2, %0\";
5579 case FRV_BUILTIN_MOR: return \"mor %1, %2, %0\";
5580 case FRV_BUILTIN_MXOR: return \"mxor %1, %2, %0\";
5581 }
5582
5583 fatal_insn (\"Bad media insn, mlogic\", insn);
5584 }"
5585 [(set_attr "length" "4")
5586 (set_attr "type" "mlogic")])
5587
5588 (define_insn "*cond_exec_mlogic"
5589 [(cond_exec
5590 (match_operator 0 "ccr_eqne_operator"
5591 [(match_operand 1 "cr_operand" "C")
5592 (const_int 0)])
5593 (set (match_operand:SI 2 "fpr_operand" "=f")
5594 (unspec:SI [(match_operand:SI 3 "fpr_operand" "f")
5595 (match_operand:SI 4 "fpr_operand" "f")
5596 (match_operand:SI 5 "const_int_operand" "n")]
5597 UNSPEC_MLOGIC)))]
5598 "TARGET_MEDIA"
5599 "*
5600 {
5601 switch (INTVAL (operands[5]))
5602 {
5603 default: break;
5604 case FRV_BUILTIN_MAND: return \"cmand %3, %4, %2, %1, %e0\";
5605 case FRV_BUILTIN_MOR: return \"cmor %3, %4, %2, %1, %e0\";
5606 case FRV_BUILTIN_MXOR: return \"cmxor %3, %4, %2, %1, %e0\";
5607 }
5608
5609 fatal_insn (\"Bad media insn, cond_exec_mlogic\", insn);
5610 }"
5611 [(set_attr "length" "4")
5612 (set_attr "type" "mlogic")])
5613
5614 ;; Logical not: type "mlogic"
5615
5616 (define_insn "mnot"
5617 [(set (match_operand:SI 0 "fpr_operand" "=f")
5618 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")] UNSPEC_MNOT))]
5619 "TARGET_MEDIA"
5620 "mnot %1, %0"
5621 [(set_attr "length" "4")
5622 (set_attr "type" "mlogic")])
5623
5624 (define_insn "*cond_exec_mnot"
5625 [(cond_exec
5626 (match_operator 0 "ccr_eqne_operator"
5627 [(match_operand 1 "cr_operand" "C")
5628 (const_int 0)])
5629 (set (match_operand:SI 2 "fpr_operand" "=f")
5630 (unspec:SI [(match_operand:SI 3 "fpr_operand" "f")] UNSPEC_MNOT)))]
5631 "TARGET_MEDIA"
5632 "cmnot %3, %2, %1, %e0"
5633 [(set_attr "length" "4")
5634 (set_attr "type" "mlogic")])
5635
5636 ;; Dual average (halfword): type "maveh"
5637
5638 (define_insn "maveh"
5639 [(set (match_operand:SI 0 "fpr_operand" "=f")
5640 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
5641 (match_operand:SI 2 "fpr_operand" "f")]
5642 UNSPEC_MAVEH))]
5643 "TARGET_MEDIA"
5644 "maveh %1, %2, %0"
5645 [(set_attr "length" "4")
5646 (set_attr "type" "maveh")])
5647
5648 ;; Dual saturation (halfword): type "msath"
5649
5650 (define_expand "msaths"
5651 [(set (match_operand:SI 0 "fpr_operand" "=f")
5652 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
5653 (match_operand:SI 2 "fpr_operand" "f")
5654 (match_dup 3)]
5655 UNSPEC_MSATH))]
5656 "TARGET_MEDIA"
5657 "operands[3] = GEN_INT (FRV_BUILTIN_MSATHS);")
5658
5659 (define_expand "msathu"
5660 [(set (match_operand:SI 0 "fpr_operand" "=f")
5661 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
5662 (match_operand:SI 2 "fpr_operand" "f")
5663 (match_dup 3)]
5664 UNSPEC_MSATH))]
5665 "TARGET_MEDIA"
5666 "operands[3] = GEN_INT (FRV_BUILTIN_MSATHU);")
5667
5668 (define_insn "*msath"
5669 [(set (match_operand:SI 0 "fpr_operand" "=f")
5670 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
5671 (match_operand:SI 2 "fpr_operand" "f")
5672 (match_operand:SI 3 "const_int_operand" "n")]
5673 UNSPEC_MSATH))]
5674 "TARGET_MEDIA"
5675 "*
5676 {
5677 switch (INTVAL (operands[3]))
5678 {
5679 default: break;
5680 case FRV_BUILTIN_MSATHS: return \"msaths %1, %2, %0\";
5681 case FRV_BUILTIN_MSATHU: return \"msathu %1, %2, %0\";
5682 }
5683
5684 fatal_insn (\"Bad media insn, msath\", insn);
5685 }"
5686 [(set_attr "length" "4")
5687 (set_attr "type" "msath")])
5688
5689 ;; Dual addition/subtraction with saturation (halfword): type "maddh"
5690
5691 (define_expand "maddhss"
5692 [(set (match_operand:SI 0 "fpr_operand" "=f")
5693 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
5694 (match_operand:SI 2 "fpr_operand" "f")
5695 (match_dup 3)]
5696 UNSPEC_MADDH))]
5697 "TARGET_MEDIA"
5698 "operands[3] = GEN_INT (FRV_BUILTIN_MADDHSS);")
5699
5700 (define_expand "maddhus"
5701 [(set (match_operand:SI 0 "fpr_operand" "=f")
5702 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
5703 (match_operand:SI 2 "fpr_operand" "f")
5704 (match_dup 3)]
5705 UNSPEC_MADDH))]
5706 "TARGET_MEDIA"
5707 "operands[3] = GEN_INT (FRV_BUILTIN_MADDHUS);")
5708
5709 (define_expand "msubhss"
5710 [(set (match_operand:SI 0 "fpr_operand" "=f")
5711 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
5712 (match_operand:SI 2 "fpr_operand" "f")
5713 (match_dup 3)]
5714 UNSPEC_MADDH))]
5715 "TARGET_MEDIA"
5716 "operands[3] = GEN_INT (FRV_BUILTIN_MSUBHSS);")
5717
5718 (define_expand "msubhus"
5719 [(set (match_operand:SI 0 "fpr_operand" "=f")
5720 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
5721 (match_operand:SI 2 "fpr_operand" "f")
5722 (match_dup 3)]
5723 UNSPEC_MADDH))]
5724 "TARGET_MEDIA"
5725 "operands[3] = GEN_INT (FRV_BUILTIN_MSUBHUS);")
5726
5727 (define_insn "*maddh"
5728 [(set (match_operand:SI 0 "fpr_operand" "=f")
5729 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
5730 (match_operand:SI 2 "fpr_operand" "f")
5731 (match_operand:SI 3 "const_int_operand" "n")]
5732 UNSPEC_MADDH))]
5733 "TARGET_MEDIA"
5734 "*
5735 {
5736 switch (INTVAL (operands[3]))
5737 {
5738 default: break;
5739 case FRV_BUILTIN_MADDHSS: return \"maddhss %1, %2, %0\";
5740 case FRV_BUILTIN_MADDHUS: return \"maddhus %1, %2, %0\";
5741 case FRV_BUILTIN_MSUBHSS: return \"msubhss %1, %2, %0\";
5742 case FRV_BUILTIN_MSUBHUS: return \"msubhus %1, %2, %0\";
5743 }
5744
5745 fatal_insn (\"Bad media insn, maddh\", insn);
5746 }"
5747 [(set_attr "length" "4")
5748 (set_attr "type" "maddh")])
5749
5750 (define_insn "*cond_exec_maddh"
5751 [(cond_exec
5752 (match_operator 0 "ccr_eqne_operator"
5753 [(match_operand 1 "cr_operand" "C")
5754 (const_int 0)])
5755 (set (match_operand:SI 2 "fpr_operand" "=f")
5756 (unspec:SI [(match_operand:SI 3 "fpr_operand" "f")
5757 (match_operand:SI 4 "fpr_operand" "f")
5758 (match_operand:SI 5 "const_int_operand" "n")]
5759 UNSPEC_MADDH)))]
5760 "TARGET_MEDIA"
5761 "*
5762 {
5763 switch (INTVAL (operands[5]))
5764 {
5765 default: break;
5766 case FRV_BUILTIN_MADDHSS: return \"cmaddhss %3, %4, %2, %1, %e0\";
5767 case FRV_BUILTIN_MADDHUS: return \"cmaddhus %3, %4, %2, %1, %e0\";
5768 case FRV_BUILTIN_MSUBHSS: return \"cmsubhss %3, %4, %2, %1, %e0\";
5769 case FRV_BUILTIN_MSUBHUS: return \"cmsubhus %3, %4, %2, %1, %e0\";
5770 }
5771
5772 fatal_insn (\"Bad media insn, cond_exec_maddh\", insn);
5773 }"
5774 [(set_attr "length" "4")
5775 (set_attr "type" "maddh")])
5776
5777 ;; Quad addition/subtraction with saturation (halfword): type "mqaddh"
5778
5779 (define_expand "mqaddhss"
5780 [(set (match_operand:DI 0 "even_fpr_operand" "=h")
5781 (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
5782 (match_operand:DI 2 "even_fpr_operand" "h")
5783 (match_dup 3)]
5784 UNSPEC_MQADDH))]
5785 "TARGET_MEDIA"
5786 "operands[3] = GEN_INT (FRV_BUILTIN_MQADDHSS);")
5787
5788 (define_expand "mqaddhus"
5789 [(set (match_operand:DI 0 "even_fpr_operand" "=h")
5790 (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
5791 (match_operand:DI 2 "even_fpr_operand" "h")
5792 (match_dup 3)]
5793 UNSPEC_MQADDH))]
5794 "TARGET_MEDIA"
5795 "operands[3] = GEN_INT (FRV_BUILTIN_MQADDHUS);")
5796
5797 (define_expand "mqsubhss"
5798 [(set (match_operand:DI 0 "even_fpr_operand" "=h")
5799 (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
5800 (match_operand:DI 2 "even_fpr_operand" "h")
5801 (match_dup 3)]
5802 UNSPEC_MQADDH))]
5803 "TARGET_MEDIA"
5804 "operands[3] = GEN_INT (FRV_BUILTIN_MQSUBHSS);")
5805
5806 (define_expand "mqsubhus"
5807 [(set (match_operand:DI 0 "even_fpr_operand" "=h")
5808 (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
5809 (match_operand:DI 2 "even_fpr_operand" "h")
5810 (match_dup 3)]
5811 UNSPEC_MQADDH))]
5812 "TARGET_MEDIA"
5813 "operands[3] = GEN_INT (FRV_BUILTIN_MQSUBHUS);")
5814
5815 (define_insn "*mqaddh"
5816 [(set (match_operand:DI 0 "even_fpr_operand" "=h")
5817 (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
5818 (match_operand:DI 2 "even_fpr_operand" "h")
5819 (match_operand:SI 3 "const_int_operand" "n")]
5820 UNSPEC_MQADDH))]
5821 "TARGET_MEDIA"
5822 "*
5823 {
5824 switch (INTVAL (operands[3]))
5825 {
5826 default: break;
5827 case FRV_BUILTIN_MQADDHSS: return \"mqaddhss %1, %2, %0\";
5828 case FRV_BUILTIN_MQADDHUS: return \"mqaddhus %1, %2, %0\";
5829 case FRV_BUILTIN_MQSUBHSS: return \"mqsubhss %1, %2, %0\";
5830 case FRV_BUILTIN_MQSUBHUS: return \"mqsubhus %1, %2, %0\";
5831 }
5832
5833 fatal_insn (\"Bad media insn, mqaddh\", insn);
5834 }"
5835 [(set_attr "length" "4")
5836 (set_attr "type" "mqaddh")])
5837
5838 (define_insn "*cond_exec_mqaddh"
5839 [(cond_exec
5840 (match_operator 0 "ccr_eqne_operator"
5841 [(match_operand 1 "cr_operand" "C")
5842 (const_int 0)])
5843 (set (match_operand:DI 2 "even_fpr_operand" "=h")
5844 (unspec:DI [(match_operand:DI 3 "even_fpr_operand" "h")
5845 (match_operand:DI 4 "even_fpr_operand" "h")
5846 (match_operand:SI 5 "const_int_operand" "n")]
5847 UNSPEC_MQADDH)))]
5848 "TARGET_MEDIA"
5849 "*
5850 {
5851 switch (INTVAL (operands[5]))
5852 {
5853 default: break;
5854 case FRV_BUILTIN_MQADDHSS: return \"cmqaddhss %3, %4, %2, %1, %e0\";
5855 case FRV_BUILTIN_MQADDHUS: return \"cmqaddhus %3, %4, %2, %1, %e0\";
5856 case FRV_BUILTIN_MQSUBHSS: return \"cmqsubhss %3, %4, %2, %1, %e0\";
5857 case FRV_BUILTIN_MQSUBHUS: return \"cmqsubhus %3, %4, %2, %1, %e0\";
5858 }
5859
5860 fatal_insn (\"Bad media insn, cond_exec_mqaddh\", insn);
5861 }"
5862 [(set_attr "length" "4")
5863 (set_attr "type" "mqaddh")])
5864
5865 ;; Pack halfword: type "mpackh"
5866
5867 (define_insn "mpackh"
5868 [(set (match_operand:SI 0 "fpr_operand" "=f")
5869 (unspec:SI [(match_operand:HI 1 "fpr_operand" "f")
5870 (match_operand:HI 2 "fpr_operand" "f")]
5871 UNSPEC_MPACKH))]
5872 "TARGET_MEDIA"
5873 "mpackh %1, %2, %0"
5874 [(set_attr "length" "4")
5875 (set_attr "type" "mpackh")])
5876
5877 ;; Unpack halfword: type "mpackh"
5878
5879 (define_insn "munpackh"
5880 [(set (match_operand:DI 0 "even_fpr_operand" "=h")
5881 (unspec:DI [(match_operand:SI 1 "fpr_operand" "f")]
5882 UNSPEC_MUNPACKH))]
5883 "TARGET_MEDIA"
5884 "munpackh %1, %0"
5885 [(set_attr "length" "4")
5886 (set_attr "type" "munpackh")])
5887
5888 ;; Dual pack halfword: type "mdpackh"
5889
5890 (define_insn "mdpackh"
5891 [(set (match_operand:DI 0 "even_fpr_operand" "=h")
5892 (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
5893 (match_operand:DI 2 "even_fpr_operand" "h")]
5894 UNSPEC_MDPACKH))]
5895 "TARGET_MEDIA"
5896 "mdpackh %1, %2, %0"
5897 [(set_attr "length" "4")
5898 (set_attr "type" "mdpackh")])
5899
5900 ;; Byte-halfword conversion: type "mbhconv"
5901
5902 (define_insn "mbtoh"
5903 [(set (match_operand:DI 0 "even_fpr_operand" "=h")
5904 (unspec:DI [(match_operand:SI 1 "fpr_operand" "f")]
5905 UNSPEC_MBTOH))]
5906 "TARGET_MEDIA"
5907 "mbtoh %1, %0"
5908 [(set_attr "length" "4")
5909 (set_attr "type" "mbhconv")])
5910
5911 (define_insn "*cond_exec_mbtoh"
5912 [(cond_exec
5913 (match_operator 0 "ccr_eqne_operator"
5914 [(match_operand 1 "cr_operand" "C")
5915 (const_int 0)])
5916 (set (match_operand:DI 2 "even_fpr_operand" "=h")
5917 (unspec:DI [(match_operand:SI 3 "fpr_operand" "f")]
5918 UNSPEC_MBTOH)))]
5919 "TARGET_MEDIA"
5920 "cmbtoh %3, %2, %1, %e0"
5921 [(set_attr "length" "4")
5922 (set_attr "type" "mbhconv")])
5923
5924 (define_insn "mhtob"
5925 [(set (match_operand:SI 0 "fpr_operand" "=f")
5926 (unspec:SI [(match_operand:DI 1 "even_fpr_operand" "h")]
5927 UNSPEC_MHTOB))]
5928 "TARGET_MEDIA"
5929 "mhtob %1, %0"
5930 [(set_attr "length" "4")
5931 (set_attr "type" "mbhconv")])
5932
5933 (define_insn "*cond_exec_mhtob"
5934 [(cond_exec
5935 (match_operator 0 "ccr_eqne_operator"
5936 [(match_operand 1 "cr_operand" "C")
5937 (const_int 0)])
5938 (set (match_operand:SI 2 "fpr_operand" "=f")
5939 (unspec:SI [(match_operand:DI 3 "even_fpr_operand" "h")]
5940 UNSPEC_MHTOB)))]
5941 "TARGET_MEDIA"
5942 "cmhtob %3, %2, %1, %e0"
5943 [(set_attr "length" "4")
5944 (set_attr "type" "mbhconv")])
5945
5946 ;; Rotate: type "mrot"
5947
5948 (define_expand "mrotli"
5949 [(set (match_operand:SI 0 "fpr_operand" "")
5950 (unspec:SI [(match_operand:SI 1 "fpr_operand" "")
5951 (match_operand:SI 2 "uint5_operand" "")
5952 (match_dup 3)]
5953 UNSPEC_MROT))]
5954 "TARGET_MEDIA"
5955 "operands[3] = GEN_INT (FRV_BUILTIN_MROTLI);")
5956
5957 (define_expand "mrotri"
5958 [(set (match_operand:SI 0 "fpr_operand" "")
5959 (unspec:SI [(match_operand:SI 1 "fpr_operand" "")
5960 (match_operand:SI 2 "uint5_operand" "")
5961 (match_dup 3)]
5962 UNSPEC_MROT))]
5963 "TARGET_MEDIA"
5964 "operands[3] = GEN_INT (FRV_BUILTIN_MROTRI);")
5965
5966 (define_insn "*mrot"
5967 [(set (match_operand:SI 0 "fpr_operand" "=f")
5968 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
5969 (match_operand:SI 2 "uint5_operand" "I")
5970 (match_operand:SI 3 "const_int_operand" "n")]
5971 UNSPEC_MROT))]
5972 "TARGET_MEDIA"
5973 "*
5974 {
5975 switch (INTVAL (operands[3]))
5976 {
5977 default: break;
5978 case FRV_BUILTIN_MROTLI: return \"mrotli %1, %2, %0\";
5979 case FRV_BUILTIN_MROTRI: return \"mrotri %1, %2, %0\";
5980 }
5981
5982 fatal_insn (\"Bad media insn, mrot\", insn);
5983 }"
5984 [(set_attr "length" "4")
5985 (set_attr "type" "mrot")])
5986
5987 ;; Dual shift halfword: type "msh"
5988
5989 (define_expand "msllhi"
5990 [(set (match_operand:SI 0 "fpr_operand" "")
5991 (unspec:SI [(match_operand:SI 1 "fpr_operand" "")
5992 (match_operand:SI 2 "uint4_operand" "")
5993 (match_dup 3)]
5994 UNSPEC_MSHIFT))]
5995 "TARGET_MEDIA"
5996 "operands[3] = GEN_INT (FRV_BUILTIN_MSLLHI);")
5997
5998 (define_expand "msrlhi"
5999 [(set (match_operand:SI 0 "fpr_operand" "")
6000 (unspec:SI [(match_operand:SI 1 "fpr_operand" "")
6001 (match_operand:SI 2 "uint4_operand" "")
6002 (match_dup 3)]
6003 UNSPEC_MSHIFT))]
6004 "TARGET_MEDIA"
6005 "operands[3] = GEN_INT (FRV_BUILTIN_MSRLHI);")
6006
6007 (define_expand "msrahi"
6008 [(set (match_operand:SI 0 "fpr_operand" "")
6009 (unspec:SI [(match_operand:SI 1 "fpr_operand" "")
6010 (match_operand:SI 2 "uint4_operand" "")
6011 (match_dup 3)]
6012 UNSPEC_MSHIFT))]
6013 "TARGET_MEDIA"
6014 "operands[3] = GEN_INT (FRV_BUILTIN_MSRAHI);")
6015
6016 (define_insn "*mshift"
6017 [(set (match_operand:SI 0 "fpr_operand" "=f")
6018 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
6019 (match_operand:SI 2 "uint4_operand" "I")
6020 (match_operand:SI 3 "const_int_operand" "n")]
6021 UNSPEC_MSHIFT))]
6022 "TARGET_MEDIA"
6023 "*
6024 {
6025 switch (INTVAL (operands[3]))
6026 {
6027 default: break;
6028 case FRV_BUILTIN_MSLLHI: return \"msllhi %1, %2, %0\";
6029 case FRV_BUILTIN_MSRLHI: return \"msrlhi %1, %2, %0\";
6030 case FRV_BUILTIN_MSRAHI: return \"msrahi %1, %2, %0\";
6031 }
6032
6033 fatal_insn (\"Bad media insn, mshift\", insn);
6034 }"
6035 [(set_attr "length" "4")
6036 (set_attr "type" "mshift")])
6037
6038 ;; Expand halfword to word: type "mexpdhw"
6039
6040 (define_insn "mexpdhw"
6041 [(set (match_operand:SI 0 "fpr_operand" "=f")
6042 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
6043 (match_operand:SI 2 "uint1_operand" "I")]
6044 UNSPEC_MEXPDHW))]
6045 "TARGET_MEDIA"
6046 "mexpdhw %1, %2, %0"
6047 [(set_attr "length" "4")
6048 (set_attr "type" "mexpdhw")])
6049
6050 (define_insn "*cond_exec_mexpdhw"
6051 [(cond_exec
6052 (match_operator 0 "ccr_eqne_operator"
6053 [(match_operand 1 "cr_operand" "C")
6054 (const_int 0)])
6055 (set (match_operand:SI 2 "fpr_operand" "=f")
6056 (unspec:SI [(match_operand:SI 3 "fpr_operand" "f")
6057 (match_operand:SI 4 "uint1_operand" "I")]
6058 UNSPEC_MEXPDHW)))]
6059 "TARGET_MEDIA"
6060 "cmexpdhw %3, %4, %2, %1, %e0"
6061 [(set_attr "length" "4")
6062 (set_attr "type" "mexpdhw")])
6063
6064 ;; Expand halfword to double: type "mexpdhd"
6065
6066 (define_insn "mexpdhd"
6067 [(set (match_operand:DI 0 "even_fpr_operand" "=h")
6068 (unspec:DI [(match_operand:SI 1 "fpr_operand" "f")
6069 (match_operand:SI 2 "uint1_operand" "I")]
6070 UNSPEC_MEXPDHD))]
6071 "TARGET_MEDIA"
6072 "mexpdhd %1, %2, %0"
6073 [(set_attr "length" "4")
6074 (set_attr "type" "mexpdhd")])
6075
6076 (define_insn "*cond_exec_mexpdhd"
6077 [(cond_exec
6078 (match_operator 0 "ccr_eqne_operator"
6079 [(match_operand 1 "cr_operand" "C")
6080 (const_int 0)])
6081 (set (match_operand:DI 2 "even_fpr_operand" "=h")
6082 (unspec:DI [(match_operand:SI 3 "fpr_operand" "f")
6083 (match_operand:SI 4 "uint1_operand" "I")]
6084 UNSPEC_MEXPDHD)))]
6085 "TARGET_MEDIA"
6086 "cmexpdhd %3, %4, %2, %1, %e0"
6087 [(set_attr "length" "4")
6088 (set_attr "type" "mexpdhd")])
6089
6090 ;; FR cut: type "mwcut"
6091
6092 (define_insn "mwcut"
6093 [(set (match_operand:SI 0 "fpr_operand" "=f")
6094 (unspec:SI [(match_operand:DI 1 "fpr_operand" "f")
6095 (match_operand:SI 2 "fpr_or_int6_operand" "fI")]
6096 UNSPEC_MWCUT))]
6097 "TARGET_MEDIA"
6098 "mwcut%i2 %1, %2, %0"
6099 [(set_attr "length" "4")
6100 (set_attr "type" "mwcut")])
6101
6102 ;; Dual multiplication (halfword): type "mmulh"
6103
6104 (define_expand "mmulhs"
6105 [(parallel [(set (match_operand:DI 0 "even_acc_operand" "=b")
6106 (unspec:DI [(match_operand:SI 1 "fpr_operand" "f")
6107 (match_operand:SI 2 "fpr_operand" "f")
6108 (match_dup 4)]
6109 UNSPEC_MMULH))
6110 (set (match_operand:HI 3 "accg_operand" "=B")
6111 (unspec:HI [(const_int 0)] UNSPEC_MMULH))])]
6112 "TARGET_MEDIA"
6113 "operands[4] = GEN_INT (FRV_BUILTIN_MMULHS);")
6114
6115 (define_expand "mmulhu"
6116 [(parallel [(set (match_operand:DI 0 "even_acc_operand" "=b")
6117 (unspec:DI [(match_operand:SI 1 "fpr_operand" "f")
6118 (match_operand:SI 2 "fpr_operand" "f")
6119 (match_dup 4)]
6120 UNSPEC_MMULH))
6121 (set (match_operand:HI 3 "accg_operand" "=B")
6122 (unspec:HI [(const_int 0)] UNSPEC_MMULH))])]
6123 "TARGET_MEDIA"
6124 "operands[4] = GEN_INT (FRV_BUILTIN_MMULHU);")
6125
6126 (define_insn "*mmulh"
6127 [(set (match_operand:DI 0 "even_acc_operand" "=b")
6128 (unspec:DI [(match_operand:SI 1 "fpr_operand" "f")
6129 (match_operand:SI 2 "fpr_operand" "f")
6130 (match_operand:SI 3 "const_int_operand" "n")]
6131 UNSPEC_MMULH))
6132 (set (match_operand:HI 4 "accg_operand" "=B")
6133 (unspec:HI [(const_int 0)] UNSPEC_MMULH))]
6134 "TARGET_MEDIA"
6135 "*
6136 {
6137 switch (INTVAL (operands[3]))
6138 {
6139 default: break;
6140 case FRV_BUILTIN_MMULHS: return \"mmulhs %1, %2, %0\";
6141 case FRV_BUILTIN_MMULHU: return \"mmulhu %1, %2, %0\";
6142 }
6143
6144 fatal_insn (\"Bad media insn, mmulh\", insn);
6145 }"
6146 [(set_attr "length" "4")
6147 (set_attr "type" "mmulh")])
6148
6149 (define_insn "*cond_exec_mmulh"
6150 [(cond_exec
6151 (match_operator 0 "ccr_eqne_operator"
6152 [(match_operand 1 "cr_operand" "C")
6153 (const_int 0)])
6154 (parallel [(set (match_operand:DI 2 "even_acc_operand" "=b")
6155 (unspec:DI [(match_operand:SI 3 "fpr_operand" "f")
6156 (match_operand:SI 4 "fpr_operand" "f")
6157 (match_operand:SI 5 "const_int_operand" "n")]
6158 UNSPEC_MMULH))
6159 (set (match_operand:HI 6 "accg_operand" "=B")
6160 (unspec:HI [(const_int 0)] UNSPEC_MMULH))]))]
6161 "TARGET_MEDIA"
6162 "*
6163 {
6164 switch (INTVAL (operands[5]))
6165 {
6166 default: break;
6167 case FRV_BUILTIN_MMULHS: return \"cmmulhs %3, %4, %2, %1, %e0\";
6168 case FRV_BUILTIN_MMULHU: return \"cmmulhu %3, %4, %2, %1, %e0\";
6169 }
6170
6171 fatal_insn (\"Bad media insn, cond_exec_mmulh\", insn);
6172 }"
6173 [(set_attr "length" "4")
6174 (set_attr "type" "mmulh")])
6175
6176 ;; Dual cross multiplication (halfword): type "mmulxh"
6177
6178 (define_expand "mmulxhs"
6179 [(parallel [(set (match_operand:DI 0 "even_acc_operand" "=b")
6180 (unspec:DI [(match_operand:SI 1 "fpr_operand" "f")
6181 (match_operand:SI 2 "fpr_operand" "f")
6182 (match_dup 4)]
6183 UNSPEC_MMULXH))
6184 (set (match_operand:HI 3 "accg_operand" "=B")
6185 (unspec:HI [(const_int 0)] UNSPEC_MMULXH))])]
6186 "TARGET_MEDIA"
6187 "operands[4] = GEN_INT (FRV_BUILTIN_MMULXHS);")
6188
6189 (define_expand "mmulxhu"
6190 [(parallel [(set (match_operand:DI 0 "even_acc_operand" "=b")
6191 (unspec:DI [(match_operand:SI 1 "fpr_operand" "f")
6192 (match_operand:SI 2 "fpr_operand" "f")
6193 (match_dup 4)]
6194 UNSPEC_MMULXH))
6195 (set (match_operand:HI 3 "accg_operand" "=B")
6196 (unspec:HI [(const_int 0)] UNSPEC_MMULXH))])]
6197 "TARGET_MEDIA"
6198 "operands[4] = GEN_INT (FRV_BUILTIN_MMULXHU);")
6199
6200 (define_insn "*mmulxh"
6201 [(set (match_operand:DI 0 "even_acc_operand" "=b")
6202 (unspec:DI [(match_operand:SI 1 "fpr_operand" "f")
6203 (match_operand:SI 2 "fpr_operand" "f")
6204 (match_operand:SI 3 "const_int_operand" "n")]
6205 UNSPEC_MMULXH))
6206 (set (match_operand:HI 4 "accg_operand" "=B")
6207 (unspec:HI [(const_int 0)] UNSPEC_MMULXH))]
6208 "TARGET_MEDIA"
6209 "*
6210 {
6211 switch (INTVAL (operands[3]))
6212 {
6213 default: break;
6214 case FRV_BUILTIN_MMULXHS: return \"mmulxhs %1, %2, %0\";
6215 case FRV_BUILTIN_MMULXHU: return \"mmulxhu %1, %2, %0\";
6216 }
6217
6218 fatal_insn (\"Bad media insn, mmulxh\", insn);
6219 }"
6220 [(set_attr "length" "4")
6221 (set_attr "type" "mmulxh")])
6222
6223 ;; Dual product-sum (halfword): type "mmach"
6224
6225 (define_expand "mmachs"
6226 [(parallel [(set (match_operand:DI 0 "even_acc_operand" "+b")
6227 (unspec:DI [(match_dup 0)
6228 (match_operand:SI 1 "fpr_operand" "f")
6229 (match_operand:SI 2 "fpr_operand" "f")
6230 (match_operand:HI 3 "accg_operand" "+B")
6231 (match_dup 4)]
6232 UNSPEC_MMACH))
6233 (set (match_dup 3)
6234 (unspec:HI [(const_int 0)] UNSPEC_MMACH))])]
6235 "TARGET_MEDIA"
6236 "operands[4] = GEN_INT (FRV_BUILTIN_MMACHS);")
6237
6238 (define_expand "mmachu"
6239 [(parallel [(set (match_operand:DI 0 "even_acc_operand" "+b")
6240 (unspec:DI [(match_dup 0)
6241 (match_operand:SI 1 "fpr_operand" "f")
6242 (match_operand:SI 2 "fpr_operand" "f")
6243 (match_operand:HI 3 "accg_operand" "+B")
6244 (match_dup 4)]
6245 UNSPEC_MMACH))
6246 (set (match_dup 3)
6247 (unspec:HI [(const_int 0)] UNSPEC_MMACH))])]
6248 "TARGET_MEDIA"
6249 "operands[4] = GEN_INT (FRV_BUILTIN_MMACHU);")
6250
6251 (define_insn "*mmach"
6252 [(set (match_operand:DI 0 "even_acc_operand" "+b")
6253 (unspec:DI [(match_dup 0)
6254 (match_operand:SI 1 "fpr_operand" "f")
6255 (match_operand:SI 2 "fpr_operand" "f")
6256 (match_operand:HI 3 "accg_operand" "+B")
6257 (match_operand:SI 4 "const_int_operand" "n")]
6258 UNSPEC_MMACH))
6259 (set (match_dup 3) (unspec:HI [(const_int 0)] UNSPEC_MMACH))]
6260 "TARGET_MEDIA"
6261 "*
6262 {
6263 switch (INTVAL (operands[4]))
6264 {
6265 default: break;
6266 case FRV_BUILTIN_MMACHS: return \"mmachs %1, %2, %0\";
6267 case FRV_BUILTIN_MMACHU: return \"mmachu %1, %2, %0\";
6268 }
6269
6270 fatal_insn (\"Bad media insn, mmach\", insn);
6271 }"
6272 [(set_attr "length" "4")
6273 (set_attr "type" "mmach")])
6274
6275 (define_insn "*cond_exec_mmach"
6276 [(cond_exec
6277 (match_operator 0 "ccr_eqne_operator"
6278 [(match_operand 1 "cr_operand" "C")
6279 (const_int 0)])
6280 (parallel [(set (match_operand:DI 2 "even_acc_operand" "+b")
6281 (unspec:DI [(match_dup 2)
6282 (match_operand:SI 3 "fpr_operand" "f")
6283 (match_operand:SI 4 "fpr_operand" "f")
6284 (match_operand:HI 5 "accg_operand" "+B")
6285 (match_operand:SI 6 "const_int_operand" "n")]
6286 UNSPEC_MMACH))
6287 (set (match_dup 5)
6288 (unspec:HI [(const_int 0)] UNSPEC_MMACH))]))]
6289 "TARGET_MEDIA"
6290 "*
6291 {
6292 switch (INTVAL (operands[6]))
6293 {
6294 default: break;
6295 case FRV_BUILTIN_MMACHS: return \"cmmachs %3, %4, %2, %1, %e0\";
6296 case FRV_BUILTIN_MMACHU: return \"cmmachu %3, %4, %2, %1, %e0\";
6297 }
6298
6299 fatal_insn (\"Bad media insn, cond_exec_mmach\", insn);
6300 }"
6301 [(set_attr "length" "4")
6302 (set_attr "type" "mmach")])
6303
6304 ;; Dual product-difference: type "mmrdh"
6305
6306 (define_expand "mmrdhs"
6307 [(parallel [(set (match_operand:DI 0 "even_acc_operand" "+b")
6308 (unspec:DI [(match_dup 0)
6309 (match_operand:SI 1 "fpr_operand" "f")
6310 (match_operand:SI 2 "fpr_operand" "f")
6311 (match_operand:HI 3 "accg_operand" "+B")
6312 (match_dup 4)]
6313 UNSPEC_MMRDH))
6314 (set (match_dup 3)
6315 (unspec:HI [(const_int 0)] UNSPEC_MMRDH))])]
6316 "TARGET_MEDIA"
6317 "operands[4] = GEN_INT (FRV_BUILTIN_MMRDHS);")
6318
6319 (define_expand "mmrdhu"
6320 [(parallel [(set (match_operand:DI 0 "even_acc_operand" "+b")
6321 (unspec:DI [(match_dup 0)
6322 (match_operand:SI 1 "fpr_operand" "f")
6323 (match_operand:SI 2 "fpr_operand" "f")
6324 (match_operand:HI 3 "accg_operand" "+B")
6325 (match_dup 4)]
6326 UNSPEC_MMRDH))
6327 (set (match_dup 3)
6328 (unspec:HI [(const_int 0)] UNSPEC_MMRDH))])]
6329 "TARGET_MEDIA"
6330 "operands[4] = GEN_INT (FRV_BUILTIN_MMRDHU);")
6331
6332 (define_insn "*mmrdh"
6333 [(set (match_operand:DI 0 "even_acc_operand" "+b")
6334 (unspec:DI [(match_dup 0)
6335 (match_operand:SI 1 "fpr_operand" "f")
6336 (match_operand:SI 2 "fpr_operand" "f")
6337 (match_operand:HI 3 "accg_operand" "+B")
6338 (match_operand:SI 4 "const_int_operand" "n")]
6339 UNSPEC_MMRDH))
6340 (set (match_dup 3)
6341 (unspec:HI [(const_int 0)] UNSPEC_MMRDH))]
6342 "TARGET_MEDIA"
6343 "*
6344 {
6345 switch (INTVAL (operands[4]))
6346 {
6347 default: break;
6348 case FRV_BUILTIN_MMRDHS: return \"mmrdhs %1, %2, %0\";
6349 case FRV_BUILTIN_MMRDHU: return \"mmrdhu %1, %2, %0\";
6350 }
6351
6352 fatal_insn (\"Bad media insn, mrdh\", insn);
6353 }"
6354 [(set_attr "length" "4")
6355 (set_attr "type" "mmrdh")])
6356
6357 ;; Quad multiply (halfword): type "mqmulh"
6358
6359 (define_expand "mqmulhs"
6360 [(parallel [(set (match_operand:V4SI 0 "quad_acc_operand" "=A")
6361 (unspec:V4SI [(match_operand:DI 1 "even_fpr_operand" "h")
6362 (match_operand:DI 2 "even_fpr_operand" "h")
6363 (match_dup 4)]
6364 UNSPEC_MQMULH))
6365 (set (match_operand:V4QI 3 "accg_operand" "=B")
6366 (unspec:V4QI [(const_int 0)] UNSPEC_MQMULH))])]
6367 "TARGET_MEDIA"
6368 "operands[4] = GEN_INT (FRV_BUILTIN_MQMULHS);")
6369
6370 (define_expand "mqmulhu"
6371 [(parallel [(set (match_operand:V4SI 0 "quad_acc_operand" "=A")
6372 (unspec:V4SI [(match_operand:DI 1 "even_fpr_operand" "h")
6373 (match_operand:DI 2 "even_fpr_operand" "h")
6374 (match_dup 4)]
6375 UNSPEC_MQMULH))
6376 (set (match_operand:V4QI 3 "accg_operand" "=B")
6377 (unspec:V4QI [(const_int 0)] UNSPEC_MQMULH))])]
6378 "TARGET_MEDIA"
6379 "operands[4] = GEN_INT (FRV_BUILTIN_MQMULHU);")
6380
6381 (define_insn "*mqmulh"
6382 [(set (match_operand:V4SI 0 "quad_acc_operand" "=A")
6383 (unspec:V4SI [(match_operand:DI 1 "even_fpr_operand" "h")
6384 (match_operand:DI 2 "even_fpr_operand" "h")
6385 (match_operand:SI 3 "const_int_operand" "n")]
6386 UNSPEC_MQMULH))
6387 (set (match_operand:V4QI 4 "accg_operand" "=B")
6388 (unspec:V4QI [(const_int 0)] UNSPEC_MQMULH))]
6389 "TARGET_MEDIA"
6390 "*
6391 {
6392 switch (INTVAL (operands[3]))
6393 {
6394 default: break;
6395 case FRV_BUILTIN_MQMULHS: return \"mqmulhs %1, %2, %0\";
6396 case FRV_BUILTIN_MQMULHU: return \"mqmulhu %1, %2, %0\";
6397 }
6398
6399 fatal_insn (\"Bad media insn, mqmulh\", insn);
6400 }"
6401 [(set_attr "length" "4")
6402 (set_attr "type" "mqmulh")])
6403
6404 (define_insn "*cond_exec_mqmulh"
6405 [(cond_exec
6406 (match_operator 0 "ccr_eqne_operator"
6407 [(match_operand 1 "cr_operand" "C")
6408 (const_int 0)])
6409 (parallel [(set (match_operand:V4SI 2 "quad_acc_operand" "=A")
6410 (unspec:V4SI [(match_operand:DI 3 "even_fpr_operand" "h")
6411 (match_operand:DI 4 "even_fpr_operand" "h")
6412 (match_operand:SI 5 "const_int_operand" "n")]
6413 UNSPEC_MQMULH))
6414 (set (match_operand:V4QI 6 "accg_operand" "=B")
6415 (unspec:V4QI [(const_int 0)] UNSPEC_MQMULH))]))]
6416 "TARGET_MEDIA"
6417 "*
6418 {
6419 switch (INTVAL (operands[5]))
6420 {
6421 default: break;
6422 case FRV_BUILTIN_MQMULHS: return \"cmqmulhs %3, %4, %2, %1, %e0\";
6423 case FRV_BUILTIN_MQMULHU: return \"cmqmulhu %3, %4, %2, %1, %e0\";
6424 }
6425
6426 fatal_insn (\"Bad media insn, cond_exec_mqmulh\", insn);
6427 }"
6428 [(set_attr "length" "4")
6429 (set_attr "type" "mqmulh")])
6430
6431 ;; Quad cross multiply (halfword): type "mqmulxh"
6432
6433 (define_expand "mqmulxhs"
6434 [(parallel [(set (match_operand:V4SI 0 "quad_acc_operand" "=A")
6435 (unspec:V4SI [(match_operand:DI 1 "even_fpr_operand" "h")
6436 (match_operand:DI 2 "even_fpr_operand" "h")
6437 (match_dup 4)]
6438 UNSPEC_MQMULXH))
6439 (set (match_operand:V4QI 3 "accg_operand" "=B")
6440 (unspec:V4QI [(const_int 0)] UNSPEC_MQMULXH))])]
6441 "TARGET_MEDIA"
6442 "operands[4] = GEN_INT (FRV_BUILTIN_MQMULXHS);")
6443
6444 (define_expand "mqmulxhu"
6445 [(parallel [(set (match_operand:V4SI 0 "quad_acc_operand" "=A")
6446 (unspec:V4SI [(match_operand:DI 1 "even_fpr_operand" "h")
6447 (match_operand:DI 2 "even_fpr_operand" "h")
6448 (match_dup 4)]
6449 UNSPEC_MQMULXH))
6450 (set (match_operand:V4QI 3 "accg_operand" "=B")
6451 (unspec:V4QI [(const_int 0)] UNSPEC_MQMULXH))])]
6452 "TARGET_MEDIA"
6453 "operands[4] = GEN_INT (FRV_BUILTIN_MQMULXHU);")
6454
6455 (define_insn "*mqmulxh"
6456 [(set (match_operand:V4SI 0 "quad_acc_operand" "=A")
6457 (unspec:V4SI [(match_operand:DI 1 "even_fpr_operand" "h")
6458 (match_operand:DI 2 "even_fpr_operand" "h")
6459 (match_operand:SI 3 "const_int_operand" "n")]
6460 UNSPEC_MQMULXH))
6461 (set (match_operand:V4QI 4 "accg_operand" "=B")
6462 (unspec:V4QI [(const_int 0)] UNSPEC_MQMULXH))]
6463 "TARGET_MEDIA"
6464 "*
6465 {
6466 switch (INTVAL (operands[3]))
6467 {
6468 default: break;
6469 case FRV_BUILTIN_MQMULXHS: return \"mqmulxhs %1, %2, %0\";
6470 case FRV_BUILTIN_MQMULXHU: return \"mqmulxhu %1, %2, %0\";
6471 }
6472
6473 fatal_insn (\"Bad media insn, mqmulxh\", insn);
6474 }"
6475 [(set_attr "length" "4")
6476 (set_attr "type" "mqmulxh")])
6477
6478 ;; Quad product-sum (halfword): type "mqmach"
6479
6480 (define_expand "mqmachs"
6481 [(parallel [(set (match_operand:V4SI 0 "even_acc_operand" "+A")
6482 (unspec:V4SI [(match_dup 0)
6483 (match_operand:DI 1 "even_fpr_operand" "h")
6484 (match_operand:DI 2 "even_fpr_operand" "h")
6485 (match_operand:V4QI 3 "accg_operand" "+B")
6486 (match_dup 4)]
6487 UNSPEC_MQMACH))
6488 (set (match_dup 3)
6489 (unspec:V4QI [(const_int 0)] UNSPEC_MQMACH))])]
6490 "TARGET_MEDIA"
6491 "operands[4] = GEN_INT (FRV_BUILTIN_MQMACHS);")
6492
6493 (define_expand "mqmachu"
6494 [(parallel [(set (match_operand:V4SI 0 "even_acc_operand" "+A")
6495 (unspec:V4SI [(match_dup 0)
6496 (match_operand:DI 1 "even_fpr_operand" "h")
6497 (match_operand:DI 2 "even_fpr_operand" "h")
6498 (match_operand:V4QI 3 "accg_operand" "+B")
6499 (match_dup 4)]
6500 UNSPEC_MQMACH))
6501 (set (match_dup 3)
6502 (unspec:V4QI [(const_int 0)] UNSPEC_MQMACH))])]
6503 "TARGET_MEDIA"
6504 "operands[4] = GEN_INT (FRV_BUILTIN_MQMACHU);")
6505
6506 (define_insn "*mqmach"
6507 [(set (match_operand:V4SI 0 "even_acc_operand" "+A")
6508 (unspec:V4SI [(match_dup 0)
6509 (match_operand:DI 1 "even_fpr_operand" "h")
6510 (match_operand:DI 2 "even_fpr_operand" "h")
6511 (match_operand:V4QI 3 "accg_operand" "+B")
6512 (match_operand:SI 4 "const_int_operand" "n")]
6513 UNSPEC_MQMACH))
6514 (set (match_dup 3)
6515 (unspec:V4QI [(const_int 0)] UNSPEC_MQMACH))]
6516 "TARGET_MEDIA"
6517 "*
6518 {
6519 switch (INTVAL (operands[4]))
6520 {
6521 default: break;
6522 case FRV_BUILTIN_MQMACHS: return \"mqmachs %1, %2, %0\";
6523 case FRV_BUILTIN_MQMACHU: return \"mqmachu %1, %2, %0\";
6524 }
6525
6526 fatal_insn (\"Bad media insn, mqmach\", insn);
6527 }"
6528 [(set_attr "length" "4")
6529 (set_attr "type" "mqmach")])
6530
6531 (define_insn "*cond_exec_mqmach"
6532 [(cond_exec
6533 (match_operator 0 "ccr_eqne_operator"
6534 [(match_operand 1 "cr_operand" "C")
6535 (const_int 0)])
6536 (parallel [(set (match_operand:V4SI 2 "even_acc_operand" "+A")
6537 (unspec:V4SI [(match_dup 2)
6538 (match_operand:DI 3 "even_fpr_operand" "h")
6539 (match_operand:DI 4 "even_fpr_operand" "h")
6540 (match_operand:V4QI 5 "accg_operand" "+B")
6541 (match_operand:SI 6 "const_int_operand" "n")]
6542 UNSPEC_MQMACH))
6543 (set (match_dup 5)
6544 (unspec:V4QI [(const_int 0)] UNSPEC_MQMACH))]))]
6545 "TARGET_MEDIA"
6546 "*
6547 {
6548 switch (INTVAL (operands[6]))
6549 {
6550 default: break;
6551 case FRV_BUILTIN_MQMACHS: return \"cmqmachs %3, %4, %2, %1, %e0\";
6552 case FRV_BUILTIN_MQMACHU: return \"cmqmachu %3, %4, %2, %1, %e0\";
6553 }
6554
6555 fatal_insn (\"Bad media insn, cond_exec_mqmach\", insn);
6556 }"
6557 [(set_attr "length" "4")
6558 (set_attr "type" "mqmach")])
6559
6560 ;; Dual complex number product-sum (halfword)
6561
6562 (define_expand "mcpxrs"
6563 [(parallel [(set (match_operand:SI 0 "acc_operand" "=a")
6564 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
6565 (match_operand:SI 2 "fpr_operand" "f")
6566 (match_dup 4)]
6567 UNSPEC_MCPX))
6568 (set (match_operand:QI 3 "accg_operand" "=B")
6569 (unspec:QI [(const_int 0)] UNSPEC_MCPX))])]
6570 "TARGET_MEDIA"
6571 "operands[4] = GEN_INT (FRV_BUILTIN_MCPXRS);")
6572
6573 (define_expand "mcpxru"
6574 [(parallel [(set (match_operand:SI 0 "acc_operand" "=a")
6575 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
6576 (match_operand:SI 2 "fpr_operand" "f")
6577 (match_dup 4)]
6578 UNSPEC_MCPX))
6579 (set (match_operand:QI 3 "accg_operand" "=B")
6580 (unspec:QI [(const_int 0)] UNSPEC_MCPX))])]
6581 "TARGET_MEDIA"
6582 "operands[4] = GEN_INT (FRV_BUILTIN_MCPXRU);")
6583
6584 (define_expand "mcpxis"
6585 [(parallel [(set (match_operand:SI 0 "acc_operand" "=a")
6586 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
6587 (match_operand:SI 2 "fpr_operand" "f")
6588 (match_dup 4)]
6589 UNSPEC_MCPX))
6590 (set (match_operand:QI 3 "accg_operand" "=B")
6591 (unspec:QI [(const_int 0)] UNSPEC_MCPX))])]
6592 "TARGET_MEDIA"
6593 "operands[4] = GEN_INT (FRV_BUILTIN_MCPXIS);")
6594
6595 (define_expand "mcpxiu"
6596 [(parallel [(set (match_operand:SI 0 "acc_operand" "=a")
6597 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
6598 (match_operand:SI 2 "fpr_operand" "f")
6599 (match_dup 4)]
6600 UNSPEC_MCPX))
6601 (set (match_operand:QI 3 "accg_operand" "=B")
6602 (unspec:QI [(const_int 0)] UNSPEC_MCPX))])]
6603 "TARGET_MEDIA"
6604 "operands[4] = GEN_INT (FRV_BUILTIN_MCPXIU);")
6605
6606 (define_insn "*mcpx"
6607 [(parallel [(set (match_operand:SI 0 "acc_operand" "=a")
6608 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
6609 (match_operand:SI 2 "fpr_operand" "f")
6610 (match_operand:SI 3 "const_int_operand" "n")]
6611 UNSPEC_MCPX))
6612 (set (match_operand:QI 4 "accg_operand" "=B")
6613 (unspec:QI [(const_int 0)] UNSPEC_MCPX))])]
6614 "TARGET_MEDIA"
6615 "*
6616 {
6617 switch (INTVAL (operands[3]))
6618 {
6619 default: break;
6620 case FRV_BUILTIN_MCPXRS: return \"mcpxrs %1, %2, %0\";
6621 case FRV_BUILTIN_MCPXRU: return \"mcpxru %1, %2, %0\";
6622 case FRV_BUILTIN_MCPXIS: return \"mcpxis %1, %2, %0\";
6623 case FRV_BUILTIN_MCPXIU: return \"mcpxiu %1, %2, %0\";
6624 }
6625
6626 fatal_insn (\"Bad media insn, mcpx\", insn);
6627 }"
6628 [(set_attr "length" "4")
6629 (set_attr "type" "mcpx")])
6630
6631 (define_insn "*cond_exec_mcpx"
6632 [(cond_exec
6633 (match_operator 0 "ccr_eqne_operator"
6634 [(match_operand 1 "cr_operand" "C")
6635 (const_int 0)])
6636 (parallel [(set (match_operand:SI 2 "acc_operand" "=a")
6637 (unspec:SI [(match_operand:SI 3 "fpr_operand" "f")
6638 (match_operand:SI 4 "fpr_operand" "f")
6639 (match_operand:SI 5 "const_int_operand" "n")]
6640 UNSPEC_MCPX))
6641 (set (match_operand:QI 6 "accg_operand" "=B")
6642 (unspec:QI [(const_int 0)] UNSPEC_MCPX))]))]
6643 "TARGET_MEDIA"
6644 "*
6645 {
6646 switch (INTVAL (operands[5]))
6647 {
6648 default: break;
6649 case FRV_BUILTIN_MCPXRS: return \"cmcpxrs %3, %4, %2, %1, %e0\";
6650 case FRV_BUILTIN_MCPXRU: return \"cmcpxru %3, %4, %2, %1, %e0\";
6651 case FRV_BUILTIN_MCPXIS: return \"cmcpxis %3, %4, %2, %1, %e0\";
6652 case FRV_BUILTIN_MCPXIU: return \"cmcpxiu %3, %4, %2, %1, %e0\";
6653 }
6654
6655 fatal_insn (\"Bad media insn, cond_exec_mcpx\", insn);
6656 }"
6657 [(set_attr "length" "4")
6658 (set_attr "type" "mcpx")])
6659
6660 ;; Quad complex number product-sum (halfword): type "mqcpx"
6661
6662 (define_expand "mqcpxrs"
6663 [(parallel [(set (match_operand:DI 0 "even_acc_operand" "=b")
6664 (unspec:DI [(match_operand:DI 1 "fpr_operand" "f")
6665 (match_operand:DI 2 "fpr_operand" "f")
6666 (match_dup 4)]
6667 UNSPEC_MQCPX))
6668 (set (match_operand:HI 3 "accg_operand" "=B")
6669 (unspec:HI [(const_int 0)] UNSPEC_MQCPX))])]
6670 "TARGET_MEDIA"
6671 "operands[4] = GEN_INT (FRV_BUILTIN_MQCPXRS);")
6672
6673 (define_expand "mqcpxru"
6674 [(parallel [(set (match_operand:DI 0 "even_acc_operand" "=b")
6675 (unspec:DI [(match_operand:DI 1 "fpr_operand" "f")
6676 (match_operand:DI 2 "fpr_operand" "f")
6677 (match_dup 4)]
6678 UNSPEC_MQCPX))
6679 (set (match_operand:HI 3 "accg_operand" "=B")
6680 (unspec:HI [(const_int 0)] UNSPEC_MQCPX))])]
6681 "TARGET_MEDIA"
6682 "operands[4] = GEN_INT (FRV_BUILTIN_MQCPXRU);")
6683
6684 (define_expand "mqcpxis"
6685 [(parallel [(set (match_operand:DI 0 "even_acc_operand" "=b")
6686 (unspec:DI [(match_operand:DI 1 "fpr_operand" "f")
6687 (match_operand:DI 2 "fpr_operand" "f")
6688 (match_dup 4)]
6689 UNSPEC_MQCPX))
6690 (set (match_operand:HI 3 "accg_operand" "=B")
6691 (unspec:HI [(const_int 0)] UNSPEC_MQCPX))])]
6692 "TARGET_MEDIA"
6693 "operands[4] = GEN_INT (FRV_BUILTIN_MQCPXIS);")
6694
6695 (define_expand "mqcpxiu"
6696 [(parallel [(set (match_operand:DI 0 "even_acc_operand" "=b")
6697 (unspec:DI [(match_operand:DI 1 "fpr_operand" "f")
6698 (match_operand:DI 2 "fpr_operand" "f")
6699 (match_dup 4)]
6700 UNSPEC_MQCPX))
6701 (set (match_operand:HI 3 "accg_operand" "=B")
6702 (unspec:HI [(const_int 0)] UNSPEC_MQCPX))])]
6703 "TARGET_MEDIA"
6704 "operands[4] = GEN_INT (FRV_BUILTIN_MQCPXIU);")
6705
6706 (define_insn "*mqcpx"
6707 [(set (match_operand:DI 0 "even_acc_operand" "=b")
6708 (unspec:DI [(match_operand:DI 1 "fpr_operand" "f")
6709 (match_operand:DI 2 "fpr_operand" "f")
6710 (match_operand:SI 3 "const_int_operand" "n")]
6711 UNSPEC_MQCPX))
6712 (set (match_operand:HI 4 "accg_operand" "=B")
6713 (unspec:HI [(const_int 0)] UNSPEC_MQCPX))]
6714 "TARGET_MEDIA"
6715 "*
6716 {
6717 switch (INTVAL (operands[3]))
6718 {
6719 default: break;
6720 case FRV_BUILTIN_MQCPXRS: return \"mqcpxrs %1, %2, %0\";
6721 case FRV_BUILTIN_MQCPXRU: return \"mqcpxru %1, %2, %0\";
6722 case FRV_BUILTIN_MQCPXIS: return \"mqcpxis %1, %2, %0\";
6723 case FRV_BUILTIN_MQCPXIU: return \"mqcpxiu %1, %2, %0\";
6724 }
6725
6726 fatal_insn (\"Bad media insn, mqcpx\", insn);
6727 }"
6728 [(set_attr "length" "4")
6729 (set_attr "type" "mqcpx")])
6730
6731 ;; Cut: type "mcut"
6732
6733 (define_expand "mcut"
6734 [(set (match_operand:SI 0 "fpr_operand" "=f")
6735 (unspec:SI [(match_operand:SI 1 "acc_operand" "a")
6736 (match_operand:SI 2 "fpr_or_int6_operand" "fI")
6737 (match_operand:QI 3 "accg_operand" "B")
6738 (match_dup 4)]
6739 UNSPEC_MCUT))]
6740 "TARGET_MEDIA"
6741 "operands[4] = GEN_INT (FRV_BUILTIN_MCUT);")
6742
6743 (define_expand "mcutss"
6744 [(set (match_operand:SI 0 "fpr_operand" "=f")
6745 (unspec:SI [(match_operand:SI 1 "acc_operand" "a")
6746 (match_operand:SI 2 "fpr_or_int6_operand" "fI")
6747 (match_operand:QI 3 "accg_operand" "B")
6748 (match_dup 4)]
6749 UNSPEC_MCUT))]
6750 "TARGET_MEDIA"
6751 "operands[4] = GEN_INT (FRV_BUILTIN_MCUTSS);")
6752
6753 (define_insn "*mcut"
6754 [(set (match_operand:SI 0 "fpr_operand" "=f")
6755 (unspec:SI [(match_operand:SI 1 "acc_operand" "a")
6756 (match_operand:SI 2 "fpr_or_int6_operand" "fI")
6757 (match_operand:QI 3 "accg_operand" "B")
6758 (match_operand:SI 4 "const_int_operand" "n")]
6759 UNSPEC_MCUT))]
6760 "TARGET_MEDIA"
6761 "*
6762 {
6763 switch (INTVAL (operands[4]))
6764 {
6765 default: break;
6766 case FRV_BUILTIN_MCUT: return \"mcut%i2 %1, %2, %0\";
6767 case FRV_BUILTIN_MCUTSS: return \"mcutss%i2 %1, %2, %0\";
6768 }
6769
6770 fatal_insn (\"Bad media insn, mcut\", insn);
6771 }"
6772 [(set_attr "length" "4")
6773 (set_attr "type" "mcut")])
6774
6775 ;; Accumulator read: type "mrdacc"
6776
6777 (define_insn "mrdacc"
6778 [(set (match_operand:SI 0 "fpr_operand" "=f")
6779 (unspec:SI [(match_operand:SI 1 "acc_operand" "a")] UNSPEC_MRDACC))]
6780 "TARGET_MEDIA"
6781 "mrdacc %1, %0"
6782 [(set_attr "length" "4")
6783 (set_attr "type" "mrdacc")])
6784
6785 (define_insn "mrdaccg"
6786 [(set (match_operand:SI 0 "fpr_operand" "=f")
6787 (unspec:SI [(match_operand:QI 1 "accg_operand" "B")] UNSPEC_MRDACCG))]
6788 "TARGET_MEDIA"
6789 "mrdaccg %1, %0"
6790 [(set_attr "length" "4")
6791 (set_attr "type" "mrdacc")])
6792
6793 ;; Accumulator write: type "mwtacc"
6794
6795 (define_insn "mwtacc"
6796 [(set (match_operand:SI 0 "acc_operand" "=a")
6797 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")] UNSPEC_MWTACC))]
6798 "TARGET_MEDIA"
6799 "mwtacc %1, %0"
6800 [(set_attr "length" "4")
6801 (set_attr "type" "mwtacc")])
6802
6803 (define_insn "mwtaccg"
6804 [(set (match_operand:QI 0 "accg_operand" "=B")
6805 (unspec:QI [(match_operand:SI 1 "fpr_operand" "f")] UNSPEC_MWTACCG))]
6806 "TARGET_MEDIA"
6807 "mwtaccg %1, %0"
6808 [(set_attr "length" "4")
6809 (set_attr "type" "mwtacc")])
6810
6811 ;; Trap: This one executes on the control unit, not the media units.
6812
6813 (define_insn "mtrap"
6814 [(unspec_volatile [(const_int 0)] UNSPEC_MTRAP)]
6815 "TARGET_MEDIA"
6816 "mtrap"
6817 [(set_attr "length" "4")
6818 (set_attr "type" "trap")])
6819
6820 ;; Clear single accumulator: type "mclracc"
6821
6822 (define_insn "mclracc_internal"
6823 [(set (match_operand:SI 0 "acc_operand" "=a")
6824 (unspec:SI [(const_int 0)] UNSPEC_MCLRACC))
6825 (set (match_operand:QI 1 "accg_operand" "=B")
6826 (unspec:QI [(const_int 0)] UNSPEC_MCLRACC))]
6827 "TARGET_MEDIA"
6828 "mclracc %0,#0"
6829 [(set_attr "length" "4")
6830 (set_attr "type" "mclracc")])
6831
6832 (define_expand "mclracc"
6833 [(parallel [(set (match_operand:SI 0 "acc_operand" "=a")
6834 (unspec:SI [(const_int 0)] UNSPEC_MCLRACC))
6835 (set (match_dup 1)
6836 (unspec:QI [(const_int 0)] UNSPEC_MCLRACC))])]
6837 "TARGET_MEDIA"
6838 "
6839 {
6840 if (GET_CODE (operands[0]) != REG || !ACC_P (REGNO (operands[0])))
6841 FAIL;
6842
6843 operands[1] = frv_matching_accg_for_acc (operands[0]);
6844 }")
6845
6846 ;; Clear all accumulators: type "mclracca"
6847
6848 (define_insn "mclracca8_internal"
6849 [(set (match_operand:V4SI 0 "quad_acc_operand" "=b")
6850 (unspec:V4SI [(const_int 0)] UNSPEC_MCLRACCA))
6851 (set (match_operand:V4SI 1 "quad_acc_operand" "=b")
6852 (unspec:V4SI [(const_int 0)] UNSPEC_MCLRACCA))
6853 (set (match_operand:V4QI 2 "accg_operand" "=B")
6854 (unspec:V4QI [(const_int 0)] UNSPEC_MCLRACCA))
6855 (set (match_operand:V4QI 3 "accg_operand" "=B")
6856 (unspec:V4QI [(const_int 0)] UNSPEC_MCLRACCA))]
6857 "TARGET_MEDIA && TARGET_ACC_8"
6858 "mclracc acc0,#1"
6859 [(set_attr "length" "4")
6860 (set_attr "type" "mclracca")])
6861
6862 (define_insn "mclracca4_internal"
6863 [(set (match_operand:V4SI 0 "quad_acc_operand" "=b")
6864 (unspec:V4SI [(const_int 0)] UNSPEC_MCLRACCA))
6865 (set (match_operand:V4QI 1 "accg_operand" "=B")
6866 (unspec:V4QI [(const_int 0)] UNSPEC_MCLRACCA))]
6867 "TARGET_MEDIA && TARGET_ACC_4"
6868 "mclracc acc0,#1"
6869 [(set_attr "length" "4")
6870 (set_attr "type" "mclracca")])
6871
6872 (define_expand "mclracca8"
6873 [(parallel [(set (match_dup 0) (unspec:V4SI [(const_int 0)] UNSPEC_MCLRACCA))
6874 (set (match_dup 1) (unspec:V4SI [(const_int 0)] UNSPEC_MCLRACCA))
6875 (set (match_dup 2) (unspec:V4QI [(const_int 0)] UNSPEC_MCLRACCA))
6876 (set (match_dup 3) (unspec:V4QI [(const_int 0)] UNSPEC_MCLRACCA))])]
6877 "TARGET_MEDIA && TARGET_ACC_8"
6878 "
6879 {
6880 operands[0] = gen_rtx_REG (V4SImode, ACC_FIRST);
6881 operands[1] = gen_rtx_REG (V4SImode, ACC_FIRST + (~3 & ACC_MASK));
6882 operands[2] = gen_rtx_REG (V4QImode, ACCG_FIRST);
6883 operands[3] = gen_rtx_REG (V4QImode, ACCG_FIRST + (~3 & ACC_MASK));
6884 }")
6885
6886 (define_expand "mclracca4"
6887 [(parallel [(set (match_dup 0) (unspec:V4SI [(const_int 0)] UNSPEC_MCLRACCA))
6888 (set (match_dup 1) (unspec:V4QI [(const_int 0)] UNSPEC_MCLRACCA))])]
6889 "TARGET_MEDIA && TARGET_ACC_4"
6890 "
6891 {
6892 operands[0] = gen_rtx_REG (V4SImode, ACC_FIRST);
6893 operands[1] = gen_rtx_REG (V4QImode, ACCG_FIRST);
6894 }")
6895
6896 (define_insn "mcop1"
6897 [(set (match_operand:SI 0 "fpr_operand" "=f")
6898 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
6899 (match_operand:SI 2 "fpr_operand" "f")] UNSPEC_MCOP1))]
6900 "TARGET_MEDIA_REV1"
6901 "mcop1 %1, %2, %0"
6902 [(set_attr "length" "4")
6903 ;; What is the class of the insn ???
6904 (set_attr "type" "multi")])
6905
6906 (define_insn "mcop2"
6907 [(set (match_operand:SI 0 "fpr_operand" "=f")
6908 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")
6909 (match_operand:SI 2 "fpr_operand" "f")] UNSPEC_MCOP2))]
6910 "TARGET_MEDIA_REV1"
6911 "mcop2 %1, %2, %0"
6912 [(set_attr "length" "4")
6913 ;; What is the class of the insn ???
6914 (set_attr "type" "multi")])
6915
6916 (define_insn "*mdunpackh_internal"
6917 [(set (match_operand:V4SI 0 "quad_fpr_operand" "=x")
6918 (unspec:V4SI [(match_operand:DI 1 "even_fpr_operand" "h")]
6919 UNSPEC_MDUNPACKH_INTERNAL))]
6920 "TARGET_MEDIA_REV1"
6921 "mdunpackh %1, %0"
6922 [(set_attr "length" "4")
6923 (set_attr "type" "mdunpackh")])
6924
6925 (define_insn_and_split "mdunpackh"
6926 [(set (match_operand:V4SI 0 "memory_operand" "=o")
6927 (unspec:V4SI [(match_operand:DI 1 "even_fpr_operand" "h")]
6928 UNSPEC_MDUNPACKH))
6929 (clobber (match_scratch:V4SI 2 "=x"))]
6930 "TARGET_MEDIA_REV1"
6931 "#"
6932 "reload_completed"
6933 [(set (match_dup 2)
6934 (unspec:V4SI [(match_dup 1)] UNSPEC_MDUNPACKH_INTERNAL))
6935 (set (match_dup 3)
6936 (match_dup 4))
6937 (set (match_dup 5)
6938 (match_dup 6))]
6939 "
6940 {
6941 operands[3] = change_address (operands[0], DImode, NULL_RTX);
6942 operands[4] = gen_rtx_REG (DImode, REGNO (operands[2]));
6943 operands[5] = frv_index_memory (operands[0], DImode, 1);
6944 operands[6] = gen_rtx_REG (DImode, REGNO (operands[2])+2);
6945 }"
6946 [(set_attr "length" "20")
6947 (set_attr "type" "multi")])
6948
6949 (define_insn "*mbtohe_internal"
6950 [(set (match_operand:V4SI 0 "quad_fpr_operand" "=x")
6951 (unspec:V4SI [(match_operand:SI 1 "fpr_operand" "f")]
6952 UNSPEC_MBTOHE_INTERNAL))]
6953 "TARGET_MEDIA_REV1"
6954 "mbtohe %1, %0"
6955 [(set_attr "length" "4")
6956 (set_attr "type" "mbhconve")])
6957
6958 (define_insn_and_split "mbtohe"
6959 [(set (match_operand:V4SI 0 "memory_operand" "=o")
6960 (unspec:V4SI [(match_operand:SI 1 "fpr_operand" "f")]
6961 UNSPEC_MBTOHE))
6962 (clobber (match_scratch:V4SI 2 "=x"))]
6963 "TARGET_MEDIA_REV1"
6964 "#"
6965 "reload_completed"
6966 [(set (match_dup 2)
6967 (unspec:V4SI [(match_dup 1)] UNSPEC_MBTOHE_INTERNAL))
6968 (set (match_dup 3)
6969 (match_dup 4))
6970 (set (match_dup 5)
6971 (match_dup 6))]
6972 "
6973 {
6974 operands[3] = change_address (operands[0], DImode, NULL_RTX);
6975 operands[4] = gen_rtx_REG (DImode, REGNO (operands[2]));
6976 operands[5] = frv_index_memory (operands[0], DImode, 1);
6977 operands[6] = gen_rtx_REG (DImode, REGNO (operands[2])+2);
6978 }"
6979 [(set_attr "length" "20")
6980 (set_attr "type" "multi")])
6981
6982 ;; Quad product-sum (halfword) instructions only found on the FR400.
6983 ;; type "mqmach"
6984
6985 (define_expand "mqxmachs"
6986 [(parallel [(set (match_operand:V4SI 0 "quad_acc_operand" "")
6987 (unspec:V4SI [(match_dup 0)
6988 (match_operand:DI 1 "even_fpr_operand" "")
6989 (match_operand:DI 2 "even_fpr_operand" "")
6990 (match_operand:V4QI 3 "accg_operand" "")
6991 (match_dup 4)]
6992 UNSPEC_MQMACH2))
6993 (set (match_dup 3)
6994 (unspec:V4QI [(const_int 0)] UNSPEC_MQMACH2))])]
6995 "TARGET_MEDIA_REV2"
6996 "operands[4] = GEN_INT (FRV_BUILTIN_MQXMACHS);")
6997
6998 (define_expand "mqxmacxhs"
6999 [(parallel [(set (match_operand:V4SI 0 "quad_acc_operand" "")
7000 (unspec:V4SI [(match_dup 0)
7001 (match_operand:DI 1 "even_fpr_operand" "")
7002 (match_operand:DI 2 "even_fpr_operand" "")
7003 (match_operand:V4QI 3 "accg_operand" "")
7004 (match_dup 4)]
7005 UNSPEC_MQMACH2))
7006 (set (match_dup 3)
7007 (unspec:V4QI [(const_int 0)] UNSPEC_MQMACH2))])]
7008 "TARGET_MEDIA_REV2"
7009 "operands[4] = GEN_INT (FRV_BUILTIN_MQXMACXHS);")
7010
7011 (define_expand "mqmacxhs"
7012 [(parallel [(set (match_operand:V4SI 0 "quad_acc_operand" "")
7013 (unspec:V4SI [(match_dup 0)
7014 (match_operand:DI 1 "even_fpr_operand" "")
7015 (match_operand:DI 2 "even_fpr_operand" "")
7016 (match_operand:V4QI 3 "accg_operand" "")
7017 (match_dup 4)]
7018 UNSPEC_MQMACH2))
7019 (set (match_dup 3)
7020 (unspec:V4QI [(const_int 0)] UNSPEC_MQMACH2))])]
7021 "TARGET_MEDIA_REV2"
7022 "operands[4] = GEN_INT (FRV_BUILTIN_MQMACXHS);")
7023
7024 (define_insn "*mqmach2"
7025 [(set (match_operand:V4SI 0 "quad_acc_operand" "+A")
7026 (unspec:V4SI [(match_dup 0)
7027 (match_operand:DI 1 "even_fpr_operand" "h")
7028 (match_operand:DI 2 "even_fpr_operand" "h")
7029 (match_operand:V4QI 3 "accg_operand" "+B")
7030 (match_operand:SI 4 "const_int_operand" "n")]
7031 UNSPEC_MQMACH2))
7032 (set (match_dup 3)
7033 (unspec:V4QI [(const_int 0)] UNSPEC_MQMACH2))]
7034 "TARGET_MEDIA_REV2"
7035 "*
7036 {
7037 switch (INTVAL (operands[4]))
7038 {
7039 default: break;
7040 case FRV_BUILTIN_MQXMACHS: return \"mqxmachs %1, %2, %0\";
7041 case FRV_BUILTIN_MQXMACXHS: return \"mqxmacxhs %1, %2, %0\";
7042 case FRV_BUILTIN_MQMACXHS: return \"mqmacxhs %1, %2, %0\";
7043 }
7044
7045 fatal_insn (\"Bad media insn, mqmach2\", insn);
7046 }"
7047 [(set_attr "length" "4")
7048 (set_attr "type" "mqmach")])
7049
7050 ;; Accumulator addition/subtraction: type "maddacc"
7051
7052 (define_expand "maddaccs"
7053 [(parallel [(set (match_operand:SI 0 "acc_operand" "")
7054 (unspec:SI [(match_operand:DI 1 "even_acc_operand" "")]
7055 UNSPEC_MADDACC))
7056 (set (match_operand:QI 2 "accg_operand" "")
7057 (unspec:QI [(match_operand:HI 3 "accg_operand" "")
7058 (match_dup 4)]
7059 UNSPEC_MADDACC))])]
7060 "TARGET_MEDIA_REV2"
7061 "operands[4] = GEN_INT (FRV_BUILTIN_MADDACCS);")
7062
7063 (define_expand "msubaccs"
7064 [(parallel [(set (match_operand:SI 0 "acc_operand" "")
7065 (unspec:SI [(match_operand:DI 1 "even_acc_operand" "")]
7066 UNSPEC_MADDACC))
7067 (set (match_operand:QI 2 "accg_operand" "")
7068 (unspec:QI [(match_operand:HI 3 "accg_operand" "")
7069 (match_dup 4)]
7070 UNSPEC_MADDACC))])]
7071 "TARGET_MEDIA_REV2"
7072 "operands[4] = GEN_INT (FRV_BUILTIN_MSUBACCS);")
7073
7074 (define_insn "masaccs"
7075 [(set (match_operand:DI 0 "even_acc_operand" "=b")
7076 (unspec:DI [(match_operand:DI 1 "even_acc_operand" "b")]
7077 UNSPEC_MASACCS))
7078 (set (match_operand:HI 2 "accg_operand" "=B")
7079 (unspec:HI [(match_operand:HI 3 "accg_operand" "B")]
7080 UNSPEC_MASACCS))]
7081 "TARGET_MEDIA_REV2"
7082 "masaccs %1, %0"
7083 [(set_attr "length" "4")
7084 (set_attr "type" "maddacc")])
7085
7086 (define_insn "*maddacc"
7087 [(set (match_operand:SI 0 "acc_operand" "=a")
7088 (unspec:SI [(match_operand:DI 1 "even_acc_operand" "b")]
7089 UNSPEC_MADDACC))
7090 (set (match_operand:QI 2 "accg_operand" "=B")
7091 (unspec:QI [(match_operand:HI 3 "accg_operand" "B")
7092 (match_operand:SI 4 "const_int_operand" "n")]
7093 UNSPEC_MADDACC))]
7094 "TARGET_MEDIA_REV2"
7095 "*
7096 {
7097 switch (INTVAL (operands[4]))
7098 {
7099 default: break;
7100 case FRV_BUILTIN_MADDACCS: return \"maddaccs %1, %0\";
7101 case FRV_BUILTIN_MSUBACCS: return \"msubaccs %1, %0\";
7102 }
7103
7104 fatal_insn (\"Bad media insn, maddacc\", insn);
7105 }"
7106 [(set_attr "length" "4")
7107 (set_attr "type" "maddacc")])
7108
7109 ;; Dual accumulator addition/subtraction: type "mdaddacc"
7110
7111 (define_expand "mdaddaccs"
7112 [(parallel [(set (match_operand:DI 0 "even_acc_operand" "")
7113 (unspec:DI [(match_operand:V4SI 1 "quad_acc_operand" "")]
7114 UNSPEC_MDADDACC))
7115 (set (match_operand:HI 2 "accg_operand" "")
7116 (unspec:HI [(match_operand:V4QI 3 "accg_operand" "")
7117 (match_dup 4)]
7118 UNSPEC_MDADDACC))])]
7119 "TARGET_MEDIA_REV2"
7120 "operands[4] = GEN_INT (FRV_BUILTIN_MDADDACCS);")
7121
7122 (define_expand "mdsubaccs"
7123 [(parallel [(set (match_operand:DI 0 "even_acc_operand" "")
7124 (unspec:DI [(match_operand:V4SI 1 "quad_acc_operand" "")]
7125 UNSPEC_MDADDACC))
7126 (set (match_operand:HI 2 "accg_operand" "")
7127 (unspec:HI [(match_operand:V4QI 3 "accg_operand" "")
7128 (match_dup 4)]
7129 UNSPEC_MDADDACC))])]
7130 "TARGET_MEDIA_REV2"
7131 "operands[4] = GEN_INT (FRV_BUILTIN_MDSUBACCS);")
7132
7133 (define_insn "mdasaccs"
7134 [(set (match_operand:V4SI 0 "quad_acc_operand" "=A")
7135 (unspec:V4SI [(match_operand:V4SI 1 "quad_acc_operand" "A")]
7136 UNSPEC_MDASACCS))
7137 (set (match_operand:V4QI 2 "accg_operand" "=B")
7138 (unspec:V4QI [(match_operand:V4QI 3 "accg_operand" "B")]
7139 UNSPEC_MDASACCS))]
7140 "TARGET_MEDIA_REV2"
7141 "mdasaccs %1, %0"
7142 [(set_attr "length" "4")
7143 (set_attr "type" "mdaddacc")])
7144
7145 (define_insn "*mdaddacc"
7146 [(set (match_operand:DI 0 "even_acc_operand" "=b")
7147 (unspec:DI [(match_operand:V4SI 1 "quad_acc_operand" "A")]
7148 UNSPEC_MDADDACC))
7149 (set (match_operand:HI 2 "accg_operand" "=B")
7150 (unspec:HI [(match_operand:V4QI 3 "accg_operand" "B")
7151 (match_operand:SI 4 "const_int_operand" "n")]
7152 UNSPEC_MDADDACC))]
7153 "TARGET_MEDIA_REV2"
7154 "*
7155 {
7156 switch (INTVAL (operands[4]))
7157 {
7158 default: break;
7159 case FRV_BUILTIN_MDADDACCS: return \"mdaddaccs %1, %0\";
7160 case FRV_BUILTIN_MDSUBACCS: return \"mdsubaccs %1, %0\";
7161 }
7162
7163 fatal_insn (\"Bad media insn, mdaddacc\", insn);
7164 }"
7165 [(set_attr "length" "4")
7166 (set_attr "type" "mdaddacc")])
7167
7168 ;; Dual absolute (halfword): type "mabsh"
7169
7170 (define_insn "mabshs"
7171 [(set (match_operand:SI 0 "fpr_operand" "=f")
7172 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")] UNSPEC_MABSHS))]
7173 "TARGET_MEDIA_REV2"
7174 "mabshs %1, %0"
7175 [(set_attr "length" "4")
7176 (set_attr "type" "mabsh")])
7177
7178 ;; Dual rotate: type "mdrot"
7179
7180 (define_insn "mdrotli"
7181 [(set (match_operand:DI 0 "even_fpr_operand" "=h")
7182 (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
7183 (match_operand:SI 2 "uint5_operand" "I")]
7184 UNSPEC_MDROTLI))]
7185 "TARGET_MEDIA_REV2"
7186 "mdrotli %1, %2, %0"
7187 [(set_attr "length" "4")
7188 (set_attr "type" "mdrot")])
7189
7190 ;; Dual coupling (concatenation): type "mcpl"
7191
7192 (define_insn "mcplhi"
7193 [(set (match_operand:SI 0 "fpr_operand" "=f")
7194 (unspec:SI [(match_operand:DI 1 "fpr_operand" "h")
7195 (match_operand:SI 2 "uint4_operand" "I")]
7196 UNSPEC_MCPLHI))]
7197 "TARGET_MEDIA_REV2"
7198 "mcplhi %1, %2, %0"
7199 [(set_attr "length" "4")
7200 (set_attr "type" "mcpl")])
7201
7202 (define_insn "mcpli"
7203 [(set (match_operand:SI 0 "fpr_operand" "=f")
7204 (unspec:SI [(match_operand:DI 1 "fpr_operand" "h")
7205 (match_operand:SI 2 "uint5_operand" "I")]
7206 UNSPEC_MCPLI))]
7207 "TARGET_MEDIA_REV2"
7208 "mcpli %1, %2, %0"
7209 [(set_attr "length" "4")
7210 (set_attr "type" "mcpl")])
7211
7212 ;; Dual cut: type "mdcut"
7213
7214 (define_insn "mdcutssi"
7215 [(set (match_operand:DI 0 "even_fpr_operand" "=h")
7216 (unspec:DI [(match_operand:DI 1 "even_acc_operand" "b")
7217 (match_operand:SI 2 "int6_operand" "I")
7218 (match_operand:HI 3 "accg_operand" "B")]
7219 UNSPEC_MDCUTSSI))]
7220 "TARGET_MEDIA_REV2"
7221 "mdcutssi %1, %2, %0"
7222 [(set_attr "length" "4")
7223 (set_attr "type" "mdcut")])
7224
7225 ;; Quad saturate (halfword): type "mqsath"
7226
7227 (define_insn "mqsaths"
7228 [(set (match_operand:DI 0 "even_fpr_operand" "=h")
7229 (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
7230 (match_operand:DI 2 "even_fpr_operand" "h")]
7231 UNSPEC_MQSATHS))]
7232 "TARGET_MEDIA_REV2"
7233 "mqsaths %1, %2, %0"
7234 [(set_attr "length" "4")
7235 (set_attr "type" "mqsath")])
7236
7237 ;; Quad limit instructions: type "mqlimh"
7238
7239 (define_insn "mqlclrhs"
7240 [(set (match_operand:DI 0 "even_fpr_operand" "=h")
7241 (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
7242 (match_operand:DI 2 "even_fpr_operand" "h")]
7243 UNSPEC_MQLCLRHS))]
7244 "TARGET_MEDIA_FR450"
7245 "mqlclrhs %1, %2, %0"
7246 [(set_attr "length" "4")
7247 (set_attr "type" "mqlimh")])
7248
7249 (define_insn "mqlmths"
7250 [(set (match_operand:DI 0 "even_fpr_operand" "=h")
7251 (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
7252 (match_operand:DI 2 "even_fpr_operand" "h")]
7253 UNSPEC_MQLMTHS))]
7254 "TARGET_MEDIA_FR450"
7255 "mqlmths %1, %2, %0"
7256 [(set_attr "length" "4")
7257 (set_attr "type" "mqlimh")])
7258
7259 (define_insn "mqsllhi"
7260 [(set (match_operand:DI 0 "even_fpr_operand" "=h")
7261 (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
7262 (match_operand:SI 2 "int6_operand" "I")]
7263 UNSPEC_MQSLLHI))]
7264 "TARGET_MEDIA_FR450"
7265 "mqsllhi %1, %2, %0"
7266 [(set_attr "length" "4")
7267 (set_attr "type" "mqshift")])
7268
7269 (define_insn "mqsrahi"
7270 [(set (match_operand:DI 0 "even_fpr_operand" "=h")
7271 (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h")
7272 (match_operand:SI 2 "int6_operand" "I")]
7273 UNSPEC_MQSRAHI))]
7274 "TARGET_MEDIA_FR450"
7275 "mqsrahi %1, %2, %0"
7276 [(set_attr "length" "4")
7277 (set_attr "type" "mqshift")])
7278
7279 ;; Set hi/lo instructions: type "mset"
7280
7281 (define_insn "mhsetlos"
7282 [(set (match_operand:SI 0 "fpr_operand" "=f")
7283 (unspec:SI [(match_operand:SI 1 "fpr_operand" "0")
7284 (match_operand:SI 2 "int12_operand" "NOP")]
7285 UNSPEC_MHSETLOS))]
7286 "TARGET_MEDIA_REV2"
7287 "mhsetlos %2, %0"
7288 [(set_attr "length" "4")
7289 (set_attr "type" "mset")])
7290
7291 (define_insn "mhsetloh"
7292 [(set (match_operand:SI 0 "fpr_operand" "=f")
7293 (unspec:SI [(match_operand:SI 1 "fpr_operand" "0")
7294 (match_operand:SI 2 "int5_operand" "I")]
7295 UNSPEC_MHSETLOH))]
7296 "TARGET_MEDIA_REV2"
7297 "mhsetloh %2, %0"
7298 [(set_attr "length" "4")
7299 (set_attr "type" "mset")])
7300
7301 (define_insn "mhsethis"
7302 [(set (match_operand:SI 0 "fpr_operand" "=f")
7303 (unspec:SI [(match_operand:SI 1 "fpr_operand" "0")
7304 (match_operand:SI 2 "int12_operand" "NOP")]
7305 UNSPEC_MHSETHIS))]
7306 "TARGET_MEDIA_REV2"
7307 "mhsethis %2, %0"
7308 [(set_attr "length" "4")
7309 (set_attr "type" "mset")])
7310
7311 (define_insn "mhsethih"
7312 [(set (match_operand:SI 0 "fpr_operand" "=f")
7313 (unspec:SI [(match_operand:SI 1 "fpr_operand" "0")
7314 (match_operand:SI 2 "int5_operand" "I")]
7315 UNSPEC_MHSETHIH))]
7316 "TARGET_MEDIA_REV2"
7317 "mhsethih %2, %0"
7318 [(set_attr "length" "4")
7319 (set_attr "type" "mset")])
7320
7321 (define_insn "mhdsets"
7322 [(set (match_operand:SI 0 "fpr_operand" "=f")
7323 (unspec:SI [(match_operand:SI 1 "int12_operand" "NOP")]
7324 UNSPEC_MHDSETS))]
7325 "TARGET_MEDIA_REV2"
7326 "mhdsets %1, %0"
7327 [(set_attr "length" "4")
7328 (set_attr "type" "mset")])
7329
7330 (define_insn "mhdseth"
7331 [(set (match_operand:SI 0 "fpr_operand" "=f")
7332 (unspec:SI [(match_operand:SI 1 "fpr_operand" "0")
7333 (match_operand:SI 2 "int5_operand" "I")]
7334 UNSPEC_MHDSETH))]
7335 "TARGET_MEDIA_REV2"
7336 "mhdseth %2, %0"
7337 [(set_attr "length" "4")
7338 (set_attr "type" "mset")])
7339
7340 ;;-----------------------------------------------------------------------------
7341
7342 (define_expand "symGOT2reg"
7343 [(match_operand:SI 0 "" "")
7344 (match_operand:SI 1 "" "")
7345 (match_operand:SI 2 "" "")
7346 (match_operand:SI 3 "" "")]
7347 ""
7348 "
7349 {
7350 rtx insn;
7351
7352 insn = emit_insn (gen_symGOT2reg_i (operands[0], operands[1], operands[2], operands[3]));
7353
7354 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
7355
7356 set_unique_reg_note (insn, REG_EQUAL, operands[1]);
7357
7358 DONE;
7359 }")
7360
7361 (define_expand "symGOT2reg_i"
7362 [(set (match_operand:SI 0 "" "")
7363 (mem:SI (plus:SI (match_operand:SI 2 "" "")
7364 (const:SI (unspec:SI [(match_operand:SI 1 "" "")
7365 (match_operand:SI 3 "" "")]
7366 UNSPEC_GOT)))))]
7367 ""
7368 "")
7369
7370 (define_expand "symGOT2reg_hilo"
7371 [(set (match_dup 6)
7372 (high:SI (const:SI (unspec:SI [(match_operand:SI 1 "" "")
7373 (match_dup 4)] UNSPEC_GOT))))
7374 (set (match_dup 5)
7375 (lo_sum:SI (match_dup 6)
7376 (const:SI (unspec:SI [(match_dup 1)
7377 (match_operand:SI 3 "" "")]
7378 UNSPEC_GOT))))
7379 (set (match_operand:SI 0 "" "")
7380 (mem:SI (plus:SI (match_dup 5)
7381 (match_operand:SI 2 "" ""))))
7382 ]
7383 ""
7384 "
7385 {
7386 if (!can_create_pseudo_p ())
7387 operands[6] = operands[5] = operands[0];
7388 else
7389 {
7390 operands[6] = gen_reg_rtx (SImode);
7391 operands[5] = gen_reg_rtx (SImode);
7392 }
7393
7394 operands[4] = GEN_INT (INTVAL (operands[3]) + 1);
7395 operands[3] = GEN_INT (INTVAL (operands[3]) + 2);
7396 }")
7397
7398 (define_expand "symGOTOFF2reg_hilo"
7399 [(set (match_dup 6)
7400 (high:SI (const:SI (unspec:SI [(match_operand:SI 1 "" "")
7401 (match_dup 4)] UNSPEC_GOT))))
7402 (set (match_dup 5)
7403 (lo_sum:SI (match_dup 6)
7404 (const:SI (unspec:SI [(match_dup 1)
7405 (match_operand:SI 3 "" "")]
7406 UNSPEC_GOT))))
7407 (set (match_operand:SI 0 "" "")
7408 (plus:SI (match_dup 5)
7409 (match_operand:SI 2 "" "")))
7410 ]
7411 ""
7412 "
7413 {
7414 if (!can_create_pseudo_p ())
7415 operands[6] = operands[5] = operands[0];
7416 else
7417 {
7418 operands[6] = gen_reg_rtx (SImode);
7419 operands[5] = gen_reg_rtx (SImode);
7420 }
7421
7422 operands[4] = GEN_INT (INTVAL (operands[3]) + 1);
7423 operands[3] = GEN_INT (INTVAL (operands[3]) + 2);
7424 }")
7425
7426 (define_expand "symGOTOFF2reg"
7427 [(match_operand:SI 0 "" "")
7428 (match_operand:SI 1 "" "")
7429 (match_operand:SI 2 "" "")
7430 (match_operand:SI 3 "" "")]
7431 ""
7432 "
7433 {
7434 rtx insn = emit_insn (gen_symGOTOFF2reg_i (operands[0], operands[1], operands[2], operands[3]));
7435
7436 set_unique_reg_note (insn, REG_EQUAL, operands[1]);
7437
7438 DONE;
7439 }")
7440
7441 (define_expand "symGOTOFF2reg_i"
7442 [(set (match_operand:SI 0 "" "")
7443 (plus:SI (match_operand:SI 2 "" "")
7444 (const:SI
7445 (unspec:SI [(match_operand:SI 1 "" "")
7446 (match_operand:SI 3 "" "")]
7447 UNSPEC_GOT))))]
7448 ""
7449 "")
7450
7451 (define_expand "symGPREL2reg"
7452 [(match_operand:SI 0 "" "")
7453 (match_operand:SI 1 "" "")
7454 (match_operand:SI 2 "" "")
7455 (match_operand:SI 3 "" "")
7456 (match_dup 4)]
7457 ""
7458 "
7459 {
7460 rtx insn;
7461
7462 if (!can_create_pseudo_p ())
7463 operands[4] = operands[0];
7464 else
7465 operands[4] = gen_reg_rtx (SImode);
7466
7467 emit_insn (frv_gen_GPsym2reg (operands[4], operands[2]));
7468
7469 insn = emit_insn (gen_symGOTOFF2reg_i (operands[0], operands[1],
7470 operands[4], operands[3]));
7471
7472 set_unique_reg_note (insn, REG_EQUAL, operands[1]);
7473
7474 DONE;
7475 }")
7476
7477 (define_expand "symGPREL2reg_hilo"
7478 [(match_operand:SI 0 "" "")
7479 (match_operand:SI 1 "" "")
7480 (match_operand:SI 2 "" "")
7481 (match_operand:SI 3 "" "")
7482 (match_dup 4)]
7483 ""
7484 "
7485 {
7486 rtx insn;
7487
7488 if (!can_create_pseudo_p ())
7489 {
7490 emit_insn (gen_symGOT2reg (operands[0], operands[1], operands[2],
7491 GEN_INT (R_FRV_GOT12)));
7492 DONE;
7493 }
7494
7495 operands[4] = gen_reg_rtx (SImode);
7496
7497 emit_insn (frv_gen_GPsym2reg (operands[4], operands[2]));
7498
7499 insn = emit_insn (gen_symGOTOFF2reg_hilo (operands[0], operands[1],
7500 operands[4], operands[3]));
7501
7502 set_unique_reg_note (insn, REG_EQUAL, operands[1]);
7503
7504 DONE;
7505 }")
7506 \f
7507 (define_constants
7508 [
7509 (UNSPEC_SMUL 154)
7510 (UNSPEC_UMUL 155)
7511 (UNSPEC_SMU 156)
7512 (UNSPEC_ADDSS 157)
7513 (UNSPEC_SUBSS 158)
7514 (UNSPEC_SLASS 159)
7515 (UNSPEC_SCAN 160)
7516 (UNSPEC_INTSS 161)
7517 (UNSPEC_SCUTSS 162)
7518 (UNSPEC_PREFETCH0 163)
7519 (UNSPEC_PREFETCH 164)
7520 (UNSPEC_IACCreadll 165)
7521 (UNSPEC_IACCreadl 166)
7522 (UNSPEC_IACCsetll 167)
7523 (UNSPEC_IACCsetl 168)
7524 (UNSPEC_SMASS 169)
7525 (UNSPEC_SMSSS 170)
7526 (UNSPEC_IMUL 171)
7527
7528 (IACC0_REG 171)
7529 ])
7530
7531 (define_insn "smul"
7532 [(set (match_operand:DI 0 "integer_register_operand" "=d")
7533 (unspec:DI [(match_operand:SI 1 "integer_register_operand" "d")
7534 (match_operand:SI 2 "integer_register_operand" "d")]
7535 UNSPEC_SMUL))]
7536 ""
7537 "smul %1, %2, %0"
7538 [(set_attr "length" "4")
7539 (set_attr "type" "mul")])
7540
7541 (define_insn "umul"
7542 [(set (match_operand:DI 0 "integer_register_operand" "=d")
7543 (unspec:DI [(match_operand:SI 1 "integer_register_operand" "d")
7544 (match_operand:SI 2 "integer_register_operand" "d")]
7545 UNSPEC_UMUL))]
7546 ""
7547 "umul %1, %2, %0"
7548 [(set_attr "length" "4")
7549 (set_attr "type" "mul")])
7550
7551 (define_insn "smass"
7552 [(set (reg:DI IACC0_REG)
7553 (unspec:DI [(match_operand:SI 0 "integer_register_operand" "d")
7554 (match_operand:SI 1 "integer_register_operand" "d")
7555 (reg:DI IACC0_REG)]
7556 UNSPEC_SMASS))]
7557 "TARGET_FR405_BUILTINS"
7558 "smass %1, %0"
7559 [(set_attr "length" "4")
7560 (set_attr "type" "macc")])
7561
7562 (define_insn "smsss"
7563 [(set (reg:DI IACC0_REG)
7564 (unspec:DI [(match_operand:SI 0 "integer_register_operand" "d")
7565 (match_operand:SI 1 "integer_register_operand" "d")
7566 (reg:DI IACC0_REG)]
7567 UNSPEC_SMSSS))]
7568 "TARGET_FR405_BUILTINS"
7569 "smsss %1, %0"
7570 [(set_attr "length" "4")
7571 (set_attr "type" "macc")])
7572
7573 (define_insn "smu"
7574 [(set (reg:DI IACC0_REG)
7575 (unspec:DI [(match_operand:SI 0 "integer_register_operand" "d")
7576 (match_operand:SI 1 "integer_register_operand" "d")]
7577 UNSPEC_SMU))]
7578 "TARGET_FR405_BUILTINS"
7579 "smu %1, %0"
7580 [(set_attr "length" "4")
7581 (set_attr "type" "macc")])
7582
7583 (define_insn "addss"
7584 [(set (match_operand:SI 0 "integer_register_operand" "=d")
7585 (unspec:SI [(match_operand:SI 1 "integer_register_operand" "d")
7586 (match_operand:SI 2 "integer_register_operand" "d")]
7587 UNSPEC_ADDSS))]
7588 "TARGET_FR405_BUILTINS"
7589 "addss %1, %2, %0"
7590 [(set_attr "length" "4")
7591 (set_attr "type" "int")])
7592
7593 (define_insn "subss"
7594 [(set (match_operand:SI 0 "integer_register_operand" "=d")
7595 (unspec:SI [(match_operand:SI 1 "integer_register_operand" "d")
7596 (match_operand:SI 2 "integer_register_operand" "d")]
7597 UNSPEC_SUBSS))]
7598 "TARGET_FR405_BUILTINS"
7599 "subss %1, %2, %0"
7600 [(set_attr "length" "4")
7601 (set_attr "type" "int")])
7602
7603 (define_insn "slass"
7604 [(set (match_operand:SI 0 "integer_register_operand" "=d")
7605 (unspec:SI [(match_operand:SI 1 "integer_register_operand" "d")
7606 (match_operand:SI 2 "integer_register_operand" "d")]
7607 UNSPEC_SLASS))]
7608 "TARGET_FR405_BUILTINS"
7609 "slass %1, %2, %0"
7610 [(set_attr "length" "4")
7611 (set_attr "type" "int")])
7612
7613 (define_insn "scan"
7614 [(set (match_operand:SI 0 "integer_register_operand" "=d")
7615 (unspec:SI [(match_operand:SI 1 "integer_register_operand" "d")
7616 (match_operand:SI 2 "integer_register_operand" "d")]
7617 UNSPEC_SCAN))]
7618 ""
7619 "scan %1, %2, %0"
7620 [(set_attr "length" "4")
7621 (set_attr "type" "scan")])
7622
7623 (define_insn "scutss"
7624 [(set (match_operand:SI 0 "integer_register_operand" "=d")
7625 (unspec:SI [(match_operand:SI 1 "integer_register_operand" "d")
7626 (reg:DI IACC0_REG)]
7627 UNSPEC_SCUTSS))]
7628 "TARGET_FR405_BUILTINS"
7629 "scutss %1,%0"
7630 [(set_attr "length" "4")
7631 (set_attr "type" "cut")])
7632
7633 (define_insn "frv_prefetch0"
7634 [(prefetch (unspec:SI [(match_operand:SI 0 "register_operand" "r")]
7635 UNSPEC_PREFETCH0)
7636 (const_int 0)
7637 (const_int 0))]
7638 ""
7639 "dcpl %0, gr0, #0"
7640 [(set_attr "length" "4")])
7641
7642 (define_insn "frv_prefetch"
7643 [(prefetch (unspec:SI [(match_operand:SI 0 "register_operand" "r")]
7644 UNSPEC_PREFETCH)
7645 (const_int 0)
7646 (const_int 0))]
7647 "TARGET_FR500_FR550_BUILTINS"
7648 "nop.p\\n\\tnldub @(%0, gr0), gr0"
7649 [(set_attr "length" "8")])
7650
7651 ;; TLS patterns
7652
7653 (define_insn "call_gettlsoff"
7654 [(set (match_operand:SI 0 "register_operand" "=D09")
7655 (unspec:SI
7656 [(match_operand:SI 1 "symbolic_operand" "")]
7657 UNSPEC_GETTLSOFF))
7658 (clobber (reg:SI GR8_REG))
7659 (clobber (reg:SI LRREG))
7660 (use (match_operand:SI 2 "register_operand" "D15"))]
7661 "HAVE_AS_TLS"
7662 "call #gettlsoff(%a1)"
7663 [(set_attr "length" "4")
7664 (set_attr "type" "load_or_call")])
7665
7666 ;; We have to expand this like a libcall (it sort of actually is)
7667 ;; because otherwise sched may move, for example, an insn that sets up
7668 ;; GR8 for a subsequence call before the *tls_indirect_call insn, and
7669 ;; then reload won't be able to fix things up.
7670 (define_expand "tls_indirect_call"
7671 [(set (reg:DI GR8_REG)
7672 (match_operand:DI 2 "register_operand" ""))
7673 (parallel
7674 [(set (reg:SI GR9_REG)
7675 (unspec:SI
7676 [(match_operand:SI 1 "symbolic_operand" "")
7677 (reg:DI GR8_REG)]
7678 UNSPEC_TLS_INDIRECT_CALL))
7679 (clobber (reg:SI GR8_REG))
7680 (clobber (reg:SI LRREG))
7681 (use (match_operand:SI 3 "register_operand" ""))])
7682 (set (match_operand:SI 0 "register_operand" "")
7683 (reg:SI GR9_REG))]
7684 "HAVE_AS_TLS")
7685
7686 (define_insn "*tls_indirect_call"
7687 [(set (reg:SI GR9_REG)
7688 (unspec:SI
7689 [(match_operand:SI 0 "symbolic_operand" "")
7690 (reg:DI GR8_REG)]
7691 UNSPEC_TLS_INDIRECT_CALL))
7692 (clobber (reg:SI GR8_REG))
7693 (clobber (reg:SI LRREG))
7694 ;; If there was a way to represent the fact that we don't need GR9
7695 ;; or GR15 to be set before this instruction (it could be in
7696 ;; parallel), we could use it here. This change wouldn't apply to
7697 ;; call_gettlsoff, thought, since the linker may turn the latter
7698 ;; into ldi @(gr15,offset),gr9.
7699 (use (match_operand:SI 1 "register_operand" "D15"))]
7700 "HAVE_AS_TLS"
7701 "calll #gettlsoff(%a0)@(gr8,gr0)"
7702 [(set_attr "length" "4")
7703 (set_attr "type" "jumpl")])
7704
7705 (define_insn "tls_load_gottlsoff12"
7706 [(set (match_operand:SI 0 "register_operand" "=r")
7707 (unspec:SI
7708 [(match_operand:SI 1 "symbolic_operand" "")
7709 (match_operand:SI 2 "register_operand" "r")]
7710 UNSPEC_TLS_LOAD_GOTTLSOFF12))]
7711 "HAVE_AS_TLS"
7712 "ldi @(%2, #gottlsoff12(%1)), %0"
7713 [(set_attr "length" "4")])
7714
7715 (define_expand "tlsoff_hilo"
7716 [(set (match_operand:SI 0 "register_operand" "=r")
7717 (high:SI (const:SI (unspec:SI
7718 [(match_operand:SI 1 "symbolic_operand" "")
7719 (match_operand:SI 2 "immediate_operand" "n")]
7720 UNSPEC_GOT))))
7721 (set (match_dup 0)
7722 (lo_sum:SI (match_dup 0)
7723 (const:SI (unspec:SI [(match_dup 1)
7724 (match_dup 3)] UNSPEC_GOT))))]
7725 ""
7726 "
7727 {
7728 operands[3] = GEN_INT (INTVAL (operands[2]) + 1);
7729 }")
7730
7731 ;; Just like movdi_ldd, but with relaxation annotations.
7732 (define_insn "tls_tlsdesc_ldd"
7733 [(set (match_operand:DI 0 "register_operand" "=r")
7734 (unspec:DI [(mem:DI (unspec:SI
7735 [(match_operand:SI 1 "register_operand" "r")
7736 (match_operand:SI 2 "register_operand" "r")
7737 (match_operand:SI 3 "symbolic_operand" "")]
7738 UNSPEC_TLS_TLSDESC_LDD_AUX))]
7739 UNSPEC_TLS_TLSDESC_LDD))]
7740 ""
7741 "ldd #tlsdesc(%a3)@(%1,%2), %0"
7742 [(set_attr "length" "4")
7743 (set_attr "type" "gload")])
7744
7745 (define_insn "tls_tlsoff_ld"
7746 [(set (match_operand:SI 0 "register_operand" "=r")
7747 (mem:SI (unspec:SI
7748 [(match_operand:SI 1 "register_operand" "r")
7749 (match_operand:SI 2 "register_operand" "r")
7750 (match_operand:SI 3 "symbolic_operand" "")]
7751 UNSPEC_TLS_TLSOFF_LD)))]
7752 ""
7753 "ld #tlsoff(%a3)@(%1,%2), %0"
7754 [(set_attr "length" "4")
7755 (set_attr "type" "gload")])
7756
7757 (define_insn "tls_lddi"
7758 [(set (match_operand:DI 0 "register_operand" "=r")
7759 (unspec:DI [(match_operand:SI 1 "symbolic_operand" "")
7760 (match_operand:SI 2 "register_operand" "d")]
7761 UNSPEC_TLS_LDDI))]
7762 ""
7763 "lddi @(%2, #gottlsdesc12(%a1)), %0"
7764 [(set_attr "length" "4")
7765 (set_attr "type" "gload")])