OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [config/] [frv/] [frv.md] - Blame information for rev 827

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.