OSDN Git Service

* sh.c (langhooks.h): Include.
[pf3gnuchains/gcc-fork.git] / gcc / config / sh / sh.md
1 ;;- Machine description for Hitachi / SuperH SH.
2 ;;  Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
3 ;;  Free Software Foundation, Inc.
4 ;;  Contributed by Steve Chamberlain (sac@cygnus.com).
5 ;;  Improved by Jim Wilson (wilson@cygnus.com).
6
7 ;; This file is part of GNU CC.
8
9 ;; GNU CC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; any later version.
13
14 ;; GNU CC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ;; GNU General Public License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU CC; see the file COPYING.  If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
23
24
25 ;; ??? Should prepend a * to all pattern names which are not used.
26 ;; This will make the compiler smaller, and rebuilds after changes faster.
27
28 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
29 ;; sequences.  Especially the sequences for arithmetic right shifts.
30
31 ;; ??? Should check all DImode patterns for consistency and usefulness.
32
33 ;; ??? The MAC.W and MAC.L instructions are not supported.  There is no
34 ;; way to generate them.
35
36 ;; ??? The cmp/str instruction is not supported.  Perhaps it can be used
37 ;; for a str* inline function.
38
39 ;; BSR is not generated by the compiler proper, but when relaxing, it
40 ;; generates .uses pseudo-ops that allow linker relaxation to create
41 ;; BSR.  This is actually implemented in bfd/{coff,elf32}-sh.c
42
43 ;; Special constraints for SH machine description:
44 ;;
45 ;;    t -- T
46 ;;    x -- mac
47 ;;    l -- pr
48 ;;    z -- r0
49 ;;
50 ;; Special formats used for outputting SH instructions:
51 ;;
52 ;;   %.  --  print a .s if insn needs delay slot
53 ;;   %@  --  print rte/rts if is/isn't an interrupt function
54 ;;   %#  --  output a nop if there is nothing to put in the delay slot
55 ;;   %O  --  print a constant without the #
56 ;;   %R  --  print the lsw reg of a double
57 ;;   %S  --  print the msw reg of a double
58 ;;   %T  --  print next word of a double REG or MEM
59 ;;
60 ;; Special predicates:
61 ;;
62 ;;  arith_operand          -- operand is valid source for arithmetic op
63 ;;  arith_reg_operand      -- operand is valid register for arithmetic op
64 ;;  general_movdst_operand -- operand is valid move destination
65 ;;  general_movsrc_operand -- operand is valid move source
66 ;;  logical_operand        -- operand is valid source for logical op
67
68 ;; -------------------------------------------------------------------------
69 ;; Constants
70 ;; -------------------------------------------------------------------------
71
72 (define_constants [
73   (AP_REG       145)
74   (PR_REG       146)
75   (T_REG        147)
76   (GBR_REG      144)
77   (MACH_REG     148)
78   (MACL_REG     149)
79   (FPUL_REG     150)
80   (RAP_REG      152)
81
82   (FPSCR_REG    151)
83
84   (PIC_REG      12)
85   (FP_REG       14)
86   (SP_REG       15)
87
88   (PR_MEDIA_REG 18)
89   (T_MEDIA_REG  19)
90
91   (R0_REG       0)
92   (R1_REG       1)
93   (R2_REG       2)
94   (R3_REG       3)
95   (R4_REG       4)
96   (R5_REG       5)
97   (R6_REG       6)
98   (R7_REG       7)
99   (R8_REG       8)
100   (R9_REG       9)
101   (R10_REG      10)
102   (R20_REG      20)
103   (R21_REG      21)
104   (R22_REG      22)
105   (R23_REG      23)
106
107   (DR0_REG      64)
108   (DR2_REG      66)
109   (DR4_REG      68)
110   (FR23_REG     87)
111
112   (TR0_REG      128)
113   (TR1_REG      129)
114   (TR2_REG      130)
115
116   (XD0_REG      136)
117
118   ;; These are used with unspec.
119   (UNSPEC_COMPACT_ARGS  0)
120   (UNSPEC_MOVA          1)
121   (UNSPEC_CASESI        2)
122   (UNSPEC_DATALABEL     3)
123   (UNSPEC_BBR           4)
124   (UNSPEC_SFUNC         5)
125   (UNSPEC_PIC           6)
126   (UNSPEC_GOT           7)
127   (UNSPEC_GOTOFF        8)
128   (UNSPEC_PLT           9)
129   (UNSPEC_CALLER        10)
130   (UNSPEC_GOTPLT        11)
131   (UNSPEC_ICACHE        12)
132   (UNSPEC_INIT_TRAMP    13)
133   (UNSPEC_FCOSA         14)
134   (UNSPEC_FSRRA         15)
135   (UNSPEC_FSINA         16)
136   (UNSPEC_NSB           17)
137   (UNSPEC_ALLOCO        18)
138
139   ;; These are used with unspec_volatile.
140   (UNSPECV_BLOCKAGE     0)
141   (UNSPECV_ALIGN        1)
142   (UNSPECV_CONST2       2)
143   (UNSPECV_CONST4       4)
144   (UNSPECV_CONST8       6)
145   (UNSPECV_WINDOW_END   10)
146   (UNSPECV_CONST_END    11)
147 ])  
148
149 ;; -------------------------------------------------------------------------
150 ;; Attributes
151 ;; -------------------------------------------------------------------------
152
153 ;; Target CPU.
154
155 (define_attr "cpu"
156  "sh1,sh2,sh3,sh3e,sh4,sh5"
157   (const (symbol_ref "sh_cpu_attr")))
158
159 (define_attr "endian" "big,little"
160  (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
161                       (const_string "little") (const_string "big"))))
162
163 ;; Indicate if the default fpu mode is single precision.
164 (define_attr "fpu_single" "yes,no"
165   (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
166                          (const_string "yes") (const_string "no"))))
167
168 (define_attr "fmovd" "yes,no"
169   (const (if_then_else (symbol_ref "TARGET_FMOVD")
170                        (const_string "yes") (const_string "no"))))
171 ;; issues/clock
172 (define_attr "issues" "1,2"
173   (const (if_then_else (symbol_ref "TARGET_SUPERSCALAR") (const_string "2") (const_string "1"))))
174
175 ;; cbranch      conditional branch instructions
176 ;; jump         unconditional jumps
177 ;; arith        ordinary arithmetic
178 ;; arith3       a compound insn that behaves similarly to a sequence of
179 ;;              three insns of type arith
180 ;; arith3b      like above, but might end with a redirected branch
181 ;; load         from memory
182 ;; load_si      Likewise, SImode variant for general register.
183 ;; store        to memory
184 ;; move         register to register
185 ;; fmove        register to register, floating point
186 ;; smpy         word precision integer multiply
187 ;; dmpy         longword or doublelongword precision integer multiply
188 ;; return       rts
189 ;; pload        load of pr reg, which can't be put into delay slot of rts
190 ;; prset        copy register to pr reg, ditto
191 ;; pstore       store of pr reg, which can't be put into delay slot of jsr
192 ;; prget        copy pr to register, ditto
193 ;; pcload       pc relative load of constant value
194 ;; pcload_si    Likewise, SImode variant for general register.
195 ;; rte          return from exception
196 ;; sfunc        special function call with known used registers
197 ;; call         function call
198 ;; fp           floating point
199 ;; fdiv         floating point divide (or square root)
200 ;; gp_fpul      move between general purpose register and fpul
201 ;; dfp_arith, dfp_cmp,dfp_conv
202 ;; dfdiv        double precision floating point divide (or square root)
203 ;; nil          no-op move, will be deleted.
204
205 (define_attr "type"
206  "cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,store,move,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,rte,sfunc,call,fp,fdiv,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt,ptabs,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
207   (const_string "other"))
208
209 ;; We define a new attribute namely "insn_class".We use
210 ;; this for DFA based pipeline description.
211 ;; Although the "type" attribute covers almost all insn 
212 ;; classes,it is more convenient to define new attribute
213 ;; for certain reservations.
214 ;;
215 ;; mt_group      SH4 "mt" group instructions.
216 ;;
217 ;; ex_group      SH4 "ex" group instructions.They mostly
218 ;;               overlap with arithmetic instructions but
219 ;;               new attribute defined to distinguish from
220 ;;               mt group instructions.
221 ;;
222 ;; lds_to_fpscr  The "type" attribute couldn't sufficiently
223 ;;               distinguish it from others.It is part of 
224 ;;               new attribute.Similar case with ldsmem_to_fpscr
225 ;;               and cwb. 
226
227 (define_attr "insn_class"
228              "mt_group,ex_group,lds_to_fpscr,ldsmem_to_fpscr,cwb,none"
229              (const_string "none"))
230
231 ;; Indicate what precision must be selected in fpscr for this insn, if any.
232
233 (define_attr "fp_mode" "single,double,none" (const_string "none"))
234
235 ; If a conditional branch destination is within -252..258 bytes away
236 ; from the instruction it can be 2 bytes long.  Something in the
237 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
238 ; branches are initially assumed to be 16 bytes long.
239 ; In machine_dependent_reorg, we split all branches that are longer than
240 ; 2 bytes.
241
242 ;; The maximum range used for SImode constant pool entries is 1018.  A final
243 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
244 ;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
245 ;; instruction around the pool table, 2 bytes of alignment before the table,
246 ;; and 30 bytes of alignment after the table.  That gives a maximum total
247 ;; pool size of 1058 bytes.
248 ;; Worst case code/pool content size ratio is 1:2 (using asms).
249 ;; Thus, in the worst case, there is one instruction in front of a maximum
250 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
251 ;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
252 ;; If we have a forward branch, the initial table will be put after the
253 ;; unconditional branch.
254 ;;
255 ;; ??? We could do much better by keeping track of the actual pcloads within
256 ;; the branch range and in the pcload range in front of the branch range.
257
258 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
259 ;; inside an le.
260 (define_attr "short_cbranch_p" "no,yes"
261   (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
262          (const_string "no")
263          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
264          (const_string "yes")
265          (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
266          (const_string "no")
267          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
268          (const_string "yes")
269          ] (const_string "no")))
270
271 (define_attr "med_branch_p" "no,yes"
272   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
273               (const_int 1988))
274          (const_string "yes")
275          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
276          (const_string "no")
277          (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
278               (const_int 8186))
279          (const_string "yes")
280          ] (const_string "no")))
281
282 (define_attr "med_cbranch_p" "no,yes"
283   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
284               (const_int 1986))
285          (const_string "yes")
286          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
287          (const_string "no")
288          (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
289                (const_int 8184))
290          (const_string "yes")
291          ] (const_string "no")))
292
293 (define_attr "braf_branch_p" "no,yes"
294   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
295          (const_string "no")
296          (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
297               (const_int 20660))
298          (const_string "yes")
299          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
300          (const_string "no")
301          (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
302               (const_int 65530))
303          (const_string "yes")
304          ] (const_string "no")))
305
306 (define_attr "braf_cbranch_p" "no,yes"
307   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
308          (const_string "no")
309          (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
310               (const_int 20658))
311          (const_string "yes")
312          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
313          (const_string "no")
314          (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
315               (const_int 65528))
316          (const_string "yes")
317          ] (const_string "no")))
318
319 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
320 ; For wider ranges, we need a combination of a code and a data part.
321 ; If we can get a scratch register for a long range jump, the code
322 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
323 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
324 ; long; otherwise, it must be 6 bytes long.
325
326 ; All other instructions are two bytes long by default.
327
328 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
329 ;; but getattrtab doesn't understand this.
330 (define_attr "length" ""
331   (cond [(eq_attr "type" "cbranch")
332          (cond [(eq_attr "short_cbranch_p" "yes")
333                 (const_int 2)
334                 (eq_attr "med_cbranch_p" "yes")
335                 (const_int 6)
336                 (eq_attr "braf_cbranch_p" "yes")
337                 (const_int 12)
338 ;; ??? using pc is not computed transitively.
339                 (ne (match_dup 0) (match_dup 0))
340                 (const_int 14)
341                 (ne (symbol_ref ("flag_pic")) (const_int 0))
342                 (const_int 24)
343                 ] (const_int 16))
344          (eq_attr "type" "jump")
345          (cond [(eq_attr "med_branch_p" "yes")
346                 (const_int 2)
347                 (and (eq (symbol_ref "GET_CODE (PREV_INSN (insn))")
348                          (symbol_ref "INSN"))
349                      (eq (symbol_ref "INSN_CODE (PREV_INSN (insn))")
350                          (symbol_ref "code_for_indirect_jump_scratch")))
351                 (if_then_else (eq_attr "braf_branch_p" "yes")
352                               (const_int 6)
353                               (const_int 10))
354                 (eq_attr "braf_branch_p" "yes")
355                 (const_int 10)
356 ;; ??? using pc is not computed transitively.
357                 (ne (match_dup 0) (match_dup 0))
358                 (const_int 12)
359                 (ne (symbol_ref ("flag_pic")) (const_int 0))
360                 (const_int 22)
361                 ] (const_int 14))
362          (eq_attr "type" "pt")
363          (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
364                        (const_int 20) (const_int 12))
365          ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
366                          (const_int 4)
367                          (const_int 2))))
368
369 ;; (define_function_unit {name} {num-units} {n-users} {test}
370 ;;                       {ready-delay} {issue-delay} [{conflict-list}])
371
372 ;; Load and store instructions save a cycle if they are aligned on a
373 ;; four byte boundary.  Using a function unit for stores encourages
374 ;; gcc to separate load and store instructions by one instruction,
375 ;; which makes it more likely that the linker will be able to word
376 ;; align them when relaxing.
377
378 ;; Loads have a latency of two.
379 ;; However, call insns can have a delay slot, so that we want one more
380 ;; insn to be scheduled between the load of the function address and the call.
381 ;; This is equivalent to a latency of three.
382 ;; We cannot use a conflict list for this, because we need to distinguish
383 ;; between the actual call address and the function arguments.
384 ;; ADJUST_COST can only properly handle reductions of the cost, so we
385 ;; use a latency of three here.
386 ;; We only do this for SImode loads of general registers, to make the work
387 ;; for ADJUST_COST easier.
388 (define_function_unit "memory" 1 0
389   (and (eq_attr "issues" "1")
390        (eq_attr "type" "load_si,pcload_si"))
391   3 2)
392 (define_function_unit "memory" 1 0
393   (and (eq_attr "issues" "1")
394        (eq_attr "type" "load,pcload,pload,store,pstore"))
395   2 2)
396
397 (define_function_unit "int"    1 0
398   (and (eq_attr "issues" "1") (eq_attr "type" "arith3,arith3b")) 3 3)
399
400 (define_function_unit "int"    1 0
401   (and (eq_attr "issues" "1") (eq_attr "type" "dyn_shift")) 2 2)
402
403 (define_function_unit "int"    1 0
404   (and (eq_attr "issues" "1") (eq_attr "type" "!arith3,arith3b,dyn_shift")) 1 1)
405
406 ;; ??? These are approximations.
407 (define_function_unit "mpy"    1 0
408   (and (eq_attr "issues" "1") (eq_attr "type" "smpy")) 2 2)
409 (define_function_unit "mpy"    1 0
410   (and (eq_attr "issues" "1") (eq_attr "type" "dmpy")) 3 3)
411
412 (define_function_unit "fp"     1 0
413   (and (eq_attr "issues" "1") (eq_attr "type" "fp,fmove")) 2 1)
414 (define_function_unit "fp"     1 0
415   (and (eq_attr "issues" "1") (eq_attr "type" "fdiv")) 13 12)
416
417
418 ;; SH4 scheduling
419 ;; The SH4 is a dual-issue implementation, thus we have to multiply all
420 ;; costs by at least two.
421 ;; There will be single increments of the modeled that don't correspond
422 ;; to the actual target ;; whenever two insns to be issued depend one a
423 ;; single resource, and the scheduler picks to be the first one.
424 ;; If we multiplied the costs just by two, just two of these single
425 ;; increments would amount to an actual cycle.  By picking a larger
426 ;; factor, we can ameliorate the effect; However, we then have to make sure
427 ;; that only two insns are modeled as issued per actual cycle.
428 ;; Moreover, we need a way to specify the latency of insns that don't
429 ;; use an actual function unit.
430 ;; We use an 'issue' function unit to do that, and a cost factor of 10.
431
432 (define_function_unit "issue" 2 0
433   (and (eq_attr "issues" "2") (eq_attr "type" "!nil,arith3"))
434   10 10)
435
436 (define_function_unit "issue" 2 0
437   (and (eq_attr "issues" "2") (eq_attr "type" "arith3"))
438   30 30)
439
440 ;; There is no point in providing exact scheduling information about branches,
441 ;; because they are at the starts / ends of basic blocks anyways.
442
443 ;; Some insns cannot be issued before/after another insn in the same cycle,
444 ;; irrespective of the type of the other insn.
445
446 ;; default is dual-issue, but can't be paired with an insn that
447 ;; uses multiple function units.
448 (define_function_unit "single_issue"     1 0
449   (and (eq_attr "issues" "2")
450        (eq_attr "type" "!smpy,dmpy,pload,pstore,dfp_cmp,gp_fpul,call,sfunc,arith3,arith3b"))
451   1 10
452   [(eq_attr "type" "smpy,dmpy,pload,pstore,dfp_cmp,gp_fpul")])
453
454 (define_function_unit "single_issue"     1 0
455   (and (eq_attr "issues" "2")
456        (eq_attr "type" "smpy,dmpy,pload,pstore,dfp_cmp,gp_fpul"))
457   10 10
458   [(const_int 1)])
459
460 ;; arith3 insns are always pairable at the start, but not inecessarily at
461 ;; the end; however, there doesn't seem to be a way to express that.
462 (define_function_unit "single_issue"     1 0
463   (and (eq_attr "issues" "2")
464        (eq_attr "type" "arith3"))
465   30 20
466   [(const_int 1)])
467
468 ;; arith3b insn are pairable at the end and have latency that prevents pairing
469 ;; with the following branch, but we don't want this latency be respected;
470 ;; When the following branch is immediately adjacent, we can redirect the
471 ;; internal branch, which is likly to be a larger win.
472 (define_function_unit "single_issue"     1 0
473   (and (eq_attr "issues" "2")
474        (eq_attr "type" "arith3b"))
475   20 20
476   [(const_int 1)])
477
478 ;; calls introduce a longisch delay that is likely to flush the pipelines.
479 (define_function_unit "single_issue"     1 0
480   (and (eq_attr "issues" "2")
481        (eq_attr "type" "call,sfunc"))
482   160 160
483   [(eq_attr "type" "!call") (eq_attr "type" "call")])
484
485 ;; Load and store instructions have no alignment peculiarities for the SH4,
486 ;; but they use the load-store unit, which they share with the fmove type
487 ;; insns (fldi[01]; fmov frn,frm; flds; fsts; fabs; fneg) .
488 ;; Loads have a latency of two.
489 ;; However, call insns can only paired with a preceding insn, and have
490 ;; a delay slot, so that we want two more insns to be scheduled between the
491 ;; load of the function address and the call.  This is equivalent to a
492 ;; latency of three.
493 ;; We cannot use a conflict list for this, because we need to distinguish
494 ;; between the actual call address and the function arguments.
495 ;; ADJUST_COST can only properly handle reductions of the cost, so we
496 ;; use a latency of three here, which gets multiplied by 10 to yield 30.
497 ;; We only do this for SImode loads of general registers, to make the work
498 ;; for ADJUST_COST easier.
499
500 ;; When specifying different latencies for different insns using the
501 ;; the same function unit, genattrtab.c assumes a 'FIFO constraint'
502 ;; so that the blockage is at least READY-COST (E) + 1 - READY-COST (C)
503 ;; for an executing insn E and a candidate insn C.
504 ;; Therefore, we define three different function units for load_store:
505 ;; load_store, load and load_si.
506
507 (define_function_unit "load_si" 1 0
508   (and (eq_attr "issues" "2")
509        (eq_attr "type" "load_si,pcload_si")) 30 10)
510 (define_function_unit "load" 1 0
511   (and (eq_attr "issues" "2")
512        (eq_attr "type" "load,pcload,pload")) 20 10)
513 (define_function_unit "load_store" 1 0
514   (and (eq_attr "issues" "2")
515        (eq_attr "type" "load_si,pcload_si,load,pcload,pload,store,pstore,fmove"))
516   10 10)
517
518 (define_function_unit "int"    1 0
519   (and (eq_attr "issues" "2") (eq_attr "type" "arith,dyn_shift")) 10 10)
520
521 ;; Again, we have to pretend a lower latency for the "int" unit to avoid a
522 ;; spurious FIFO constraint; the multiply instructions use the "int"
523 ;; unit actually only for two cycles.
524 (define_function_unit "int"    1 0
525   (and (eq_attr "issues" "2") (eq_attr "type" "smpy,dmpy")) 20 20)
526
527 ;; We use a fictous "mpy" unit to express the actual latency.
528 (define_function_unit "mpy"    1 0
529   (and (eq_attr "issues" "2") (eq_attr "type" "smpy,dmpy")) 40 20)
530
531 ;; Again, we have to pretend a lower latency for the "int" unit to avoid a
532 ;; spurious FIFO constraint.
533 (define_function_unit "int"     1 0
534   (and (eq_attr "issues" "2") (eq_attr "type" "gp_fpul")) 10 10)
535
536 ;; We use a fictous "gp_fpul" unit to express the actual latency.
537 (define_function_unit "gp_fpul"     1 0
538   (and (eq_attr "issues" "2") (eq_attr "type" "gp_fpul")) 20 10)
539
540 ;; ??? multiply uses the floating point unit, but with a two cycle delay.
541 ;; Thus, a simple single-precision fp operation could finish if issued in
542 ;; the very next cycle, but stalls when issued two or three cycles later.
543 ;; Similarily, a divide / sqrt can work without stalls if issued in
544 ;; the very next cycle, while it would have to block if issued two or
545 ;; three cycles later.
546 ;; There is no way to model this with gcc's function units.  This problem is
547 ;; actually mentioned in md.texi.  Tackling this problem requires first that
548 ;; it is possible to speak about the target in an open discussion.
549 ;; 
550 ;; However, simple double-precision operations always conflict.
551
552 (define_function_unit "fp"    1 0
553   (and (eq_attr "issues" "2") (eq_attr "type" "smpy,dmpy")) 40 40
554   [(eq_attr "type" "dfp_cmp,dfp_conv,dfp_arith")])
555
556 ;; The "fp" unit is for pipeline stages F1 and F2.
557
558 (define_function_unit "fp"     1 0
559   (and (eq_attr "issues" "2") (eq_attr "type" "fp")) 30 10)
560
561 ;; Again, we have to pretend a lower latency for the "fp" unit to avoid a
562 ;; spurious FIFO constraint; the bulk of the fdiv type insns executes in
563 ;; the F3 stage.
564 (define_function_unit "fp"     1 0
565   (and (eq_attr "issues" "2") (eq_attr "type" "fdiv")) 30 10)
566
567 ;; The "fdiv" function unit models the aggregate effect of the F1, F2 and F3
568 ;; pipeline stages on the pipelining of fdiv/fsqrt insns.
569 ;; We also use it to give the actual latency here.
570 ;; fsqrt is actually one cycle faster than fdiv (and the value used here),
571 ;; but that will hardly matter in practice for scheduling.
572 (define_function_unit "fdiv"     1 0
573   (and (eq_attr "issues" "2") (eq_attr "type" "fdiv")) 120 100)
574
575 ;; There is again a late use of the "fp" unit by [d]fdiv type insns
576 ;; that we can't express.
577
578 (define_function_unit "fp"     1 0
579   (and (eq_attr "issues" "2") (eq_attr "type" "dfp_cmp,dfp_conv")) 40 20)
580
581 (define_function_unit "fp"     1 0
582   (and (eq_attr "issues" "2") (eq_attr "type" "dfp_arith")) 80 60)
583
584 (define_function_unit "fp"     1 0
585   (and (eq_attr "issues" "2") (eq_attr "type" "dfdiv")) 230 10)
586
587 (define_function_unit "fdiv"     1 0
588   (and (eq_attr "issues" "2") (eq_attr "type" "dfdiv")) 230 210)
589
590 ;; This should be enough for pt insns to be moved 5 insns ahead of
591 ;; corresponding branches.
592 (define_function_unit "pt" 1 0
593   (eq_attr "type" "pt,ptabs") 10 2)
594
595 ; Definitions for filling branch delay slots.
596
597 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
598
599 ;; ??? This should be (nil) instead of (const_int 0)
600 (define_attr "hit_stack" "yes,no"
601         (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
602                    (const_int 0))
603                (const_string "no")]
604               (const_string "yes")))
605
606 (define_attr "interrupt_function" "no,yes"
607   (const (symbol_ref "current_function_interrupt")))
608
609 (define_attr "in_delay_slot" "yes,no"
610   (cond [(eq_attr "type" "cbranch") (const_string "no")
611          (eq_attr "type" "pcload,pcload_si") (const_string "no")
612          (eq_attr "needs_delay_slot" "yes") (const_string "no")
613          (eq_attr "length" "2") (const_string "yes")
614          ] (const_string "no")))
615
616 (define_attr "is_sfunc" ""
617   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
618
619 (define_delay
620   (eq_attr "needs_delay_slot" "yes")
621   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
622
623 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
624 ;; and thus we can't put a pop instruction in its delay slot.
625 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
626 ;; instruction can go in the delay slot.
627
628 ;; Since a normal return (rts) implicitly uses the PR register,
629 ;; we can't allow PR register loads in an rts delay slot.
630
631 (define_delay
632   (eq_attr "type" "return")
633   [(and (eq_attr "in_delay_slot" "yes")
634         (ior (and (eq_attr "interrupt_function" "no")
635                   (eq_attr "type" "!pload,prset"))
636              (and (eq_attr "interrupt_function" "yes")
637                   (ior
638                    (ne (symbol_ref "TARGET_SH3") (const_int 0))
639                    (eq_attr "hit_stack" "no"))))) (nil) (nil)])
640
641 ;; Since a call implicitly uses the PR register, we can't allow
642 ;; a PR register store in a jsr delay slot.
643
644 (define_delay
645   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
646   [(and (eq_attr "in_delay_slot" "yes")
647         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
648
649 ;; Say that we have annulled true branches, since this gives smaller and
650 ;; faster code when branches are predicted as not taken.
651
652 (define_delay
653   (and (eq_attr "type" "cbranch")
654        (ne (symbol_ref "TARGET_SH2") (const_int 0)))
655   [(eq_attr "in_delay_slot" "yes") (eq_attr "in_delay_slot" "yes") (nil)])
656 \f
657 ;; -------------------------------------------------------------------------
658 ;; SImode signed integer comparisons
659 ;; -------------------------------------------------------------------------
660
661 (define_insn ""
662   [(set (reg:SI T_REG)
663         (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
664                        (match_operand:SI 1 "arith_operand" "L,r"))
665                (const_int 0)))]
666   "TARGET_SH1"
667   "tst  %1,%0"
668   [(set_attr "insn_class" "mt_group")])
669
670 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
671 ;; That would still allow reload to create cmpi instructions, but would
672 ;; perhaps allow forcing the constant into a register when that is better.
673 ;; Probably should use r0 for mem/imm compares, but force constant into a
674 ;; register for pseudo/imm compares.
675
676 (define_insn "cmpeqsi_t"
677   [(set (reg:SI T_REG)
678         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
679                (match_operand:SI 1 "arith_operand" "N,rI,r")))]
680   "TARGET_SH1"
681   "@
682         tst     %0,%0
683         cmp/eq  %1,%0
684         cmp/eq  %1,%0"
685    [(set_attr "insn_class" "mt_group,mt_group,mt_group")])
686
687 (define_insn "cmpgtsi_t"
688   [(set (reg:SI T_REG)
689         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
690                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
691   "TARGET_SH1"
692   "@
693         cmp/gt  %1,%0
694         cmp/pl  %0"
695    [(set_attr "insn_class" "mt_group,mt_group")])
696
697 (define_insn "cmpgesi_t"
698   [(set (reg:SI T_REG)
699         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
700                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
701   "TARGET_SH1"
702   "@
703         cmp/ge  %1,%0
704         cmp/pz  %0"
705    [(set_attr "insn_class" "mt_group,mt_group")])
706
707 ;; -------------------------------------------------------------------------
708 ;; SImode unsigned integer comparisons
709 ;; -------------------------------------------------------------------------
710
711 (define_insn "cmpgeusi_t"
712   [(set (reg:SI T_REG)
713         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
714                 (match_operand:SI 1 "arith_reg_operand" "r")))]
715   "TARGET_SH1"
716   "cmp/hs       %1,%0"
717    [(set_attr "insn_class" "mt_group")])
718
719 (define_insn "cmpgtusi_t"
720   [(set (reg:SI T_REG)
721         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
722                 (match_operand:SI 1 "arith_reg_operand" "r")))]
723   "TARGET_SH1"
724   "cmp/hi       %1,%0"
725    [(set_attr "insn_class" "mt_group")])
726
727 ;; We save the compare operands in the cmpxx patterns and use them when
728 ;; we generate the branch.
729
730 (define_expand "cmpsi"
731   [(set (reg:SI T_REG)
732         (compare (match_operand:SI 0 "arith_operand" "")
733                  (match_operand:SI 1 "arith_operand" "")))]
734   "TARGET_SH1"
735   "
736 {
737   sh_compare_op0 = operands[0];
738   sh_compare_op1 = operands[1];
739   DONE;
740 }")
741 \f
742 ;; -------------------------------------------------------------------------
743 ;; DImode signed integer comparisons
744 ;; -------------------------------------------------------------------------
745
746 ;; ??? Could get better scheduling by splitting the initial test from the
747 ;; rest of the insn after reload.  However, the gain would hardly justify
748 ;; the sh.md size increase necessary to do that.
749
750 (define_insn ""
751   [(set (reg:SI T_REG)
752         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
753                        (match_operand:DI 1 "arith_operand" "r"))
754                (const_int 0)))]
755   "TARGET_SH1"
756   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
757                                  insn, operands);"
758   [(set_attr "length" "6")
759    (set_attr "type" "arith3b")])
760
761 (define_insn "cmpeqdi_t"
762   [(set (reg:SI T_REG)
763         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
764                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
765   "TARGET_SH1"
766   "@
767         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
768         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
769   [(set_attr "length" "6")
770    (set_attr "type" "arith3b")])
771
772 (define_split
773   [(set (reg:SI T_REG)
774         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
775                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
776 ;; If we applied this split when not optimizing, it would only be
777 ;; applied during the machine-dependent reorg, when no new basic blocks
778 ;; may be created.
779   "TARGET_SH1 && reload_completed && optimize"
780   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
781    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
782                            (label_ref (match_dup 6))
783                            (pc)))
784    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
785    (match_dup 6)]
786   "
787 {
788   operands[2]
789     = gen_rtx_REG (SImode,
790                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
791   operands[3]
792     = (operands[1] == const0_rtx
793        ? const0_rtx
794        : gen_rtx_REG (SImode,
795                       true_regnum (operands[1])
796                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
797   operands[4] = gen_lowpart (SImode, operands[0]);
798   operands[5] = gen_lowpart (SImode, operands[1]);
799   operands[6] = gen_label_rtx ();
800 }")
801
802 (define_insn "cmpgtdi_t"
803   [(set (reg:SI T_REG)
804         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
805                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
806   "TARGET_SH2"
807   "@
808         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
809         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
810   [(set_attr "length" "8")
811    (set_attr "type" "arith3")])
812
813 (define_insn "cmpgedi_t"
814   [(set (reg:SI T_REG)
815         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
816                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
817   "TARGET_SH2"
818   "@
819         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
820         cmp/pz\\t%S0"
821   [(set_attr "length" "8,2")
822    (set_attr "type" "arith3,arith")])
823 \f
824 ;; -------------------------------------------------------------------------
825 ;; DImode unsigned integer comparisons
826 ;; -------------------------------------------------------------------------
827
828 (define_insn "cmpgeudi_t"
829   [(set (reg:SI T_REG)
830         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
831                 (match_operand:DI 1 "arith_reg_operand" "r")))]
832   "TARGET_SH2"
833   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
834   [(set_attr "length" "8")
835    (set_attr "type" "arith3")])
836
837 (define_insn "cmpgtudi_t"
838   [(set (reg:SI T_REG)
839         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
840                 (match_operand:DI 1 "arith_reg_operand" "r")))]
841   "TARGET_SH2"
842   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
843   [(set_attr "length" "8")
844    (set_attr "type" "arith3")])
845
846 (define_insn "cmpeqdi_media"
847   [(set (match_operand:DI 0 "register_operand" "=r,r")
848         (eq:DI (match_operand:DI 1 "register_operand" "%r,r")
849                (match_operand:DI 2 "arith_reg_or_0_operand" "N,r")))]
850   "TARGET_SHMEDIA"
851   "@
852         cmpeq   %1, r63, %0
853         cmpeq   %1, %2, %0")
854
855 (define_insn "cmpgtdi_media"
856   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
857         (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "N,r,r")
858                (match_operand:DI 2 "arith_reg_or_0_operand" "r,N,r")))]
859   "TARGET_SHMEDIA"
860   "@
861         cmpgt   r63, %2, %0
862         cmpgt   %1, r63, %0
863         cmpgt   %1, %2, %0")
864
865 (define_insn "cmpgtudi_media"
866   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
867         (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "N,r,r")
868                 (match_operand:DI 2 "arith_reg_or_0_operand" "r,N,r")))]
869   "TARGET_SHMEDIA"
870   "@
871         cmpgtu  r63, %2, %0
872         cmpgtu  %1, r63, %0
873         cmpgtu  %1, %2, %0")
874
875 ;; We save the compare operands in the cmpxx patterns and use them when
876 ;; we generate the branch.
877
878 (define_expand "cmpdi"
879   [(set (reg:SI T_REG)
880         (compare (match_operand:DI 0 "arith_operand" "")
881                  (match_operand:DI 1 "arith_operand" "")))]
882   "TARGET_SH2 || TARGET_SHMEDIA"
883   "
884 {
885   sh_compare_op0 = operands[0];
886   sh_compare_op1 = operands[1];
887   DONE;
888 }")
889 ;; -------------------------------------------------------------------------
890 ;; Conditional move instructions
891 ;; -------------------------------------------------------------------------
892
893 ;; The insn names may seem reversed, but note that cmveq performs the move
894 ;; if op1 == 0, and cmvne does it if op1 != 0.
895
896 (define_insn "movdicc_false"
897   [(set (match_operand:DI 0 "register_operand" "=r")
898         (if_then_else:DI (eq (match_operand:DI 1 "register_operand" "r")
899                              (const_int 0))
900          (match_operand:DI 2 "register_operand" "r")
901          (match_operand:DI 3 "register_operand" "0")))]
902   "TARGET_SHMEDIA"
903   "cmveq        %1, %2, %0")
904
905 (define_insn "movdicc_true"
906   [(set (match_operand:DI 0 "register_operand" "=r")
907         (if_then_else:DI (ne (match_operand:DI 1 "register_operand" "r")
908                              (const_int 0))
909          (match_operand:DI 2 "register_operand" "r")
910          (match_operand:DI 3 "register_operand" "0")))]
911   "TARGET_SHMEDIA"
912   "cmvne        %1, %2, %0")
913
914 (define_expand "movdicc"
915   [(set (match_operand:DI 0 "register_operand" "")
916         (if_then_else:DI (match_operand 1 "comparison_operator" "")
917                          (match_operand:DI 2 "register_operand" "")
918                          (match_operand:DI 3 "register_operand" "")))]
919   "TARGET_SHMEDIA"
920   "
921 {
922   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
923       && GET_MODE (sh_compare_op0) == DImode
924       && sh_compare_op1 == const0_rtx)
925     operands[1] = gen_rtx (GET_CODE (operands[1]), VOIDmode,
926                            sh_compare_op0, sh_compare_op1);
927   else
928     {
929       rtx tmp;
930
931       if (no_new_pseudos)
932         FAIL;
933
934       tmp = gen_reg_rtx (DImode);
935
936       switch (GET_CODE (operands[1]))
937         {
938         case EQ:
939           emit_insn (gen_seq (tmp));
940           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
941           break;
942
943         case NE:
944           emit_insn (gen_seq (tmp));
945           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
946           break;
947
948         case GT:
949           emit_insn (gen_sgt (tmp));
950           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
951           break;
952
953         case LT:
954           emit_insn (gen_slt (tmp));
955           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
956           break;
957
958         case GE:
959           emit_insn (gen_slt (tmp));
960           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
961           break;
962
963         case LE:
964           emit_insn (gen_sgt (tmp));
965           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
966           break;
967
968         case GTU:
969           emit_insn (gen_sgtu (tmp));
970           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
971           break;
972
973         case LTU:
974           emit_insn (gen_sltu (tmp));
975           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
976           break;
977
978         case GEU:
979           emit_insn (gen_sltu (tmp));
980           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
981           break;
982
983         case LEU:
984           emit_insn (gen_sgtu (tmp));
985           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
986           break;
987
988         case UNORDERED:
989           emit_insn (gen_sunordered (tmp));
990           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
991           break;
992
993         case ORDERED:
994           emit_insn (gen_sunordered (tmp));
995           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
996           break;
997
998         case UNEQ:
999         case UNGE:
1000         case UNGT:
1001         case UNLE:
1002         case UNLT:
1003         case LTGT:
1004           FAIL;
1005
1006         default:
1007           abort ();
1008         }
1009     }
1010 }")
1011 \f
1012 ;; -------------------------------------------------------------------------
1013 ;; Addition instructions
1014 ;; -------------------------------------------------------------------------
1015
1016 (define_expand "adddi3"
1017   [(set (match_operand:DI 0 "arith_reg_operand" "")
1018         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1019                  (match_operand:DI 2 "arith_operand" "")))]
1020   ""
1021   "
1022 {
1023   if (TARGET_SH1)
1024     {
1025       if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
1026         FAIL;
1027       operands[2] = force_reg (DImode, operands[2]);
1028       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1029       DONE;
1030     }
1031 }")
1032
1033 (define_insn "*adddi3_media"
1034   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1035         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1036                  (match_operand:DI 2 "arith_operand" "r,P")))]
1037   "TARGET_SHMEDIA"
1038   "@
1039         add     %1, %2, %0
1040         addi    %1, %2, %0")
1041
1042 (define_insn "*adddi3z_media"
1043   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1044         (zero_extend:DI
1045          (plus:SI (match_operand:SI 1 "arith_reg_operand" "r,r")
1046                   (match_operand:SI 2 "arith_reg_or_0_operand" "r,n"))))]
1047   "TARGET_SHMEDIA"
1048   "@
1049         addz.l  %1, %2, %0
1050         addz.l  %1, r63, %0")
1051                  
1052 (define_insn "adddi3_compact"
1053   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1054         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1055                  (match_operand:DI 2 "arith_reg_operand" "r")))
1056    (clobber (reg:SI T_REG))]
1057   "TARGET_SH1"
1058   "#"
1059   [(set_attr "length" "6")])
1060
1061 (define_split
1062   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1063         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1064                  (match_operand:DI 2 "arith_reg_operand" "r")))
1065    (clobber (reg:SI T_REG))]
1066   "TARGET_SH1 && reload_completed"
1067   [(const_int 0)]
1068   "
1069 {
1070   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1071   high0 = gen_rtx_REG (SImode,
1072                        true_regnum (operands[0])
1073                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1074   high2 = gen_rtx_REG (SImode,
1075                        true_regnum (operands[2])
1076                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1077   emit_insn (gen_clrt ());
1078   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1079   emit_insn (gen_addc1 (high0, high0, high2));
1080   DONE;
1081 }")
1082
1083 (define_insn "addc"
1084   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1085         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1086                           (match_operand:SI 2 "arith_reg_operand" "r"))
1087                  (reg:SI T_REG)))
1088    (set (reg:SI T_REG)
1089         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1090   "TARGET_SH1"
1091   "addc %2,%0"
1092   [(set_attr "type" "arith")
1093    (set_attr "insn_class" "ex_group")])
1094
1095 (define_insn "addc1"
1096   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1097         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1098                           (match_operand:SI 2 "arith_reg_operand" "r"))
1099                  (reg:SI T_REG)))
1100    (clobber (reg:SI T_REG))]
1101   "TARGET_SH1"
1102   "addc %2,%0"
1103   [(set_attr "type" "arith")
1104    (set_attr "insn_class" "ex_group")])
1105
1106 (define_expand "addsi3"
1107   [(set (match_operand:SI 0 "arith_reg_operand" "")
1108         (plus:SI (match_operand:SI 1 "arith_operand" "")
1109                  (match_operand:SI 2 "arith_operand" "")))]
1110   ""
1111   "
1112 {
1113   if (TARGET_SHMEDIA)
1114     operands[1] = force_reg (SImode, operands[1]);
1115 }")
1116
1117 (define_insn "addsi3_media"
1118   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
1119         (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r")
1120                  (match_operand:SI 2 "arith_operand" "r,P")))]
1121   "TARGET_SHMEDIA"
1122   "@
1123         add.l   %1, %2, %0
1124         addi.l  %1, %2, %0")
1125   
1126 (define_insn "*addsi3_compact"
1127   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1128         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1129                  (match_operand:SI 2 "arith_operand" "rI")))]
1130   "TARGET_SH1"
1131   "add  %2,%0"
1132   [(set_attr "type" "arith")
1133    (set_attr "insn_class" "ex_group")])
1134
1135 ;; -------------------------------------------------------------------------
1136 ;; Subtraction instructions
1137 ;; -------------------------------------------------------------------------
1138
1139 (define_expand "subdi3"
1140   [(set (match_operand:DI 0 "arith_reg_operand" "")
1141         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1142                   (match_operand:DI 2 "arith_reg_operand" "")))]
1143   ""
1144   "
1145 {
1146   if (TARGET_SH1)
1147     {
1148       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1149       DONE;
1150     }
1151 }")
1152   
1153 (define_insn "*subdi3_media"
1154   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1155         (minus:DI (match_operand:DI 1 "arith_reg_operand" "r")
1156                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1157   "TARGET_SHMEDIA"
1158   "sub  %1, %2, %0")
1159   
1160 (define_insn "subdi3_compact"
1161   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1162         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1163                  (match_operand:DI 2 "arith_reg_operand" "r")))
1164    (clobber (reg:SI T_REG))]
1165   "TARGET_SH1"
1166   "#"
1167   [(set_attr "length" "6")])
1168
1169 (define_split
1170   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1171         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1172                   (match_operand:DI 2 "arith_reg_operand" "r")))
1173    (clobber (reg:SI T_REG))]
1174   "TARGET_SH1 && reload_completed"
1175   [(const_int 0)]
1176   "
1177 {
1178   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1179   high0 = gen_rtx_REG (SImode,
1180                        true_regnum (operands[0])
1181                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1182   high2 = gen_rtx_REG (SImode,
1183                        true_regnum (operands[2])
1184                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1185   emit_insn (gen_clrt ());
1186   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1187   emit_insn (gen_subc1 (high0, high0, high2));
1188   DONE;
1189 }")
1190
1191 (define_insn "subc"
1192   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1193         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1194                             (match_operand:SI 2 "arith_reg_operand" "r"))
1195                   (reg:SI T_REG)))
1196    (set (reg:SI T_REG)
1197         (gtu:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1198   "TARGET_SH1"
1199   "subc %2,%0"
1200   [(set_attr "type" "arith")
1201    (set_attr "insn_class" "ex_group")])
1202
1203 (define_insn "subc1"
1204   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1205         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1206                             (match_operand:SI 2 "arith_reg_operand" "r"))
1207                   (reg:SI T_REG)))
1208    (clobber (reg:SI T_REG))]
1209   "TARGET_SH1"
1210   "subc %2,%0"
1211   [(set_attr "type" "arith")
1212    (set_attr "insn_class" "ex_group")])
1213
1214 (define_insn "*subsi3_internal"
1215   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1216         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1217                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1218   "TARGET_SH1"
1219   "sub  %2,%0"
1220   [(set_attr "type" "arith")
1221    (set_attr "insn_class" "ex_group")])
1222
1223 (define_insn "*subsi3_media"
1224   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1225         (minus:SI (match_operand:SI 1 "arith_reg_operand" "r")
1226                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1227   "TARGET_SHMEDIA"
1228   "sub.l        %1, %2, %0")
1229
1230 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1231 ;; will sometimes save one instruction.  Otherwise we might get
1232 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1233 ;; are the same.
1234
1235 (define_expand "subsi3"
1236   [(set (match_operand:SI 0 "arith_reg_operand" "")
1237         (minus:SI (match_operand:SI 1 "arith_operand" "")
1238                   (match_operand:SI 2 "arith_reg_operand" "")))]
1239   ""
1240   "
1241 {
1242   if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1243     {
1244       emit_insn (gen_negsi2 (operands[0], operands[2]));
1245       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1246       DONE;
1247     }
1248   if (TARGET_SHMEDIA)
1249     {
1250       if (no_new_pseudos && ! arith_reg_operand (operands[1], SImode))
1251         FAIL;
1252       operands[1] = force_reg (SImode, operands[1]);
1253     }
1254 }")
1255 \f
1256 ;; -------------------------------------------------------------------------
1257 ;; Division instructions
1258 ;; -------------------------------------------------------------------------
1259
1260 ;; We take advantage of the library routines which don't clobber as many
1261 ;; registers as a normal function call would.
1262
1263 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1264 ;; also has an effect on the register that holds the address of the sfunc.
1265 ;; To make this work, we have an extra dummy insns that shows the use
1266 ;; of this register for reorg.
1267
1268 (define_insn "use_sfunc_addr"
1269   [(set (reg:SI PR_REG)
1270         (unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1271   "TARGET_SH1"
1272   ""
1273   [(set_attr "length" "0")])
1274
1275 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1276 ;; hard register 0.  If we used hard register 0, then the next instruction
1277 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1278 ;; gets allocated to a stack slot that needs its address reloaded, then
1279 ;; there is nothing to prevent reload from using r0 to reload the address.
1280 ;; This reload would clobber the value in r0 we are trying to store.
1281 ;; If we let reload allocate r0, then this problem can never happen.
1282
1283 (define_insn "udivsi3_i1"
1284   [(set (match_operand:SI 0 "register_operand" "=z")
1285         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1286    (clobber (reg:SI T_REG))
1287    (clobber (reg:SI PR_REG))
1288    (clobber (reg:SI R4_REG))
1289    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1290   "TARGET_SH1 && ! TARGET_SH4"
1291   "jsr  @%1%#"
1292   [(set_attr "type" "sfunc")
1293    (set_attr "needs_delay_slot" "yes")])
1294
1295 ; Since shmedia-nofpu code could be linked against shcompact code, and
1296 ; the udivsi3 libcall has the same name, we must consider all registers
1297 ; clobbered that are in the union of the registers clobbered by the
1298 ; shmedia and the shcompact implementation.  Note, if the shcompact
1299 ; implemenation actually used shcompact code, we'd need to clobber
1300 ; also r23 and fr23.
1301 (define_insn "udivsi3_i1_media"
1302   [(set (match_operand:SI 0 "register_operand" "=z")
1303         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1304    (clobber (reg:SI T_MEDIA_REG))
1305    (clobber (reg:SI PR_MEDIA_REG))
1306    (clobber (reg:SI R20_REG))
1307    (clobber (reg:SI R21_REG))
1308    (clobber (reg:SI R22_REG))
1309    (clobber (reg:DI TR0_REG))
1310    (clobber (reg:DI TR1_REG))
1311    (clobber (reg:DI TR2_REG))
1312    (use (match_operand:DI 1 "target_operand" "b"))]
1313   "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1314   "blink        %1, r18"
1315   [(set_attr "type" "sfunc")
1316    (set_attr "needs_delay_slot" "yes")])
1317
1318 (define_expand "udivsi3_i4_media"
1319   [(set (match_dup 2) (zero_extend:DI (reg:SI R4_REG)))
1320    (set (match_dup 3) (zero_extend:DI (reg:SI R5_REG)))
1321    (set (match_dup 4) (float:DF (match_dup 2)))
1322    (set (match_dup 5) (float:DF (match_dup 3)))
1323    (set (match_dup 6) (div:DF (match_dup 4) (match_dup 5)))
1324    (set (subreg:DI (match_operand:SI 0 "register_operand" "=r") 0)
1325         (fix:DI (match_dup 6)))]
1326   "TARGET_SHMEDIA_FPU"
1327   "
1328 {
1329   operands[2] = gen_reg_rtx (DImode);
1330   operands[3] = gen_reg_rtx (DImode);
1331   operands[4] = gen_reg_rtx (DFmode);
1332   operands[5] = gen_reg_rtx (DFmode);
1333   operands[6] = gen_reg_rtx (DFmode);
1334 }")
1335
1336 (define_insn "udivsi3_i4"
1337   [(set (match_operand:SI 0 "register_operand" "=y")
1338         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1339    (clobber (reg:SI T_REG))
1340    (clobber (reg:SI PR_REG))
1341    (clobber (reg:DF DR0_REG))
1342    (clobber (reg:DF DR2_REG))
1343    (clobber (reg:DF DR4_REG))
1344    (clobber (reg:SI R0_REG))
1345    (clobber (reg:SI R1_REG))
1346    (clobber (reg:SI R4_REG))
1347    (clobber (reg:SI R5_REG))
1348    (use (reg:PSI FPSCR_REG))
1349    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1350   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1351   "jsr  @%1%#"
1352   [(set_attr "type" "sfunc")
1353    (set_attr "fp_mode" "double")
1354    (set_attr "needs_delay_slot" "yes")])
1355
1356 (define_insn "udivsi3_i4_single"
1357   [(set (match_operand:SI 0 "register_operand" "=y")
1358         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1359    (clobber (reg:SI T_REG))
1360    (clobber (reg:SI PR_REG))
1361    (clobber (reg:DF DR0_REG))
1362    (clobber (reg:DF DR2_REG))
1363    (clobber (reg:DF DR4_REG))
1364    (clobber (reg:SI R0_REG))
1365    (clobber (reg:SI R1_REG))
1366    (clobber (reg:SI R4_REG))
1367    (clobber (reg:SI R5_REG))
1368    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1369   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1370   "jsr  @%1%#"
1371   [(set_attr "type" "sfunc")
1372    (set_attr "needs_delay_slot" "yes")])
1373
1374 (define_expand "udivsi3"
1375   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1376    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1377    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1378    (parallel [(set (match_operand:SI 0 "register_operand" "")
1379                    (udiv:SI (reg:SI R4_REG)
1380                             (reg:SI R5_REG)))
1381               (clobber (reg:SI T_REG))
1382               (clobber (reg:SI PR_REG))
1383               (clobber (reg:SI R4_REG))
1384               (use (match_dup 3))])]
1385   ""
1386   "
1387 {
1388   rtx first, last;
1389
1390   operands[3] = gen_reg_rtx (Pmode);
1391   /* Emit the move of the address to a pseudo outside of the libcall.  */
1392   if (TARGET_HARD_SH4 && TARGET_SH3E)
1393     {
1394       emit_move_insn (operands[3],
1395                       gen_rtx_SYMBOL_REF (SImode, \"__udivsi3_i4\"));
1396       if (TARGET_FPU_SINGLE)
1397         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1398       else
1399         last = gen_udivsi3_i4 (operands[0], operands[3]);
1400     }
1401   else if (TARGET_SHMEDIA_FPU)
1402     last = gen_udivsi3_i4_media (operands[0]);
1403   else if (TARGET_SH5)
1404     {
1405       emit_move_insn (operands[3],
1406                       gen_rtx_SYMBOL_REF (Pmode,
1407                                           (TARGET_FPU_ANY
1408                                            ? \"__udivsi3_i4\"
1409                                            : \"__udivsi3\")));
1410
1411       if (TARGET_SHMEDIA)
1412         last = gen_udivsi3_i1_media (operands[0],
1413                                      Pmode == DImode
1414                                      ? operands[3]
1415                                      : gen_rtx_SUBREG (DImode, operands[3],
1416                                                        0));
1417       else if (TARGET_FPU_ANY)
1418         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1419       else
1420         last = gen_udivsi3_i1 (operands[0], operands[3]);
1421     }
1422   else
1423     {
1424       emit_move_insn (operands[3],
1425                       gen_rtx_SYMBOL_REF (SImode, \"__udivsi3\"));
1426       last = gen_udivsi3_i1 (operands[0], operands[3]);
1427     }
1428   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1429   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1430   last = emit_insn (last);
1431   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1432      invariant code motion can move it.  */
1433   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1434   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1435   DONE;
1436 }")
1437
1438 (define_insn "divsi3_i1"
1439   [(set (match_operand:SI 0 "register_operand" "=z")
1440         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1441    (clobber (reg:SI T_REG))
1442    (clobber (reg:SI PR_REG))
1443    (clobber (reg:SI R1_REG))
1444    (clobber (reg:SI R2_REG))
1445    (clobber (reg:SI R3_REG))
1446    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1447   "TARGET_SH1 && ! TARGET_SH4"
1448   "jsr  @%1%#"
1449   [(set_attr "type" "sfunc")
1450    (set_attr "needs_delay_slot" "yes")])
1451
1452 ; Since shmedia-nofpu code could be linked against shcompact code, and
1453 ; the udivsi3 libcall has the same name, we must consider all registers
1454 ; clobbered that are in the union of the registers clobbered by the
1455 ; shmedia and the shcompact implementation.  Note, if the shcompact
1456 ; implemenation actually used shcompact code, we'd need to clobber
1457 ; also r22, r23 and fr23.
1458 (define_insn "divsi3_i1_media"
1459   [(set (match_operand:SI 0 "register_operand" "=z")
1460         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1461    (clobber (reg:SI T_MEDIA_REG))
1462    (clobber (reg:SI PR_MEDIA_REG))
1463    (clobber (reg:SI R1_REG))
1464    (clobber (reg:SI R2_REG))
1465    (clobber (reg:SI R3_REG))
1466    (clobber (reg:SI R20_REG))
1467    (clobber (reg:SI R21_REG))
1468    (clobber (reg:DI TR0_REG))
1469    (clobber (reg:DI TR1_REG))
1470    (clobber (reg:DI TR2_REG))
1471    (use (match_operand:DI 1 "target_operand" "b"))]
1472   "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1473   "blink        %1, r18")
1474
1475 (define_expand "divsi3_i4_media"
1476   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1477    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1478    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1479    (set (match_operand:SI 0 "register_operand" "=r")
1480         (fix:SI (match_dup 5)))]
1481   "TARGET_SHMEDIA_FPU"
1482   "
1483 {
1484   operands[3] = gen_reg_rtx (DFmode);
1485   operands[4] = gen_reg_rtx (DFmode);
1486   operands[5] = gen_reg_rtx (DFmode);
1487 }")
1488
1489 (define_insn "divsi3_i4"
1490   [(set (match_operand:SI 0 "register_operand" "=y")
1491         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1492    (clobber (reg:SI PR_REG))
1493    (clobber (reg:DF DR0_REG))
1494    (clobber (reg:DF DR2_REG))
1495    (use (reg:PSI FPSCR_REG))
1496    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1497   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1498   "jsr  @%1%#"
1499   [(set_attr "type" "sfunc")
1500    (set_attr "fp_mode" "double")
1501    (set_attr "needs_delay_slot" "yes")])
1502
1503 (define_insn "divsi3_i4_single"
1504   [(set (match_operand:SI 0 "register_operand" "=y")
1505         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1506    (clobber (reg:SI PR_REG))
1507    (clobber (reg:DF DR0_REG))
1508    (clobber (reg:DF DR2_REG))
1509    (clobber (reg:SI R2_REG))
1510    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1511   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1512   "jsr  @%1%#"
1513   [(set_attr "type" "sfunc")
1514    (set_attr "needs_delay_slot" "yes")])
1515
1516 (define_expand "divsi3"
1517   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1518    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1519    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1520    (parallel [(set (match_operand:SI 0 "register_operand" "")
1521                    (div:SI (reg:SI R4_REG)
1522                            (reg:SI R5_REG)))
1523               (clobber (reg:SI T_REG))
1524               (clobber (reg:SI PR_REG))
1525               (clobber (reg:SI R1_REG))
1526               (clobber (reg:SI R2_REG))
1527               (clobber (reg:SI R3_REG))
1528               (use (match_dup 3))])]
1529   ""
1530   "
1531 {
1532   rtx first = 0, last;
1533
1534   operands[3] = gen_reg_rtx (Pmode);
1535   /* Emit the move of the address to a pseudo outside of the libcall.  */
1536   if (TARGET_HARD_SH4 && TARGET_SH3E)
1537     {
1538       emit_move_insn (operands[3],
1539                       gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3_i4\"));
1540       if (TARGET_FPU_SINGLE)
1541         last = gen_divsi3_i4_single (operands[0], operands[3]);
1542       else
1543         last = gen_divsi3_i4 (operands[0], operands[3]);
1544     }
1545   else if (TARGET_SHMEDIA_FPU)
1546     {
1547       operands[1] = force_reg (SImode, operands[1]);
1548       operands[2] = force_reg (SImode, operands[2]);
1549       last = gen_divsi3_i4_media (operands[0], operands[1], operands[2]);
1550       first = last;
1551     }
1552   else if (TARGET_SH5)
1553     {
1554       emit_move_insn (operands[3],
1555                       gen_rtx_SYMBOL_REF (Pmode,
1556                                           (TARGET_FPU_ANY
1557                                            ? \"__sdivsi3_i4\"
1558                                            : \"__sdivsi3\")));
1559
1560       if (TARGET_SHMEDIA)
1561         last = gen_divsi3_i1_media (operands[0], 
1562                                     Pmode == DImode
1563                                     ? operands[3]
1564                                     : gen_rtx_SUBREG (DImode, operands[3],
1565                                                       0));
1566       else if (TARGET_FPU_ANY)
1567         last = gen_divsi3_i4_single (operands[0], operands[3]);
1568       else
1569         last = gen_divsi3_i1 (operands[0], operands[3]);
1570     }
1571   else
1572     {
1573       emit_move_insn (operands[3], gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3\"));
1574       last = gen_divsi3_i1 (operands[0], operands[3]);
1575     }
1576   if (! first)
1577     {
1578       first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1579       emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1580     }
1581   last = emit_insn (last);
1582   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1583      invariant code motion can move it.  */
1584   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1585   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1586   DONE;
1587 }")
1588 \f
1589 ;; -------------------------------------------------------------------------
1590 ;; Multiplication instructions
1591 ;; -------------------------------------------------------------------------
1592
1593 (define_insn "umulhisi3_i"
1594   [(set (reg:SI MACL_REG)
1595         (mult:SI (zero_extend:SI
1596                   (match_operand:HI 0 "arith_reg_operand" "r"))
1597                  (zero_extend:SI
1598                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
1599   "TARGET_SH1"
1600   "mulu.w       %1,%0"
1601   [(set_attr "type" "smpy")])
1602
1603 (define_insn "mulhisi3_i"
1604   [(set (reg:SI MACL_REG)
1605         (mult:SI (sign_extend:SI
1606                   (match_operand:HI 0 "arith_reg_operand" "r"))
1607                  (sign_extend:SI
1608                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
1609   "TARGET_SH1"
1610   "muls.w       %1,%0"
1611   [(set_attr "type" "smpy")])
1612
1613 (define_expand "mulhisi3"
1614   [(set (reg:SI MACL_REG)
1615         (mult:SI (sign_extend:SI
1616                   (match_operand:HI 1 "arith_reg_operand" ""))
1617                  (sign_extend:SI
1618                   (match_operand:HI 2 "arith_reg_operand" ""))))
1619    (set (match_operand:SI 0 "arith_reg_operand" "")
1620         (reg:SI MACL_REG))]
1621   "TARGET_SH1"
1622   "
1623 {
1624   rtx first, last;
1625
1626   first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1627   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1628   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1629      invariant code motion can move it.  */
1630   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1631   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1632   DONE;
1633 }")
1634
1635 (define_expand "umulhisi3"
1636   [(set (reg:SI MACL_REG)
1637         (mult:SI (zero_extend:SI
1638                   (match_operand:HI 1 "arith_reg_operand" ""))
1639                  (zero_extend:SI
1640                   (match_operand:HI 2 "arith_reg_operand" ""))))
1641    (set (match_operand:SI 0 "arith_reg_operand" "")
1642         (reg:SI MACL_REG))]
1643   "TARGET_SH1"
1644   "
1645 {
1646   rtx first, last;
1647
1648   first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1649   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1650   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1651      invariant code motion can move it.  */
1652   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1653   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1654   DONE;
1655 }")
1656
1657 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1658 ;; a call to a routine which clobbers known registers.
1659
1660 (define_insn ""
1661   [(set (match_operand:SI 1 "register_operand" "=z")
1662         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1663    (clobber (reg:SI MACL_REG))
1664    (clobber (reg:SI T_REG))
1665    (clobber (reg:SI PR_REG))
1666    (clobber (reg:SI R3_REG))
1667    (clobber (reg:SI R2_REG))
1668    (clobber (reg:SI R1_REG))
1669    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1670   "TARGET_SH1"
1671   "jsr  @%0%#"
1672   [(set_attr "type" "sfunc")
1673    (set_attr "needs_delay_slot" "yes")])
1674
1675 (define_expand "mulsi3_call"
1676   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1677    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1678    (parallel[(set (match_operand:SI 0 "register_operand" "")
1679                   (mult:SI (reg:SI R4_REG)
1680                            (reg:SI R5_REG)))
1681              (clobber (reg:SI MACL_REG))
1682              (clobber (reg:SI T_REG))
1683              (clobber (reg:SI PR_REG))
1684              (clobber (reg:SI R3_REG))
1685              (clobber (reg:SI R2_REG))
1686              (clobber (reg:SI R1_REG))
1687              (use (match_operand:SI 3 "register_operand" ""))])]
1688   "TARGET_SH1"
1689   "")
1690
1691 (define_insn "mul_l"
1692   [(set (reg:SI MACL_REG)
1693         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1694                  (match_operand:SI 1 "arith_reg_operand" "r")))]
1695   "TARGET_SH2"
1696   "mul.l        %1,%0"
1697   [(set_attr "type" "dmpy")])
1698
1699 (define_expand "mulsi3"
1700   [(set (reg:SI MACL_REG)
1701         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
1702                   (match_operand:SI 2 "arith_reg_operand" "")))
1703    (set (match_operand:SI 0 "arith_reg_operand" "")
1704         (reg:SI MACL_REG))]
1705   "TARGET_SH1"
1706   "
1707 {
1708   rtx first, last;
1709
1710   if (!TARGET_SH2)
1711     {
1712       /* The address must be set outside the libcall,
1713          since it goes into a pseudo.  */
1714       rtx sym = gen_rtx_SYMBOL_REF (SImode, \"__mulsi3\");
1715       rtx addr = force_reg (SImode, sym);
1716       rtx insns = gen_mulsi3_call (operands[0], operands[1],
1717                                    operands[2], addr);
1718       first = insns;
1719       last = emit_insn (insns);
1720     }
1721   else
1722     {
1723       rtx macl = gen_rtx_REG (SImode, MACL_REG);
1724
1725       first = emit_insn (gen_mul_l (operands[1], operands[2]));
1726       /* consec_sets_giv can only recognize the first insn that sets a
1727          giv as the giv insn.  So we must tag this also with a REG_EQUAL
1728          note.  */
1729       last = emit_insn (gen_movsi_i ((operands[0]), macl));
1730     }
1731   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1732      invariant code motion can move it.  */
1733   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1734   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1735   DONE;
1736 }")
1737
1738 (define_insn "mulsidi3_i"
1739   [(set (reg:SI MACH_REG)
1740         (truncate:SI
1741          (lshiftrt:DI
1742           (mult:DI
1743            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1744            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1745           (const_int 32))))
1746    (set (reg:SI MACL_REG)
1747         (mult:SI (match_dup 0)
1748                  (match_dup 1)))]
1749   "TARGET_SH2"
1750   "dmuls.l      %1,%0"
1751   [(set_attr "type" "dmpy")])
1752
1753 (define_expand "mulsidi3"
1754   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1755         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1756                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1757   "TARGET_SH2 || TARGET_SHMEDIA"
1758   "
1759 {
1760   if (TARGET_SH2)
1761     {
1762        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1763                                         operands[2]));
1764        DONE;
1765     }
1766 }")
1767
1768 (define_insn "mulsidi3_media"
1769   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1770         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "%r"))
1771                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1772   "TARGET_SHMEDIA"
1773   "muls.l       %1, %2, %0")
1774   
1775 (define_insn "mulsidi3_compact"
1776   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1777         (mult:DI
1778          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1779          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1780    (clobber (reg:SI MACH_REG))
1781    (clobber (reg:SI MACL_REG))]
1782   "TARGET_SH2"
1783   "#")
1784
1785 (define_split
1786   [(set (match_operand:DI 0 "arith_reg_operand" "")
1787         (mult:DI
1788          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1789          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1790    (clobber (reg:SI MACH_REG))
1791    (clobber (reg:SI MACL_REG))]
1792   "TARGET_SH2"
1793   [(const_int 0)]
1794   "
1795 {
1796   rtx low_dst = gen_lowpart (SImode, operands[0]);
1797   rtx high_dst = gen_highpart (SImode, operands[0]);
1798
1799   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1800
1801   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1802   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1803   /* We need something to tag the possible REG_EQUAL notes on to.  */
1804   emit_move_insn (operands[0], operands[0]);
1805   DONE;
1806 }")
1807
1808 (define_insn "umulsidi3_i"
1809   [(set (reg:SI MACH_REG)
1810         (truncate:SI
1811          (lshiftrt:DI
1812           (mult:DI
1813            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1814            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1815           (const_int 32))))
1816    (set (reg:SI MACL_REG)
1817         (mult:SI (match_dup 0)
1818                  (match_dup 1)))]
1819   "TARGET_SH2"
1820   "dmulu.l      %1,%0"
1821   [(set_attr "type" "dmpy")])
1822
1823 (define_expand "umulsidi3"
1824   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1825         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1826                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1827   "TARGET_SH2 || TARGET_SHMEDIA"
1828   "
1829 {
1830   if (TARGET_SH2)
1831     {
1832        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1833                                          operands[2]));
1834        DONE;
1835     }
1836 }")
1837
1838 (define_insn "umulsidi3_media"
1839   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1840         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "%r"))
1841                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1842   "TARGET_SHMEDIA"
1843   "mulu.l       %1, %2, %0")
1844   
1845 (define_insn "umulsidi3_compact"
1846   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1847         (mult:DI
1848          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1849          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1850    (clobber (reg:SI MACH_REG))
1851    (clobber (reg:SI MACL_REG))]
1852   "TARGET_SH2"
1853   "#")
1854
1855 (define_split
1856   [(set (match_operand:DI 0 "arith_reg_operand" "")
1857         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1858                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1859    (clobber (reg:SI MACH_REG))
1860    (clobber (reg:SI MACL_REG))]
1861   "TARGET_SH2"
1862   [(const_int 0)]
1863   "
1864 {
1865   rtx low_dst = gen_lowpart (SImode, operands[0]);
1866   rtx high_dst = gen_highpart (SImode, operands[0]);
1867
1868   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1869
1870   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1871   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1872   /* We need something to tag the possible REG_EQUAL notes on to.  */
1873   emit_move_insn (operands[0], operands[0]);
1874   DONE;
1875 }")
1876
1877 (define_insn "smulsi3_highpart_i"
1878   [(set (reg:SI MACH_REG)
1879         (truncate:SI
1880          (lshiftrt:DI
1881           (mult:DI
1882            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1883            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1884           (const_int 32))))
1885    (clobber (reg:SI MACL_REG))]
1886   "TARGET_SH2"
1887   "dmuls.l      %1,%0"
1888   [(set_attr "type" "dmpy")])
1889
1890 (define_expand "smulsi3_highpart"
1891   [(parallel
1892     [(set (reg:SI MACH_REG)
1893           (truncate:SI
1894            (lshiftrt:DI
1895             (mult:DI
1896              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1897              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1898             (const_int 32))))
1899     (clobber (reg:SI MACL_REG))])
1900    (set (match_operand:SI 0 "arith_reg_operand" "")
1901         (reg:SI MACH_REG))]
1902   "TARGET_SH2"
1903   "
1904 {
1905   rtx first, last;
1906
1907   first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1908   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1909   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1910      invariant code motion can move it.  */
1911   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1912   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1913   /* expand_binop can't find a suitable code in mul_highpart_optab to
1914      make a REG_EQUAL note from, so make one here.
1915      ??? Alternatively, we could put this at the calling site of expand_binop,
1916      i.e. expand_mult_highpart.  */
1917   REG_NOTES (last)
1918     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1919                          REG_NOTES (last));
1920   DONE;
1921 }")
1922
1923 (define_insn "umulsi3_highpart_i"
1924   [(set (reg:SI MACH_REG)
1925         (truncate:SI
1926          (lshiftrt:DI
1927           (mult:DI
1928            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1929            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1930           (const_int 32))))
1931    (clobber (reg:SI MACL_REG))]
1932   "TARGET_SH2"
1933   "dmulu.l      %1,%0"
1934   [(set_attr "type" "dmpy")])
1935
1936 (define_expand "umulsi3_highpart"
1937   [(parallel
1938     [(set (reg:SI MACH_REG)
1939           (truncate:SI
1940            (lshiftrt:DI
1941             (mult:DI
1942              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1943              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1944             (const_int 32))))
1945     (clobber (reg:SI MACL_REG))])
1946    (set (match_operand:SI 0 "arith_reg_operand" "")
1947         (reg:SI MACH_REG))]
1948   "TARGET_SH2"
1949   "
1950 {
1951   rtx first, last;
1952
1953   first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1954   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1955   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1956      invariant code motion can move it.  */
1957   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1958   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1959   DONE;
1960 }")
1961 \f
1962 ;; -------------------------------------------------------------------------
1963 ;; Logical operations
1964 ;; -------------------------------------------------------------------------
1965
1966 (define_insn ""
1967   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1968         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1969                 (match_operand:SI 2 "logical_operand" "r,L")))]
1970   "TARGET_SH1"
1971   "and  %2,%0"
1972   [(set_attr "type" "arith")
1973    (set_attr "insn_class" "ex_group")])
1974
1975 ;; If the constant is 255, then emit a extu.b instruction instead of an
1976 ;; and, since that will give better code.
1977
1978 (define_expand "andsi3"
1979   [(set (match_operand:SI 0 "arith_reg_operand" "")
1980         (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1981                 (match_operand:SI 2 "logical_operand" "")))]
1982   "TARGET_SH1"
1983   "
1984 {
1985   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1986     {
1987       emit_insn (gen_zero_extendqisi2 (operands[0],
1988                                        gen_lowpart (QImode, operands[1])));
1989       DONE;
1990     }
1991 }")
1992
1993 (define_insn_and_split "anddi3"
1994   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1995         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
1996                 (match_operand:DI 2 "and_operand" "r,P,n")))]
1997   "TARGET_SHMEDIA"
1998   "@
1999         and     %1, %2, %0
2000         andi    %1, %2, %0
2001         #"
2002   "reload_completed
2003    && ! logical_operand (operands[2], DImode)"
2004   [(const_int 0)]
2005   "
2006 {
2007   if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
2008     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
2009   else
2010     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
2011   DONE;
2012 }")
2013
2014 (define_insn "*andcdi3"
2015   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2016         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
2017                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
2018   "TARGET_SHMEDIA"
2019   "andc %1,%2,%0")
2020
2021 (define_insn "iorsi3"
2022   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
2023         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2024                 (match_operand:SI 2 "logical_operand" "r,L")))]
2025   "TARGET_SH1"
2026   "or   %2,%0"
2027   [(set_attr "type" "arith")
2028    (set_attr "insn_class" "ex_group")])
2029
2030 (define_insn "iordi3"
2031   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2032         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2033                 (match_operand:DI 2 "logical_operand" "r,P")))]
2034   "TARGET_SHMEDIA"
2035   "@
2036         or      %1, %2, %0
2037         ori     %1, %2, %0")
2038
2039 (define_insn "xorsi3"
2040   [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
2041         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2042                 (match_operand:SI 2 "logical_operand" "L,r")))]
2043   "TARGET_SH1"
2044   "xor  %2,%0"
2045   [(set_attr "type" "arith")
2046    (set_attr "insn_class" "ex_group")])
2047
2048 (define_insn "xordi3"
2049   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2050         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2051                 (match_operand:DI 2 "shmedia_6bit_operand" "r,O")))]
2052   "TARGET_SHMEDIA"
2053   "@
2054         xor     %1, %2, %0
2055         xori    %1, %2, %0")
2056 \f
2057 ;; -------------------------------------------------------------------------
2058 ;; Shifts and rotates
2059 ;; -------------------------------------------------------------------------
2060
2061 (define_insn "rotlsi3_1"
2062   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2063         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2064                    (const_int 1)))
2065    (set (reg:SI T_REG)
2066         (lshiftrt:SI (match_dup 1) (const_int 31)))]
2067   "TARGET_SH1"
2068   "rotl %0"
2069   [(set_attr "type" "arith")
2070    (set_attr "insn_class" "ex_group")])
2071
2072 (define_insn "rotlsi3_31"
2073   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2074         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2075                    (const_int 31)))
2076    (clobber (reg:SI T_REG))]
2077   "TARGET_SH1"
2078   "rotr %0"
2079   [(set_attr "type" "arith")
2080    (set_attr "insn_class" "ex_group")])
2081
2082 (define_insn "rotlsi3_16"
2083   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2084         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2085                    (const_int 16)))]
2086   "TARGET_SH1"
2087   "swap.w       %1,%0"
2088   [(set_attr "type" "arith")
2089   (set_attr "insn_class" "ex_group")])
2090
2091 (define_expand "rotlsi3"
2092   [(set (match_operand:SI 0 "arith_reg_operand" "")
2093         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2094                    (match_operand:SI 2 "immediate_operand" "")))]
2095   "TARGET_SH1"
2096   "
2097 {
2098   static const char rot_tab[] = {
2099     000, 000, 000, 000, 000, 000, 010, 001,
2100     001, 001, 011, 013, 003, 003, 003, 003,
2101     003, 003, 003, 003, 003, 013, 012, 002,
2102     002, 002, 010, 000, 000, 000, 000, 000,
2103   };
2104
2105   int count, choice;
2106
2107   if (GET_CODE (operands[2]) != CONST_INT)
2108     FAIL;
2109   count = INTVAL (operands[2]);
2110   choice = rot_tab[count];
2111   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2112     FAIL;
2113   choice &= 7;
2114   switch (choice)
2115     {
2116     case 0:
2117       emit_move_insn (operands[0], operands[1]);
2118       count -= (count & 16) * 2;
2119       break;
2120     case 3:
2121      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2122      count -= 16;
2123      break;
2124     case 1:
2125     case 2:
2126       {
2127         rtx parts[2];
2128         parts[0] = gen_reg_rtx (SImode);
2129         parts[1] = gen_reg_rtx (SImode);
2130         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2131         parts[choice-1] = operands[1];
2132         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2133         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2134         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2135         count = (count & ~16) - 8;
2136       }
2137     }
2138
2139   for (; count > 0; count--)
2140     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2141   for (; count < 0; count++)
2142     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2143
2144   DONE;
2145 }")
2146
2147 (define_insn "*rotlhi3_8"
2148   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2149         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2150                    (const_int 8)))]
2151   "TARGET_SH1"
2152   "swap.b       %1,%0"
2153   [(set_attr "type" "arith")
2154    (set_attr "insn_class" "ex_group")])
2155
2156 (define_expand "rotlhi3"
2157   [(set (match_operand:HI 0 "arith_reg_operand" "")
2158         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2159                    (match_operand:HI 2 "immediate_operand" "")))]
2160   "TARGET_SH1"
2161   "
2162 {
2163   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2164     FAIL;
2165 }")
2166
2167 ;;
2168 ;; shift left
2169
2170 ;; This pattern is used by init_expmed for computing the costs of shift
2171 ;; insns.
2172
2173 (define_insn_and_split "ashlsi3_std"
2174   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2175         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2176                    (match_operand:SI 2 "nonmemory_operand" "r,M,K,?ri")))
2177    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2178   "TARGET_SH3
2179    || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2180        && CONST_OK_FOR_K (INTVAL (operands[2])))"
2181   "@
2182    shld %2,%0
2183    add  %0,%0
2184    shll%O2      %0
2185    #"
2186   "TARGET_SH3
2187    && reload_completed
2188    && GET_CODE (operands[2]) == CONST_INT
2189    && ! CONST_OK_FOR_K (INTVAL (operands[2]))"
2190   [(set (match_dup 3) (match_dup 2))
2191    (parallel
2192     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2193      (clobber (match_dup 4))])]
2194   "operands[4] = gen_rtx_SCRATCH (SImode);"
2195   [(set_attr "length" "*,*,*,4")
2196    (set_attr "type" "dyn_shift,arith,arith,arith")
2197    (set_attr "insn_class" "ex_group,ex_group,ex_group,ex_group")])
2198
2199 (define_insn "ashlhi3_k"
2200   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2201         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2202                    (match_operand:HI 2 "const_int_operand" "M,K")))]
2203   "TARGET_SH1 && CONST_OK_FOR_K (INTVAL (operands[2]))"
2204   "@
2205         add     %0,%0
2206         shll%O2 %0"
2207   [(set_attr "type" "arith")
2208    (set_attr "insn_class" "ex_group")])
2209
2210 (define_insn "ashlsi3_n"
2211   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2212         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2213                    (match_operand:SI 2 "const_int_operand" "n")))
2214    (clobber (reg:SI T_REG))]
2215   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2216   "#"
2217   [(set (attr "length")
2218         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2219                (const_string "2")
2220                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2221                (const_string "4")
2222                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2223                (const_string "6")]
2224               (const_string "8")))
2225    (set_attr "type" "arith")
2226    (set_attr "insn_class" "ex_group")])
2227
2228 (define_split
2229   [(set (match_operand:SI 0 "arith_reg_operand" "")
2230         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2231                    (match_operand:SI 2 "const_int_operand" "n")))
2232    (clobber (reg:SI T_REG))]
2233   "TARGET_SH1 && reload_completed"
2234   [(use (reg:SI R0_REG))]
2235   "
2236 {
2237   gen_shifty_op (ASHIFT, operands);
2238   DONE;
2239 }")
2240
2241 (define_insn "ashlsi3_media"
2242   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2243         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r,r")
2244                    (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2245   "TARGET_SHMEDIA"
2246   "@
2247         shlld.l %1, %2, %0
2248         shlli.l %1, %2, %0")
2249
2250 (define_expand "ashlsi3"
2251   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2252                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2253                               (match_operand:SI 2 "nonmemory_operand" "")))
2254               (clobber (reg:SI T_REG))])]
2255   ""
2256   "
2257 {
2258   if (TARGET_SHMEDIA)
2259     {
2260       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2261       DONE;
2262     }
2263   if (GET_CODE (operands[2]) == CONST_INT
2264       && sh_dynamicalize_shift_p (operands[2]))
2265     operands[2] = force_reg (SImode, operands[2]);
2266   if (TARGET_SH3)
2267     {
2268       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2269       DONE;
2270     }
2271   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2272     FAIL;
2273 }")
2274
2275 (define_insn "ashlhi3"
2276   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2277         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2278                    (match_operand:HI 2 "const_int_operand" "n")))
2279    (clobber (reg:SI T_REG))]
2280   "TARGET_SH1"
2281   "#"
2282   [(set (attr "length")
2283         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2284                (const_string "2")
2285                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2286                (const_string "4")]
2287               (const_string "6")))
2288    (set_attr "type" "arith")])
2289
2290 (define_split
2291   [(set (match_operand:HI 0 "arith_reg_operand" "")
2292         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2293                    (match_operand:HI 2 "const_int_operand" "n")))
2294    (clobber (reg:SI T_REG))]
2295   "TARGET_SH1 && reload_completed"
2296   [(use (reg:SI R0_REG))]
2297   "
2298 {
2299   gen_shifty_hi_op (ASHIFT, operands);
2300   DONE;
2301 }")
2302
2303 ;
2304 ; arithmetic shift right
2305 ;
2306
2307 (define_insn "ashrsi3_k"
2308   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2309         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2310                      (match_operand:SI 2 "const_int_operand" "M")))
2311    (clobber (reg:SI T_REG))]
2312   "TARGET_SH1 && INTVAL (operands[2]) == 1"
2313   "shar %0"
2314   [(set_attr "type" "arith")
2315    (set_attr "insn_class" "ex_group")])
2316
2317 ;; We can't do HImode right shifts correctly unless we start out with an
2318 ;; explicit zero / sign extension; doing that would result in worse overall
2319 ;; code, so just let the machine independent code widen the mode.
2320 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2321
2322
2323 ;; ??? This should be a define expand.
2324
2325 (define_insn "ashrsi2_16"
2326   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2327         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2328                      (const_int 16)))]
2329   "TARGET_SH1"
2330   "#"
2331   [(set_attr "length" "4")])
2332
2333 (define_split
2334   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2335         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2336                      (const_int 16)))]
2337   "TARGET_SH1"
2338   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2339    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2340   "operands[2] = gen_lowpart (HImode, operands[0]);")
2341
2342 ;; ??? This should be a define expand.
2343
2344 (define_insn "ashrsi2_31"
2345   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2346         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2347                      (const_int 31)))
2348    (clobber (reg:SI T_REG))]
2349   "TARGET_SH1"
2350   "#"
2351   [(set_attr "length" "4")])
2352
2353 (define_split
2354   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2355         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2356                      (const_int 31)))
2357    (clobber (reg:SI T_REG))]
2358   "TARGET_SH1"
2359   [(const_int 0)]
2360   "
2361 {
2362   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2363   emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2364   DONE;
2365 }")
2366
2367 (define_insn "ashlsi_c"
2368   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2369         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2370    (set (reg:SI T_REG)
2371         (lt:SI (match_dup 1) (const_int 0)))]
2372   "TARGET_SH1"
2373   "shll %0"
2374   [(set_attr "type" "arith")
2375    (set_attr "insn_class" "ex_group")])
2376
2377 (define_insn "ashrsi3_d"
2378   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2379         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2380                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2381   "TARGET_SH3"
2382   "shad %2,%0"
2383   [(set_attr "type" "dyn_shift")
2384    (set_attr "insn_class" "ex_group")])
2385
2386 (define_insn "ashrsi3_n"
2387   [(set (reg:SI R4_REG)
2388         (ashiftrt:SI (reg:SI R4_REG)
2389                      (match_operand:SI 0 "const_int_operand" "i")))
2390    (clobber (reg:SI T_REG))
2391    (clobber (reg:SI PR_REG))
2392    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2393   "TARGET_SH1"
2394   "jsr  @%1%#"
2395   [(set_attr "type" "sfunc")
2396    (set_attr "needs_delay_slot" "yes")])
2397
2398 (define_insn "ashrsi3_media"
2399   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2400         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r,r")
2401                      (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2402   "TARGET_SHMEDIA"
2403   "@
2404         shard.l %1, %2, %0
2405         shari.l %1, %2, %0")
2406
2407 (define_expand "ashrsi3"
2408   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2409                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2410                                 (match_operand:SI 2 "nonmemory_operand" "")))
2411               (clobber (reg:SI T_REG))])]
2412   ""
2413   "
2414 {
2415   if (TARGET_SHMEDIA)
2416     {
2417       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2418       DONE;
2419     }
2420   if (expand_ashiftrt (operands))
2421     DONE;
2422   else
2423     FAIL;
2424 }")
2425
2426 ;; logical shift right
2427
2428 (define_insn "lshrsi3_d"
2429   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2430         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2431                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2432   "TARGET_SH3"
2433   "shld %2,%0"
2434   [(set_attr "type" "dyn_shift")
2435    (set_attr "insn_class" "ex_group")])
2436
2437 ;;  Only the single bit shift clobbers the T bit.
2438
2439 (define_insn "lshrsi3_m"
2440   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2441         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2442                      (match_operand:SI 2 "const_int_operand" "M")))
2443    (clobber (reg:SI T_REG))]
2444   "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2445   "shlr %0"
2446   [(set_attr "type" "arith")
2447    (set_attr "insn_class" "ex_group")])
2448
2449 (define_insn "lshrsi3_k"
2450   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2451         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2452                      (match_operand:SI 2 "const_int_operand" "K")))]
2453   "TARGET_SH1 && CONST_OK_FOR_K (INTVAL (operands[2]))
2454    && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2455   "shlr%O2      %0"
2456   [(set_attr "type" "arith")
2457    (set_attr "insn_class" "ex_group")])
2458
2459 (define_insn "lshrsi3_n"
2460   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2461         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2462                      (match_operand:SI 2 "const_int_operand" "n")))
2463    (clobber (reg:SI T_REG))]
2464   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2465   "#"
2466   [(set (attr "length")
2467         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2468                (const_string "2")
2469                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2470                (const_string "4")
2471                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2472                (const_string "6")]
2473               (const_string "8")))
2474    (set_attr "type" "arith")])
2475
2476 (define_split
2477   [(set (match_operand:SI 0 "arith_reg_operand" "")
2478         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2479                      (match_operand:SI 2 "const_int_operand" "n")))
2480    (clobber (reg:SI T_REG))]
2481   "TARGET_SH1 && reload_completed"
2482   [(use (reg:SI R0_REG))]
2483   "
2484 {
2485   gen_shifty_op (LSHIFTRT, operands);
2486   DONE;
2487 }")
2488
2489 (define_insn "lshrsi3_media"
2490   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2491         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r,r")
2492                      (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2493   "TARGET_SHMEDIA"
2494   "@
2495         shlrd.l %1, %2, %0
2496         shlri.l %1, %2, %0")
2497
2498 (define_expand "lshrsi3"
2499   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2500                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2501                                 (match_operand:SI 2 "nonmemory_operand" "")))
2502               (clobber (reg:SI T_REG))])]
2503   ""
2504   "
2505 {
2506   if (TARGET_SHMEDIA)
2507     {
2508       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2509       DONE;
2510     }
2511   if (GET_CODE (operands[2]) == CONST_INT
2512       && sh_dynamicalize_shift_p (operands[2]))
2513     operands[2] = force_reg (SImode, operands[2]);
2514   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2515     {
2516       rtx count = copy_to_mode_reg (SImode, operands[2]);
2517       emit_insn (gen_negsi2 (count, count));
2518       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2519       DONE;
2520     }
2521   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2522     FAIL;
2523 }")
2524
2525 ;; ??? This should be a define expand.
2526
2527 (define_insn "ashldi3_k"
2528   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2529         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2530                    (const_int 1)))
2531    (clobber (reg:SI T_REG))]
2532   "TARGET_SH1"
2533   "shll %R0\;rotcl      %S0"
2534   [(set_attr "length" "4")
2535    (set_attr "type" "arith")
2536    (set_attr "insn_class" "ex_group")])
2537
2538 (define_insn "ashldi3_media"
2539   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2540         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2541                    (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2542   "TARGET_SHMEDIA"
2543   "@
2544         shlld   %1, %2, %0
2545         shlli   %1, %2, %0")
2546
2547 (define_expand "ashldi3"
2548   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2549                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2550                               (match_operand:DI 2 "immediate_operand" "")))
2551               (clobber (reg:SI T_REG))])]
2552   ""
2553   "
2554 {
2555   if (TARGET_SHMEDIA)
2556     {
2557       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2558       DONE;
2559     }
2560   if (GET_CODE (operands[2]) != CONST_INT
2561       || INTVAL (operands[2]) != 1)
2562     FAIL;
2563 }")
2564
2565 ;; ??? This should be a define expand.
2566
2567 (define_insn "lshrdi3_k"
2568   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2569         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2570                      (const_int 1)))
2571    (clobber (reg:SI T_REG))]
2572   "TARGET_SH1"
2573   "shlr %S0\;rotcr      %R0"
2574   [(set_attr "length" "4")
2575    (set_attr "type" "arith")
2576    (set_attr "insn_class" "ex_group")])
2577
2578 (define_insn "lshrdi3_media"
2579   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2580         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2581                      (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2582   "TARGET_SHMEDIA"
2583   "@
2584         shlrd   %1, %2, %0
2585         shlri   %1, %2, %0")
2586
2587 (define_expand "lshrdi3"
2588   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2589                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2590                                (match_operand:DI 2 "immediate_operand" "")))
2591              (clobber (reg:SI T_REG))])]
2592   ""
2593   "
2594 {
2595   if (TARGET_SHMEDIA)
2596     {
2597       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2598       DONE;
2599     }
2600   if (GET_CODE (operands[2]) != CONST_INT
2601       || INTVAL (operands[2]) != 1)
2602     FAIL;
2603 }")
2604
2605 ;; ??? This should be a define expand.
2606
2607 (define_insn "ashrdi3_k"
2608   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2609         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2610                      (const_int 1)))
2611    (clobber (reg:SI T_REG))]
2612   "TARGET_SH1"
2613   "shar %S0\;rotcr      %R0"
2614   [(set_attr "length" "4")
2615    (set_attr "type" "arith")
2616    (set_attr "insn_class" "ex_group")])
2617
2618 (define_insn "ashrdi3_media"
2619   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2620         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2621                      (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2622   "TARGET_SHMEDIA"
2623   "@
2624         shard   %1, %2, %0
2625         shari   %1, %2, %0")
2626
2627 (define_expand "ashrdi3"
2628   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2629                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2630                                 (match_operand:DI 2 "immediate_operand" "")))
2631               (clobber (reg:SI T_REG))])]
2632   ""
2633   "
2634 {
2635   if (TARGET_SHMEDIA)
2636     {
2637       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2638       DONE;
2639     }
2640   if (GET_CODE (operands[2]) != CONST_INT
2641       || INTVAL (operands[2]) != 1)
2642     FAIL;
2643 }")
2644
2645 ;; combined left/right shift
2646
2647 (define_split
2648   [(set (match_operand:SI 0 "register_operand" "")
2649         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2650                            (match_operand:SI 2 "const_int_operand" "n"))
2651                 (match_operand:SI 3 "const_int_operand" "n")))]
2652   "TARGET_SH1 && (unsigned)INTVAL (operands[2]) < 32"
2653   [(use (reg:SI R0_REG))]
2654   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2655    DONE;")
2656
2657 (define_split
2658   [(set (match_operand:SI 0 "register_operand" "")
2659         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2660                            (match_operand:SI 2 "const_int_operand" "n"))
2661                 (match_operand:SI 3 "const_int_operand" "n")))
2662    (clobber (reg:SI T_REG))]
2663   "TARGET_SH1 && (unsigned)INTVAL (operands[2]) < 32"
2664   [(use (reg:SI R0_REG))]
2665   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2666    DONE;")
2667
2668 (define_insn ""
2669   [(set (match_operand:SI 0 "register_operand" "=r")
2670         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2671                            (match_operand:SI 2 "const_int_operand" "n"))
2672                 (match_operand:SI 3 "const_int_operand" "n")))
2673    (clobber (reg:SI T_REG))]
2674   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2675  "#"
2676   [(set (attr "length")
2677         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2678                (const_string "4")
2679                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2680                (const_string "6")
2681                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2682                (const_string "8")
2683                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2684                (const_string "10")
2685                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2686                (const_string "12")
2687                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2688                (const_string "14")
2689                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2690                (const_string "16")]
2691               (const_string "18")))
2692    (set_attr "type" "arith")])
2693
2694 (define_insn ""
2695   [(set (match_operand:SI 0 "register_operand" "=z")
2696         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2697                            (match_operand:SI 2 "const_int_operand" "n"))
2698                 (match_operand:SI 3 "const_int_operand" "n")))
2699    (clobber (reg:SI T_REG))]
2700   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2701  "#"
2702   [(set (attr "length")
2703         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2704                (const_string "4")
2705                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2706                (const_string "6")
2707                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2708                (const_string "8")]
2709               (const_string "10")))
2710    (set_attr "type" "arith")])
2711
2712 ;; shift left / and combination with a scratch register: The combine pass
2713 ;; does not accept the individual instructions, even though they are
2714 ;; cheap.  But it needs a precise description so that it is usable after
2715 ;; reload.
2716 (define_insn "and_shl_scratch"
2717   [(set (match_operand:SI 0 "register_operand" "=r,&r")
2718         (lshiftrt:SI
2719          (ashift:SI
2720           (and:SI
2721            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2722                         (match_operand:SI 2 "const_int_operand" "N,n"))
2723            (match_operand:SI 3 "" "0,r"))
2724           (match_operand:SI 4 "const_int_operand" "n,n"))
2725          (match_operand:SI 5 "const_int_operand" "n,n")))
2726    (clobber (reg:SI T_REG))]
2727   "TARGET_SH1"
2728   "#"
2729   [(set (attr "length")
2730         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2731                (const_string "4")
2732                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2733                (const_string "6")
2734                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2735                (const_string "8")
2736                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2737                (const_string "10")]
2738               (const_string "12")))
2739    (set_attr "type" "arith")])
2740
2741 (define_split
2742   [(set (match_operand:SI 0 "register_operand" "=r,&r")
2743         (lshiftrt:SI
2744          (ashift:SI
2745           (and:SI
2746            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2747                         (match_operand:SI 2 "const_int_operand" "N,n"))
2748            (match_operand:SI 3 "register_operand" "0,r"))
2749           (match_operand:SI 4 "const_int_operand" "n,n"))
2750          (match_operand:SI 5 "const_int_operand" "n,n")))
2751    (clobber (reg:SI T_REG))]
2752   "TARGET_SH1"
2753   [(use (reg:SI R0_REG))]
2754   "
2755 {
2756   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2757
2758   if (INTVAL (operands[2]))
2759     {
2760       gen_shifty_op (LSHIFTRT, operands);
2761     }
2762   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2763   operands[2] = operands[4];
2764   gen_shifty_op (ASHIFT, operands);
2765   if (INTVAL (operands[5]))
2766     {
2767       operands[2] = operands[5];
2768       gen_shifty_op (LSHIFTRT, operands);
2769     }
2770   DONE;
2771 }")
2772
2773 ;; signed left/right shift combination.
2774 (define_split
2775   [(set (match_operand:SI 0 "register_operand" "=r")
2776         (sign_extract:SI
2777          (ashift:SI (match_operand:SI 1 "register_operand" "r")
2778                     (match_operand:SI 2 "const_int_operand" "n"))
2779          (match_operand:SI 3 "const_int_operand" "n")
2780          (const_int 0)))
2781    (clobber (reg:SI T_REG))]
2782   "TARGET_SH1"
2783   [(use (reg:SI R0_REG))]
2784   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2785    DONE;")
2786
2787 (define_insn "shl_sext_ext"
2788   [(set (match_operand:SI 0 "register_operand" "=r")
2789         (sign_extract:SI
2790          (ashift:SI (match_operand:SI 1 "register_operand" "0")
2791                     (match_operand:SI 2 "const_int_operand" "n"))
2792          (match_operand:SI 3 "const_int_operand" "n")
2793          (const_int 0)))
2794    (clobber (reg:SI T_REG))]
2795   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2796   "#"
2797   [(set (attr "length")
2798         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2799                (const_string "2")
2800                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2801                (const_string "4")
2802                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2803                (const_string "6")
2804                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2805                (const_string "8")
2806                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2807                (const_string "10")
2808                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2809                (const_string "12")
2810                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2811                (const_string "14")
2812                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2813                (const_string "16")]
2814               (const_string "18")))
2815     (set_attr "type" "arith")])
2816
2817 (define_insn "shl_sext_sub"
2818   [(set (match_operand:SI 0 "register_operand" "=z")
2819         (sign_extract:SI
2820          (ashift:SI (match_operand:SI 1 "register_operand" "0")
2821                     (match_operand:SI 2 "const_int_operand" "n"))
2822          (match_operand:SI 3 "const_int_operand" "n")
2823          (const_int 0)))
2824    (clobber (reg:SI T_REG))]
2825   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2826   "#"
2827   [(set (attr "length")
2828         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2829                (const_string "6")
2830                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2831                (const_string "8")
2832                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2833                (const_string "10")
2834                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2835                (const_string "12")]
2836               (const_string "14")))
2837     (set_attr "type" "arith")])
2838
2839 ;; These patterns are found in expansions of DImode shifts by 16, and
2840 ;; allow the xtrct instruction to be generated from C source.
2841
2842 (define_insn "xtrct_left"
2843   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2844         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2845                            (const_int 16))
2846                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2847                              (const_int 16))))]
2848   "TARGET_SH1"
2849   "xtrct        %1,%0"
2850   [(set_attr "type" "arith")
2851    (set_attr "insn_class" "ex_group")])
2852
2853 (define_insn "xtrct_right"
2854   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2855         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2856                              (const_int 16))
2857                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2858                            (const_int 16))))]
2859   "TARGET_SH1"
2860   "xtrct        %2,%0"
2861   [(set_attr "type" "arith")
2862    (set_attr "insn_class" "ex_group")])
2863
2864 ;; -------------------------------------------------------------------------
2865 ;; Unary arithmetic
2866 ;; -------------------------------------------------------------------------
2867
2868 (define_insn "negc"
2869   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2870         (neg:SI (plus:SI (reg:SI T_REG)
2871                          (match_operand:SI 1 "arith_reg_operand" "r"))))
2872    (set (reg:SI T_REG)
2873         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2874                (const_int 0)))]
2875   "TARGET_SH1"
2876   "negc %1,%0"
2877   [(set_attr "type" "arith")
2878    (set_attr "insn_class" "ex_group")])
2879
2880 (define_insn "*negdi_media"
2881   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2882         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2883   "TARGET_SHMEDIA"
2884   "sub  r63, %1, %0")
2885
2886 (define_expand "negdi2"
2887   [(set (match_operand:DI 0 "arith_reg_operand" "")
2888         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))
2889    (clobber (reg:SI T_REG))]
2890   ""
2891   "
2892 {
2893   if (TARGET_SH1)
2894     {
2895       int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2896       int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2897
2898       rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2899       rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2900
2901       rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2902       rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2903
2904       emit_insn (gen_clrt ());
2905       emit_insn (gen_negc (low_dst, low_src));
2906       emit_insn (gen_negc (high_dst, high_src));
2907       DONE;
2908     }
2909 }")
2910
2911 (define_insn "negsi2"
2912   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2913         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2914   "TARGET_SH1"
2915   "neg  %1,%0"
2916   [(set_attr "type" "arith")
2917    (set_attr "insn_class" "ex_group")])
2918
2919 (define_insn "one_cmplsi2"
2920   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2921         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2922   "TARGET_SH1"
2923   "not  %1,%0"
2924   [(set_attr "type" "arith")
2925    (set_attr "insn_class" "ex_group")])
2926
2927 (define_expand "one_cmpldi2"
2928   [(set (match_operand:DI 0 "arith_reg_operand" "")
2929         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2930                 (const_int -1)))]
2931   "TARGET_SHMEDIA" "")
2932 \f
2933 ;; -------------------------------------------------------------------------
2934 ;; Zero extension instructions
2935 ;; -------------------------------------------------------------------------
2936
2937 (define_insn "zero_extendsidi2"
2938   [(set (match_operand:DI 0 "register_operand" "=r")
2939         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2940   "TARGET_SHMEDIA"
2941   "addz.l       %1, r63, %0")
2942
2943 (define_insn "zero_extendhidi2"
2944   [(set (match_operand:DI 0 "register_operand" "=r,r")
2945         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
2946   "TARGET_SHMEDIA"
2947   "@
2948         #
2949         ld%M1.uw        %m1, %0")
2950
2951 (define_split
2952   [(set (match_operand:DI 0 "register_operand" "=r")
2953         (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
2954   "TARGET_SHMEDIA && reload_completed"
2955   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
2956    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))])
2957
2958 (define_insn "zero_extendqidi2"
2959   [(set (match_operand:DI 0 "register_operand" "=r,r")
2960         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
2961   "TARGET_SHMEDIA"
2962   "@
2963         andi    %1, 255, %0
2964         ld%M1.ub        %m1, %0")
2965
2966 (define_insn "zero_extendhisi2"
2967   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2968         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
2969   "TARGET_SH1"
2970   "extu.w       %1,%0"
2971   [(set_attr "type" "arith")
2972    (set_attr "insn_class" "ex_group")])
2973
2974 (define_insn "zero_extendqisi2"
2975   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2976         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
2977   "TARGET_SH1"
2978   "extu.b       %1,%0"
2979   [(set_attr "type" "arith")
2980    (set_attr "insn_class" "ex_group")])
2981
2982 (define_insn "zero_extendqihi2"
2983   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2984         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
2985   "TARGET_SH1"
2986   "extu.b       %1,%0"
2987   [(set_attr "type" "arith")
2988    (set_attr "insn_class" "ex_group")])
2989
2990 ;; -------------------------------------------------------------------------
2991 ;; Sign extension instructions
2992 ;; -------------------------------------------------------------------------
2993
2994 ;; ??? This should be a define expand.
2995 ;; ??? Or perhaps it should be dropped?
2996
2997 ;; convert_move generates good code for SH[1-4].
2998 (define_insn "extendsidi2"
2999   [(set (match_operand:DI 0 "register_operand" "=r,r")
3000         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3001   "TARGET_SHMEDIA"
3002   "@
3003         add.l   %1, r63, %0
3004         ld%M1.l %m1, %0")
3005
3006 (define_insn "extendhidi2"
3007   [(set (match_operand:DI 0 "register_operand" "=r,r")
3008         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3009   "TARGET_SHMEDIA"
3010   "@
3011         #
3012         ld%M1.w %m1, %0")
3013
3014 (define_split
3015   [(set (match_operand:DI 0 "register_operand" "=r")
3016         (sign_extend:DI (match_operand:HI 1 "register_operand" "r")))]
3017   "TARGET_SHMEDIA && reload_completed"
3018   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3019    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))])
3020
3021 (define_insn "extendqidi2"
3022   [(set (match_operand:DI 0 "register_operand" "=r,r")
3023         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
3024   "TARGET_SHMEDIA"
3025   "@
3026         #
3027         ld%M1.b %m1, %0")
3028
3029 (define_split
3030   [(set (match_operand:DI 0 "register_operand" "=r")
3031         (sign_extend:DI (match_operand:QI 1 "register_operand" "r")))]
3032   "TARGET_SHMEDIA && reload_completed"
3033   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3034    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))])
3035
3036 (define_insn "extendhisi2"
3037   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3038         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3039   "TARGET_SH1"
3040   "@
3041         exts.w  %1,%0
3042         mov.w   %1,%0"
3043   [(set_attr "type" "arith,load")
3044    (set_attr "insn_class" "ex_group,*")])
3045
3046 (define_insn "extendqisi2"
3047   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3048         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3049   "TARGET_SH1"
3050   "@
3051         exts.b  %1,%0
3052         mov.b   %1,%0"
3053   [(set_attr "type" "arith,load")
3054    (set_attr "insn_class" "ex_group,*")])
3055
3056 (define_insn "extendqihi2"
3057   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3058         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3059   "TARGET_SH1"
3060   "@
3061         exts.b  %1,%0
3062         mov.b   %1,%0"
3063   [(set_attr "type" "arith,load")
3064    (set_attr "insn_class" "ex_group,*")])
3065
3066 ;; -------------------------------------------------------------------------
3067 ;; Move instructions
3068 ;; -------------------------------------------------------------------------
3069
3070 ;; define push and pop so it is easy for sh.c
3071 ;; We can't use push and pop on SHcompact because the stack must always
3072 ;; be 8-byte aligned.
3073
3074 (define_expand "push"
3075   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3076         (match_operand:SI 0 "register_operand" "r,l,x"))]
3077   "TARGET_SH1 && ! TARGET_SH5"
3078   "")
3079
3080 (define_expand "pop"
3081   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3082         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3083   "TARGET_SH1 && ! TARGET_SH5"
3084   "")
3085
3086 (define_expand "push_e"
3087   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3088                    (match_operand:SF 0 "" ""))
3089               (use (reg:PSI FPSCR_REG))
3090               (clobber (scratch:SI))])]
3091   "TARGET_SH1 && ! TARGET_SH5"
3092   "")
3093
3094 (define_insn "push_fpul"
3095   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3096   "TARGET_SH3E && ! TARGET_SH5"
3097   "sts.l        fpul,@-r15"
3098   [(set_attr "type" "store")
3099    (set_attr "hit_stack" "yes")])
3100
3101 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3102 ;; so use that.
3103 (define_expand "push_4"
3104   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3105                    (match_operand:DF 0 "" ""))
3106               (use (reg:PSI FPSCR_REG))
3107               (clobber (scratch:SI))])]
3108   "TARGET_SH1 && ! TARGET_SH5"
3109   "")
3110
3111 (define_expand "pop_e"
3112   [(parallel [(set (match_operand:SF 0 "" "")
3113               (mem:SF (post_inc:SI (reg:SI SP_REG))))
3114               (use (reg:PSI FPSCR_REG))
3115               (clobber (scratch:SI))])]
3116   "TARGET_SH1 && ! TARGET_SH5"
3117   "")
3118
3119 (define_insn "pop_fpul"
3120   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3121   "TARGET_SH3E && ! TARGET_SH5"
3122   "lds.l        @r15+,fpul"
3123   [(set_attr "type" "load")
3124    (set_attr "hit_stack" "yes")])
3125
3126 (define_expand "pop_4"
3127   [(parallel [(set (match_operand:DF 0 "" "")
3128                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
3129               (use (reg:PSI FPSCR_REG))
3130               (clobber (scratch:SI))])]
3131   "TARGET_SH1 && ! TARGET_SH5"
3132   "")
3133
3134 ;; These two patterns can happen as the result of optimization, when
3135 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3136 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3137
3138 (define_insn "clrt"
3139   [(set (reg:SI T_REG) (const_int 0))]
3140   "TARGET_SH1"
3141   "clrt")
3142
3143 (define_insn "sett"
3144   [(set (reg:SI T_REG) (const_int 1))]
3145   "TARGET_SH1"
3146   "sett")
3147
3148 ;; t/r must come after r/r, lest reload will try to reload stuff like
3149 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3150 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3151 (define_insn "movsi_i"
3152   [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3153         (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3154   "TARGET_SH1
3155    && ! TARGET_SH3E
3156    && (register_operand (operands[0], SImode)
3157        || register_operand (operands[1], SImode))"
3158   "@
3159         mov.l   %1,%0
3160         mov     %1,%0
3161         cmp/pl  %1
3162         mov.l   %1,%0
3163         sts     %1,%0
3164         sts     %1,%0
3165         movt    %0
3166         mov.l   %1,%0
3167         sts.l   %1,%0
3168         sts.l   %1,%0
3169         lds     %1,%0
3170         lds     %1,%0
3171         lds.l   %1,%0
3172         lds.l   %1,%0
3173         fake    %1,%0"
3174   [(set_attr "type" "pcload_si,move,*,load_si,move,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3175    (set_attr "insn_class"  "*,*,mt_group,*,*,*,*,*,*,*,*,*,*,*,*")
3176    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3177
3178 ;; t/r must come after r/r, lest reload will try to reload stuff like
3179 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3180 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3181 ;; will require a reload.
3182 (define_insn "movsi_ie"
3183   [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,y")
3184         (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y"))]
3185   "TARGET_SH3E
3186    && (register_operand (operands[0], SImode)
3187        || register_operand (operands[1], SImode))"
3188   "@
3189         mov.l   %1,%0
3190         mov     %1,%0
3191         cmp/pl  %1
3192         mov.l   %1,%0
3193         sts     %1,%0
3194         sts     %1,%0
3195         movt    %0
3196         mov.l   %1,%0
3197         sts.l   %1,%0
3198         sts.l   %1,%0
3199         lds     %1,%0
3200         lds     %1,%0
3201         lds.l   %1,%0
3202         lds.l   %1,%0
3203         lds.l   %1,%0
3204         sts.l   %1,%0
3205         fake    %1,%0
3206         lds     %1,%0
3207         sts     %1,%0
3208         ! move optimized away"
3209   [(set_attr "type" "pcload_si,move,*,load_si,move,prget,move,store,store,pstore,move,prset,load,pload,load,store,pcload_si,gp_fpul,gp_fpul,nil")
3210    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3211
3212 (define_insn "movsi_i_lowpart"
3213   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3214         (match_operand:SI 1 "general_movsrc_operand" "Q,rI,mr,x,l,t,r,i"))]
3215    "TARGET_SH1
3216     && (register_operand (operands[0], SImode)
3217         || register_operand (operands[1], SImode))"
3218   "@
3219         mov.l   %1,%0
3220         mov     %1,%0
3221         mov.l   %1,%0
3222         sts     %1,%0
3223         sts     %1,%0
3224         movt    %0
3225         mov.l   %1,%0
3226         fake    %1,%0"
3227   [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
3228
3229 (define_insn "*movsi_media"
3230   [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,m,f,m,f,r,f,*b*k,r,b*k")
3231         (match_operand:SI 1 "general_movsrc_operand" "r,JS,ns,m,r,m,f,r,f,f,r,*b*k,T"))]
3232   "TARGET_SHMEDIA_FPU
3233    && (register_operand (operands[0], SImode)
3234        || register_operand (operands[1], SImode))"
3235   "@
3236         add.l   %1, r63, %0
3237         movi    %1, %0
3238         #
3239         ld%M1.l %m1, %0
3240         st%M0.l %m0, %1
3241         fld%M1.s        %m1, %0
3242         fst%M0.s        %m0, %1
3243         fmov.ls %1, %0
3244         fmov.sl %1, %0
3245         fmov.s  %1, %0
3246         ptabs   %1, %0
3247         gettr   %1, %0
3248         pt      %1, %0"
3249   [(set_attr "type"   "move,move,*,load,store,load,store,move,move,move,ptabs,move,pt")
3250    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3251
3252 (define_insn "*movsi_media_nofpu"
3253   [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,m,*b*k,r,b*k")
3254         (match_operand:SI 1 "general_movsrc_operand" "r,JS,ns,m,r,r,*b*k,T"))]
3255   "TARGET_SHMEDIA
3256    && (register_operand (operands[0], SImode)
3257        || register_operand (operands[1], SImode))"
3258   "@
3259         add.l   %1, r63, %0
3260         movi    %1, %0
3261         #
3262         ld%M1.l %m1, %0
3263         st%M0.l %m0, %1
3264         ptabs   %1, %0
3265         gettr   %1, %0
3266         pt      %1, %0"
3267   [(set_attr "type"   "move,move,*,load,store,ptabs,move,pt")
3268    (set_attr "length" "4,4,8,4,4,4,4,12")])
3269
3270 (define_split
3271   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3272         (match_operand:SI 1 "immediate_operand" "s"))]
3273   "TARGET_SHMEDIA && reload_completed
3274    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3275   [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3276   "
3277 {
3278   operands[2] = shallow_copy_rtx (operands[1]);
3279   PUT_MODE (operands[2], DImode);
3280 }")
3281
3282 (define_split
3283   [(set (match_operand:SI 0 "register_operand" "=r")
3284         (match_operand:SI 1 "immediate_operand" "n"))]
3285   "TARGET_SHMEDIA
3286    && ((GET_CODE (operands[1]) == CONST_INT
3287         && ! CONST_OK_FOR_J (INTVAL (operands[1])))
3288        || GET_CODE (operands[1]) == CONST_DOUBLE)"
3289   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3290
3291 (define_expand "movsi"
3292   [(set (match_operand:SI 0 "general_movdst_operand" "")
3293         (match_operand:SI 1 "general_movsrc_operand" ""))]
3294   ""
3295   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
3296
3297 (define_expand "ic_invalidate_line"
3298   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
3299                                 (match_dup 1)] UNSPEC_ICACHE)
3300               (clobber (scratch:SI))])]
3301   "TARGET_HARD_SH4 || TARGET_SH5"
3302   "
3303 {
3304   if (TARGET_SHMEDIA)
3305     {
3306       emit_insn (gen_ic_invalidate_line_media (operands[0]));
3307       DONE;
3308     }
3309   else if (TARGET_SHCOMPACT)
3310     {
3311       operands[1] = gen_rtx_SYMBOL_REF (Pmode, \"__ic_invalidate\");
3312       operands[1] = force_reg (Pmode, operands[1]);
3313       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3314       DONE;
3315     }
3316   operands[0] = force_reg (Pmode, operands[0]);
3317   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3318                                                                Pmode)));
3319 }")
3320
3321 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
3322 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3323 ;; the requirement *1*00 for associative address writes.  The alignment of
3324 ;; %0 implies that its least significant bit is cleared,
3325 ;; thus we clear the V bit of a matching entry if there is one.
3326 (define_insn "ic_invalidate_line_i"
3327   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
3328                      (match_operand:SI 1 "register_operand" "r")]
3329                      UNSPEC_ICACHE)
3330    (clobber (match_scratch:SI 2 "=&r"))]
3331   "TARGET_HARD_SH4"
3332   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
3333   [(set_attr "length" "8")
3334    (set_attr "insn_class" "cwb")])
3335
3336 (define_insn "ic_invalidate_line_media"
3337   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3338                     UNSPEC_ICACHE)]
3339   "TARGET_SHMEDIA"
3340   "icbi %0, 0\;synci"
3341   [(set_attr "length" "8")])
3342
3343 (define_insn "ic_invalidate_line_compact"
3344   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3345                      (match_operand:SI 1 "register_operand" "r")]
3346                     UNSPEC_ICACHE)
3347    (clobber (reg:SI PR_REG))]
3348   "TARGET_SHCOMPACT"
3349   "jsr @%1%#"
3350   [(set_attr "type" "sfunc")
3351    (set_attr "needs_delay_slot" "yes")])
3352
3353 (define_insn "movqi_i"
3354   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3355         (match_operand:QI 1 "general_movsrc_operand"  "ri,m,r,t,l,r"))]
3356   "TARGET_SH1
3357    && (arith_reg_operand (operands[0], QImode)
3358        || arith_reg_operand (operands[1], QImode))"
3359   "@
3360         mov     %1,%0
3361         mov.b   %1,%0
3362         mov.b   %1,%0
3363         movt    %0
3364         sts     %1,%0
3365         lds     %1,%0"
3366  [(set_attr "type" "move,load,store,move,move,move")])
3367
3368 (define_insn "*movqi_media"
3369   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
3370         (match_operand:QI 1 "general_movsrc_operand" "r,JS,m,r"))]
3371   "TARGET_SHMEDIA
3372    && (arith_reg_operand (operands[0], QImode)
3373        || arith_reg_operand (operands[1], QImode))"
3374   "@
3375         add.l   %1, r63, %0
3376         movi    %1, %0
3377         ld%M1.b %m1, %0
3378         st%M0.b %m0, %1")
3379
3380 (define_expand "movqi"
3381   [(set (match_operand:QI 0 "general_operand" "")
3382         (match_operand:QI 1 "general_operand"  ""))]
3383   ""
3384   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
3385
3386 (define_insn "movhi_i"
3387   [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
3388         (match_operand:HI 1 "general_movsrc_operand" "Q,rI,m,t,r,l,r,i"))]
3389   "TARGET_SH1
3390    && (arith_reg_operand (operands[0], HImode)
3391        || arith_reg_operand (operands[1], HImode))"
3392   "@
3393         mov.w   %1,%0
3394         mov     %1,%0
3395         mov.w   %1,%0
3396         movt    %0
3397         mov.w   %1,%0
3398         sts     %1,%0
3399         lds     %1,%0
3400         fake    %1,%0"
3401   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
3402
3403 (define_insn "*movhi_media"
3404   [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
3405         (match_operand:HI 1 "general_movsrc_operand" "r,JS,n,m,r"))]
3406   "TARGET_SHMEDIA
3407    && (arith_reg_operand (operands[0], HImode)
3408        || arith_reg_operand (operands[1], HImode))"
3409   "@
3410         add.l   %1, r63, %0
3411         movi    %1, %0
3412         #
3413         ld%M1.w %m1, %0
3414         st%M0.w %m0, %1")
3415
3416 (define_split
3417   [(set (match_operand:HI 0 "register_operand" "=r")
3418         (match_operand:HI 1 "immediate_operand" "n"))]
3419   "TARGET_SHMEDIA && ! CONST_OK_FOR_J (INTVAL (operands[1]))"
3420   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3421
3422 (define_expand "movhi"
3423   [(set (match_operand:HI 0 "general_movdst_operand" "")
3424         (match_operand:HI 1 "general_movsrc_operand"  ""))]
3425   ""
3426   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3427
3428 ;; ??? This should be a define expand.
3429
3430 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3431 ;; compiled with -m2 -ml -O3 -funroll-loops
3432 (define_insn ""
3433   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3434         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I,i,x,r"))]
3435   "TARGET_SH1
3436    && (arith_reg_operand (operands[0], DImode)
3437        || arith_reg_operand (operands[1], DImode))"
3438   "* return output_movedouble (insn, operands, DImode);"
3439   [(set_attr "length" "4")
3440    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
3441
3442 ;; If the output is a register and the input is memory or a register, we have
3443 ;; to be careful and see which word needs to be loaded first.  
3444
3445 (define_split
3446   [(set (match_operand:DI 0 "general_movdst_operand" "")
3447         (match_operand:DI 1 "general_movsrc_operand" ""))]
3448   "TARGET_SH1 && reload_completed"
3449   [(set (match_dup 2) (match_dup 3))
3450    (set (match_dup 4) (match_dup 5))]
3451   "
3452 {
3453   int regno;
3454
3455   if ((GET_CODE (operands[0]) == MEM
3456        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3457       || (GET_CODE (operands[1]) == MEM
3458           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3459     FAIL;
3460
3461   if (GET_CODE (operands[0]) == REG)
3462     regno = REGNO (operands[0]);
3463   else if (GET_CODE (operands[0]) == SUBREG)
3464     regno = subreg_regno (operands[0]);
3465   else if (GET_CODE (operands[0]) == MEM)
3466     regno = -1;
3467   else
3468     abort ();
3469
3470   if (regno == -1
3471       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
3472     {
3473       operands[2] = operand_subword (operands[0], 0, 0, DImode);
3474       operands[3] = operand_subword (operands[1], 0, 0, DImode);
3475       operands[4] = operand_subword (operands[0], 1, 0, DImode);
3476       operands[5] = operand_subword (operands[1], 1, 0, DImode);
3477     }
3478   else
3479     {
3480       operands[2] = operand_subword (operands[0], 1, 0, DImode);
3481       operands[3] = operand_subword (operands[1], 1, 0, DImode);
3482       operands[4] = operand_subword (operands[0], 0, 0, DImode);
3483       operands[5] = operand_subword (operands[1], 0, 0, DImode);
3484     }
3485
3486   if (operands[2] == 0 || operands[3] == 0
3487       || operands[4] == 0 || operands[5] == 0)
3488     FAIL;
3489 }")
3490
3491 (define_insn "*movdi_media"
3492   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,f,m,f,r,f,*b*k,r,b*k")
3493         (match_operand:DI 1 "general_movsrc_operand" "r,JS,iF,m,rl,m,f,r,f,f,r,*b*k,T"))]
3494   "TARGET_SHMEDIA_FPU
3495    && (register_operand (operands[0], DImode)
3496        || register_operand (operands[1], DImode))"
3497   "@
3498         add     %1, r63, %0
3499         movi    %1, %0
3500         #
3501         ld%M1.q %m1, %0
3502         st%M0.q %m0, %1
3503         fld%M1.d        %m1, %0
3504         fst%M0.d        %m0, %1
3505         fmov.qd %1, %0
3506         fmov.dq %1, %0
3507         fmov.d  %1, %0
3508         ptabs   %1, %0
3509         gettr   %1, %0
3510         pt      %1, %0"
3511   [(set_attr "type"   "move,move,*,load,store,load,store,move,move,move,ptabs,move,pt")
3512    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3513
3514 (define_insn "*movdi_media_nofpu"
3515   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b*k,r,b*k")
3516         (match_operand:DI 1 "general_movsrc_operand" "r,JS,iF,m,rl,r,*b*k,T"))]
3517   "TARGET_SHMEDIA
3518    && (register_operand (operands[0], DImode)
3519        || register_operand (operands[1], DImode))"
3520   "@
3521         add     %1, r63, %0
3522         movi    %1, %0
3523         #
3524         ld%M1.q %m1, %0
3525         st%M0.q %m0, %1
3526         ptabs   %1, %0
3527         gettr   %1, %0
3528         pt      %1, %0"
3529   [(set_attr "type"   "move,move,*,load,store,ptabs,move,pt")
3530    (set_attr "length" "4,4,16,4,4,4,4,*")])
3531
3532 (define_split
3533   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3534         (match_operand:DI 1 "immediate_operand" "s"))]
3535   "TARGET_SHMEDIA && reload_completed
3536    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3537   [(set (match_dup 0) (match_dup 1))]
3538   "
3539 {
3540   rtx insn;
3541
3542   if (TARGET_SHMEDIA64)
3543     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3544   else
3545     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3546
3547   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3548                                         REG_NOTES (insn));
3549
3550   DONE;
3551 }")
3552
3553 (define_expand "movdi_const"
3554   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3555         (const:DI (sign_extend:DI
3556                    (truncate:HI
3557                     (ashiftrt:DI
3558                      (match_operand:DI 1 "immediate_operand" "s")
3559                      (const_int 48))))))
3560    (set (match_dup 0)
3561         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3562                 (zero_extend:DI
3563                  (truncate:HI
3564                   (const:DI
3565                    (sign_extend:DI
3566                     (truncate:HI
3567                      (ashiftrt:SI
3568                       (match_dup 1)
3569                       (const_int 32)))))))))
3570    (set (match_dup 0)
3571         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3572                 (zero_extend:DI
3573                  (truncate:HI
3574                   (const:DI
3575                    (sign_extend:DI
3576                     (truncate:HI
3577                      (ashiftrt:SI
3578                       (match_dup 1)
3579                       (const_int 16)))))))))
3580    (set (match_dup 0)
3581         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3582                 (zero_extend:DI
3583                  (truncate:HI
3584                   (const:DI
3585                    (sign_extend:DI
3586                     (truncate:HI
3587                      (match_dup 1))))))))]
3588   "TARGET_SHMEDIA64 && reload_completed
3589    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3590   "
3591 {
3592   if (GET_CODE (operands[1]) == LABEL_REF
3593       && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
3594     LABEL_NUSES (XEXP (operands[1], 0)) += 4;
3595   else if (GOTOFF_P (operands[1])
3596            && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == LABEL_REF
3597            && (GET_CODE (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0))
3598                == CODE_LABEL))
3599     LABEL_NUSES (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0)) += 4;
3600 }")
3601
3602 (define_expand "movdi_const_32bit"
3603   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3604         (const:DI (sign_extend:DI
3605                    (truncate:HI
3606                     (ashiftrt:DI
3607                      (match_operand:DI 1 "immediate_operand" "s")
3608                      (const_int 16))))))
3609    (set (match_dup 0)
3610         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3611                 (zero_extend:DI
3612                  (truncate:HI
3613                   (const:DI
3614                    (sign_extend:DI
3615                     (truncate:HI
3616                      (match_dup 1))))))))]
3617   "TARGET_SHMEDIA32 && reload_completed
3618    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3619   "
3620 {
3621   if (GET_CODE (operands[1]) == LABEL_REF
3622       && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
3623     LABEL_NUSES (XEXP (operands[1], 0)) += 2;
3624   else if (GOTOFF_P (operands[1])
3625            && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == LABEL_REF
3626            && (GET_CODE (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0))
3627                == CODE_LABEL))
3628     LABEL_NUSES (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0)) += 2;
3629 }")
3630
3631 (define_expand "movdi_const_16bit"
3632   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3633         (const:DI (sign_extend:DI
3634                    (truncate:HI
3635                     (match_operand:DI 1 "immediate_operand" "s")))))]
3636   "TARGET_SHMEDIA && flag_pic && reload_completed
3637    && GET_CODE (operands[1]) == SYMBOL_REF"
3638   "")
3639
3640 (define_split
3641   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3642         (match_operand:DI 1 "immediate_operand" "i"))]
3643   "TARGET_SHMEDIA && reload_completed
3644    && GET_CODE (operands[1]) == CONST_INT
3645    && ! CONST_OK_FOR_J (INTVAL (operands[1]))"
3646   [(set (match_dup 0) (match_dup 2))
3647    (match_dup 1)]
3648   "
3649 {
3650   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
3651   unsigned HOST_WIDE_INT low = val;
3652   unsigned HOST_WIDE_INT high = val;
3653   unsigned HOST_WIDE_INT sign;
3654   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
3655
3656   /* Sign-extend the 16 least-significant bits.  */
3657   low &= 0xffff;
3658   low ^= 0x8000;
3659   low -= 0x8000;
3660
3661   /* Arithmetic shift right the word by 16 bits.  */
3662   high >>= 16;
3663   sign = 1;
3664   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
3665   high ^= sign;
3666   high -= sign;
3667   do
3668     {
3669       /* If we can't generate the constant with a two-insn movi / shori
3670          sequence, try some other strategies.  */
3671       if (! CONST_OK_FOR_J (high))
3672         {
3673           /* Try constant load / left shift.  We know VAL != 0.  */
3674           val2 = val ^ (val-1);
3675           if (val2 > 0x1ffff)
3676             {
3677               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
3678
3679               if (CONST_OK_FOR_J (val >> trailing_zeroes)
3680                   || (! CONST_OK_FOR_J (high >> 16)
3681                       && CONST_OK_FOR_J (val >> (trailing_zeroes + 16))))
3682                 {
3683                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
3684                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
3685                                                    GEN_INT (trailing_zeroes));
3686                   break;
3687                 }
3688             }
3689           /* Try constant load / right shift.  */
3690           val2 = (val >> 15) + 1;
3691           if (val2 == (val2 & -val2))
3692             {
3693               int shift = 49 - exact_log2 (val2);
3694
3695               val2 = trunc_int_for_mode (val << shift, DImode);
3696               if (CONST_OK_FOR_J (val2))
3697                 {
3698                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
3699                                                    GEN_INT (shift));
3700                   break;
3701                 }
3702             }
3703           /* Try mperm.w .  */
3704           val2 = val & 0xffff;
3705           if ((val >> 16 & 0xffff) == val2
3706               && (val >> 32 & 0xffff) == val2
3707               && (val >> 48 & 0xffff) == val2)
3708             {
3709               val2 = (HOST_WIDE_INT) val >> 48;
3710               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
3711               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
3712               break;
3713             }
3714           /* Try movi / mshflo.l  */
3715           val2 = (HOST_WIDE_INT) val >> 32;
3716           if (val2 == trunc_int_for_mode (val, SImode))
3717             {
3718               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
3719                                              operands[0]);
3720               break;
3721             }
3722           /* Try movi / mshflo.l w/ r63.  */
3723           val2 = val + ((HOST_WIDE_INT) -1 << 32);
3724           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_J (val2))
3725             {
3726               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
3727                                              GEN_INT (0));
3728               break;
3729             }
3730         }
3731       val2 = high;
3732       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
3733     }
3734   while (0);
3735   operands[2] = GEN_INT (val2);
3736 }")
3737
3738 (define_split
3739   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3740         (match_operand:DI 1 "immediate_operand" "F"))]
3741   "TARGET_SHMEDIA && reload_completed
3742    && GET_CODE (operands[1]) == CONST_DOUBLE"
3743   [(set (match_dup 0) (match_dup 2))
3744   (set (match_dup 0)
3745        (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3746                (zero_extend:DI (truncate:HI (match_dup 1)))))]
3747   "
3748 {
3749   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
3750   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
3751   unsigned HOST_WIDE_INT val = low;
3752   unsigned HOST_WIDE_INT sign;
3753
3754   /* Sign-extend the 16 least-significant bits.  */
3755   val &= 0xffff;
3756   val ^= 0x8000;
3757   val -= 0x8000;
3758   operands[1] = GEN_INT (val);
3759
3760   /* Arithmetic shift right the double-word by 16 bits.  */
3761   low >>= 16;
3762   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
3763   high >>= 16;
3764   sign = 1;
3765   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
3766   high ^= sign;
3767   high -= sign;
3768
3769   /* This will only be true if high is a sign-extension of low, i.e.,
3770      it must be either 0 or (unsigned)-1, and be zero iff the
3771      most-significant bit of low is set.  */
3772   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
3773     operands[2] = GEN_INT (low);
3774   else
3775     operands[2] = immed_double_const (low, high, DImode);
3776 }")
3777
3778 (define_insn "shori_media"
3779   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
3780         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
3781                            (const_int 16))
3782                 (zero_extend:DI
3783                  (truncate:HI
3784                   (match_operand:DI 2 "immediate_operand" "JS,nF")))))]
3785   "TARGET_SHMEDIA"
3786   "@
3787         shori   %u2, %0
3788         #")
3789
3790 (define_expand "movdi"
3791   [(set (match_operand:DI 0 "general_movdst_operand" "")
3792         (match_operand:DI 1 "general_movsrc_operand" ""))]
3793   ""
3794   "{ if (prepare_move_operands (operands, DImode)) DONE; }")
3795
3796 (define_insn "movdf_media"
3797   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
3798         (match_operand:DF 1 "general_movsrc_operand" "f,r,f,r,F,m,f,m,r"))]
3799   "TARGET_SHMEDIA_FPU
3800    && (register_operand (operands[0], DFmode)
3801        || register_operand (operands[1], DFmode))"
3802   "@
3803         fmov.d  %1, %0
3804         fmov.qd %1, %0
3805         fmov.dq %1, %0
3806         add     %1, r63, %0
3807         #
3808         fld%M1.d        %m1, %0
3809         fst%M0.d        %m0, %1
3810         ld%M1.q %m1, %0
3811         st%M0.q %m0, %1"
3812   [(set_attr "type" "move,move,move,move,*,load,store,load,store")])
3813
3814 (define_insn "movdf_media_nofpu"
3815   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
3816         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,r"))]
3817   "TARGET_SHMEDIA
3818    && (register_operand (operands[0], DFmode)
3819        || register_operand (operands[1], DFmode))"
3820   "@
3821         add     %1, r63, %0
3822         #
3823         ld%M1.q %m1, %0
3824         st%M0.q %m0, %1"
3825   [(set_attr "type" "move,*,load,store")])
3826
3827 (define_split
3828   [(set (match_operand:DF 0 "arith_reg_operand" "")
3829         (match_operand:DF 1 "immediate_operand" ""))]
3830   "TARGET_SHMEDIA && reload_completed"
3831   [(set (match_dup 3) (match_dup 2))]
3832   "
3833 {
3834   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
3835   long values[2];
3836   REAL_VALUE_TYPE value;
3837
3838   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
3839   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
3840
3841   if (HOST_BITS_PER_WIDE_INT >= 64)
3842     operands[2] = immed_double_const ((unsigned long) values[endian]
3843                                       | ((HOST_WIDE_INT) values[1 - endian]
3844                                          << 32), 0, DImode);
3845   else if (HOST_BITS_PER_WIDE_INT == 32)
3846     operands[2] = immed_double_const (values[endian], values[1 - endian],
3847                                       DImode);
3848   else
3849     abort ();
3850
3851   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
3852 }")
3853
3854 ;; ??? This should be a define expand.
3855
3856 (define_insn "movdf_k"
3857   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
3858         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
3859   "TARGET_SH1
3860    && (! TARGET_SH4 || reload_completed
3861        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
3862        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
3863        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
3864    && (arith_reg_operand (operands[0], DFmode)
3865        || arith_reg_operand (operands[1], DFmode))"
3866   "* return output_movedouble (insn, operands, DFmode);"
3867   [(set_attr "length" "4")
3868    (set_attr "type" "move,pcload,load,store")])
3869
3870 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
3871 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
3872 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
3873 ;; the d/m/c/X alternative, which is split later into single-precision
3874 ;; instructions.  And when not optimizing, no splits are done before fixing
3875 ;; up pcloads, so we need usable length information for that.
3876 (define_insn "movdf_i4"
3877   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
3878         (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
3879    (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
3880    (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
3881   "TARGET_SH4
3882    && (arith_reg_operand (operands[0], DFmode)
3883        || arith_reg_operand (operands[1], DFmode))"
3884   "@
3885         fmov    %1,%0
3886         #
3887         #
3888         fmov.d  %1,%0
3889         fmov.d  %1,%0
3890         #
3891         #
3892         #
3893         #
3894         #"
3895   [(set_attr_alternative "length"
3896      [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
3897       (const_int 4)
3898       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
3899       (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
3900       (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
3901       (const_int 4)
3902       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
3903       ;; We can't use 4-byte push/pop on SHcompact, so we have to
3904       ;; increment or decrement r15 explicitly.
3905       (if_then_else
3906        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
3907        (const_int 10) (const_int 8))
3908       (if_then_else
3909        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
3910        (const_int 10) (const_int 8))])
3911    (set_attr "type" "fmove,move,pcload,load,store,pcload,load,store,load,load")
3912    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
3913                                            (const_string "double")
3914                                            (const_string "none")))])
3915
3916 ;; Moving DFmode between fp/general registers through memory
3917 ;; (the top of the stack) is faster than moving through fpul even for
3918 ;; little endian.  Because the type of an instruction is important for its
3919 ;; scheduling,  it is beneficial to split these operations, rather than
3920 ;; emitting them in one single chunk, even if this will expose a stack
3921 ;; use that will prevent scheduling of other stack accesses beyond this
3922 ;; instruction.
3923 (define_split
3924   [(set (match_operand:DF 0 "register_operand" "")
3925         (match_operand:DF 1 "register_operand" ""))
3926    (use (match_operand:PSI 2 "fpscr_operand" "c"))
3927    (clobber (match_scratch:SI 3 "=X"))]
3928   "TARGET_SH4 && reload_completed
3929    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
3930   [(const_int 0)]
3931   "
3932 {
3933   rtx insn, tos;
3934
3935   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
3936     {
3937       emit_move_insn (stack_pointer_rtx,
3938                       plus_constant (stack_pointer_rtx, -8));
3939       tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
3940     }
3941   else
3942     tos = gen_rtx (MEM, DFmode, gen_rtx (PRE_DEC, Pmode, stack_pointer_rtx));
3943   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
3944   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
3945     REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
3946   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
3947     tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
3948   else
3949     tos = gen_rtx (MEM, DFmode, gen_rtx (POST_INC, Pmode, stack_pointer_rtx));
3950   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
3951   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
3952     emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
3953   else
3954     REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
3955   DONE;
3956 }")
3957
3958 ;; local-alloc sometimes allocates scratch registers even when not required,
3959 ;; so we must be prepared to handle these.
3960
3961 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
3962 (define_split
3963   [(set (match_operand:DF 0 "general_movdst_operand" "")
3964         (match_operand:DF 1 "general_movsrc_operand"  ""))
3965    (use (match_operand:PSI 2 "fpscr_operand" "c"))
3966    (clobber (match_scratch:SI 3 "X"))]
3967   "TARGET_SH4
3968    && reload_completed
3969    && true_regnum (operands[0]) < 16
3970    && true_regnum (operands[1]) < 16"
3971   [(set (match_dup 0) (match_dup 1))]
3972   "
3973 {
3974   /* If this was a reg <-> mem operation with base + index reg addressing,
3975      we have to handle this in a special way.  */
3976   rtx mem = operands[0];
3977   int store_p = 1;
3978   if (! memory_operand (mem, DFmode))
3979     {
3980       mem = operands[1];
3981       store_p = 0;
3982     }
3983   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
3984     mem = SUBREG_REG (mem);
3985   if (GET_CODE (mem) == MEM)
3986     {
3987       rtx addr = XEXP (mem, 0);
3988       if (GET_CODE (addr) == PLUS
3989           && GET_CODE (XEXP (addr, 0)) == REG
3990           && GET_CODE (XEXP (addr, 1)) == REG)
3991         {
3992           int offset;
3993           rtx reg0 = gen_rtx (REG, Pmode, 0);
3994           rtx regop = operands[store_p], word0 ,word1;
3995
3996           if (GET_CODE (regop) == SUBREG)
3997             alter_subreg (&regop);
3998           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
3999             offset = 2;
4000           else
4001             offset = 4;
4002           mem = copy_rtx (mem);
4003           PUT_MODE (mem, SImode);
4004           word0 = gen_rtx (SUBREG, SImode, regop, 0);
4005           alter_subreg (&word0);
4006           word1 = gen_rtx (SUBREG, SImode, regop, 4);
4007           alter_subreg (&word1);
4008           if (store_p || ! refers_to_regno_p (REGNO (word0),
4009                                               REGNO (word0) + 1, addr, 0))
4010             {
4011               emit_insn (store_p
4012                          ? gen_movsi_ie (mem, word0)
4013                          : gen_movsi_ie (word0, mem));
4014               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4015               mem = copy_rtx (mem);
4016               emit_insn (store_p
4017                          ? gen_movsi_ie (mem, word1)
4018                          : gen_movsi_ie (word1, mem));
4019               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4020             }
4021           else
4022             {
4023               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4024               emit_insn (gen_movsi_ie (word1, mem));
4025               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4026               mem = copy_rtx (mem);
4027               emit_insn (gen_movsi_ie (word0, mem));
4028             }
4029           DONE;
4030         }
4031     }
4032 }")
4033
4034 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4035 (define_split
4036   [(set (match_operand:DF 0 "register_operand" "")
4037         (match_operand:DF 1 "memory_operand"  ""))
4038    (use (match_operand:PSI 2 "fpscr_operand" "c"))
4039    (clobber (reg:SI R0_REG))]
4040   "TARGET_SH4 && reload_completed"
4041   [(parallel [(set (match_dup 0) (match_dup 1))
4042               (use (match_dup 2))
4043               (clobber (scratch:SI))])]
4044   "")
4045
4046 (define_expand "reload_indf"
4047   [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4048                    (match_operand:DF 1 "immediate_operand" "FQ"))
4049               (use (reg:PSI FPSCR_REG))
4050               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4051   "TARGET_SH1"
4052   "")
4053
4054 (define_expand "reload_outdf"
4055   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4056                    (match_operand:DF 1 "register_operand" "af,r"))
4057               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
4058   "TARGET_SH1"
4059   "")
4060
4061 ;; Simplify no-op moves.
4062 (define_split
4063   [(set (match_operand:SF 0 "register_operand" "")
4064         (match_operand:SF 1 "register_operand" ""))
4065    (use (match_operand:PSI 2 "fpscr_operand" ""))
4066    (clobber (match_scratch:SI 3 "X"))]
4067   "TARGET_SH3E && reload_completed
4068    && true_regnum (operands[0]) == true_regnum (operands[1])"
4069   [(set (match_dup 0) (match_dup 0))]
4070   "")
4071
4072 ;; fmovd substitute post-reload splits
4073 (define_split
4074   [(set (match_operand:DF 0 "register_operand" "")
4075         (match_operand:DF 1 "register_operand" ""))
4076    (use (match_operand:PSI 2 "fpscr_operand" "c"))
4077    (clobber (match_scratch:SI 3 "X"))]
4078   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4079    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4080    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4081   [(const_int 0)]
4082   "
4083 {
4084   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4085   emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst),
4086                            gen_rtx (REG, SFmode, src), operands[2]));
4087   emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst + 1),
4088                            gen_rtx (REG, SFmode, src + 1), operands[2]));
4089   DONE;
4090 }")
4091
4092 (define_split
4093   [(set (match_operand:DF 0 "register_operand" "")
4094         (mem:DF (match_operand:SI 1 "register_operand" "")))
4095    (use (match_operand:PSI 2 "fpscr_operand" "c"))
4096    (clobber (match_scratch:SI 3 "X"))]
4097   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4098    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4099    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4100   [(const_int 0)]
4101   "
4102 {
4103   int regno = true_regnum (operands[0]);
4104   rtx insn;
4105   rtx mem2 = gen_rtx (MEM, SFmode, gen_rtx (POST_INC, Pmode, operands[1]));
4106
4107   insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4108                                            regno + !! TARGET_LITTLE_ENDIAN),
4109                                   mem2, operands[2]));
4110   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[1], NULL_RTX);
4111   insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4112                                            regno + ! TARGET_LITTLE_ENDIAN),
4113                                   gen_rtx (MEM, SFmode, operands[1]),
4114                                   operands[2]));
4115   DONE;
4116 }")
4117
4118 (define_split
4119   [(set (match_operand:DF 0 "register_operand" "")
4120         (match_operand:DF 1 "memory_operand" ""))
4121    (use (match_operand:PSI 2 "fpscr_operand" "c"))
4122    (clobber (match_scratch:SI 3 "X"))]
4123   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4124    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
4125   [(const_int 0)]
4126   "
4127 {
4128   int regno = true_regnum (operands[0]);
4129   rtx addr, insn, adjust = NULL_RTX;
4130   rtx mem2 = copy_rtx (operands[1]);
4131   rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4132   rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4133
4134   PUT_MODE (mem2, SFmode);
4135   operands[1] = copy_rtx (mem2);
4136   addr = XEXP (mem2, 0);
4137   if (GET_CODE (addr) != POST_INC)
4138     {
4139       /* If we have to modify the stack pointer, the value that we have
4140          read with post-increment might be modified by an interrupt,
4141          so write it back.  */
4142       if (REGNO (addr) == STACK_POINTER_REGNUM)
4143         adjust = gen_push_e (reg0);
4144       else
4145         adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4146       XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4147     }
4148   addr = XEXP (addr, 0);
4149   insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4150   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4151   insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4152   if (adjust)
4153     emit_insn (adjust);
4154   else
4155     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4156   DONE;
4157 }")
4158
4159 (define_split
4160   [(set (match_operand:DF 0 "memory_operand" "")
4161         (match_operand:DF 1 "register_operand" ""))
4162    (use (match_operand:PSI 2 "fpscr_operand" "c"))
4163    (clobber (match_scratch:SI 3 "X"))]
4164   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4165    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4166   [(const_int 0)]
4167   "
4168 {
4169   int regno = true_regnum (operands[1]);
4170   rtx insn, addr, adjust = NULL_RTX;
4171
4172   operands[0] = copy_rtx (operands[0]);
4173   PUT_MODE (operands[0], SFmode);
4174   insn = emit_insn (gen_movsf_ie (operands[0],
4175                                   gen_rtx (REG, SFmode,
4176                                            regno + ! TARGET_LITTLE_ENDIAN),
4177                                   operands[2]));
4178   operands[0] = copy_rtx (operands[0]);
4179   addr = XEXP (operands[0], 0);
4180   if (GET_CODE (addr) != PRE_DEC)
4181     {
4182       adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4183       emit_insn_before (adjust, insn);
4184       XEXP (operands[0], 0) = addr = gen_rtx (PRE_DEC, SImode, addr);
4185     }
4186   addr = XEXP (addr, 0);
4187   if (! adjust)
4188     REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4189   insn = emit_insn (gen_movsf_ie (operands[0],
4190                                   gen_rtx (REG, SFmode,
4191                                            regno + !! TARGET_LITTLE_ENDIAN),
4192                                   operands[2]));
4193   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4194   DONE;
4195 }")
4196
4197 ;; If the output is a register and the input is memory or a register, we have
4198 ;; to be careful and see which word needs to be loaded first.  
4199
4200 (define_split
4201   [(set (match_operand:DF 0 "general_movdst_operand" "")
4202         (match_operand:DF 1 "general_movsrc_operand" ""))]
4203   "TARGET_SH1 && reload_completed"
4204   [(set (match_dup 2) (match_dup 3))
4205    (set (match_dup 4) (match_dup 5))]
4206   "
4207 {
4208   int regno;
4209
4210   if ((GET_CODE (operands[0]) == MEM
4211        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4212       || (GET_CODE (operands[1]) == MEM
4213           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4214     FAIL;
4215
4216   if (GET_CODE (operands[0]) == REG)
4217     regno = REGNO (operands[0]);
4218   else if (GET_CODE (operands[0]) == SUBREG)
4219     regno = subreg_regno (operands[0]);
4220   else if (GET_CODE (operands[0]) == MEM)
4221     regno = -1;
4222   else
4223     abort ();
4224
4225   if (regno == -1
4226       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
4227     {
4228       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4229       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4230       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4231       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4232     }
4233   else
4234     {
4235       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4236       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4237       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4238       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4239     }
4240
4241   if (operands[2] == 0 || operands[3] == 0
4242       || operands[4] == 0 || operands[5] == 0)
4243     FAIL;
4244 }")
4245
4246 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4247 ;; used only once, let combine add in the index again.
4248
4249 (define_split
4250   [(set (match_operand:SI 0 "register_operand" "")
4251         (match_operand:SI 1 "" ""))
4252    (clobber (match_operand 2 "register_operand" ""))]
4253   "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4254   [(use (reg:SI R0_REG))]
4255   "
4256 {
4257   rtx addr, reg, const_int;
4258
4259   if (GET_CODE (operands[1]) != MEM)
4260     FAIL;
4261   addr = XEXP (operands[1], 0);
4262   if (GET_CODE (addr) != PLUS)
4263     FAIL;
4264   reg = XEXP (addr, 0);
4265   const_int = XEXP (addr, 1);
4266   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4267          && GET_CODE (const_int) == CONST_INT))
4268     FAIL;
4269   emit_move_insn (operands[2], const_int);
4270   emit_move_insn (operands[0],
4271                   change_address (operands[1], VOIDmode,
4272                                   gen_rtx_PLUS (SImode, reg, operands[2])));
4273   DONE;
4274 }")
4275
4276 (define_split
4277   [(set (match_operand:SI 1 "" "")
4278         (match_operand:SI 0 "register_operand" ""))
4279    (clobber (match_operand 2 "register_operand" ""))]
4280   "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4281   [(use (reg:SI R0_REG))]
4282   "
4283 {
4284   rtx addr, reg, const_int;
4285
4286   if (GET_CODE (operands[1]) != MEM)
4287     FAIL;
4288   addr = XEXP (operands[1], 0);
4289   if (GET_CODE (addr) != PLUS)
4290     FAIL;
4291   reg = XEXP (addr, 0);
4292   const_int = XEXP (addr, 1);
4293   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4294          && GET_CODE (const_int) == CONST_INT))
4295     FAIL;
4296   emit_move_insn (operands[2], const_int);
4297   emit_move_insn (change_address (operands[1], VOIDmode,
4298                                   gen_rtx_PLUS (SImode, reg, operands[2])),
4299                   operands[0]);
4300   DONE;
4301 }")
4302
4303 (define_expand "movdf"
4304   [(set (match_operand:DF 0 "general_movdst_operand" "")
4305         (match_operand:DF 1 "general_movsrc_operand" ""))]
4306   ""
4307   "
4308 {
4309   if (prepare_move_operands (operands, DFmode)) DONE;
4310   if (TARGET_SHMEDIA)
4311     {
4312       if (TARGET_SHMEDIA_FPU)
4313         emit_insn (gen_movdf_media (operands[0], operands[1]));
4314       else
4315         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4316       DONE;
4317     }
4318   if (TARGET_SH4)
4319     {
4320       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4321       DONE;
4322     }
4323 }")
4324
4325 (define_insn "movv2sf_i"
4326   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4327         (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4328   "TARGET_SHMEDIA_FPU
4329    && (fp_arith_reg_operand (operands[0], V2SFmode)
4330        || fp_arith_reg_operand (operands[1], V2SFmode))"
4331   "@
4332         #
4333         fld%M1.p        %m1, %0
4334         fst%M0.p        %m0, %1")
4335
4336 (define_split
4337   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f")
4338         (match_operand:V2SF 1 "nonimmediate_operand" "f"))]
4339   "TARGET_SHMEDIA_FPU && reload_completed
4340    && fp_arith_reg_operand (operands[0], V2SFmode)
4341    && fp_arith_reg_operand (operands[1], V2SFmode)"
4342   [(set (subreg:DF (match_dup 0) 0) (subreg:DF (match_dup 1) 0))])
4343
4344 (define_expand "movv2sf"
4345   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4346         (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4347   "TARGET_SHMEDIA_FPU"
4348   "
4349 {
4350   if (prepare_move_operands (operands, V2SFmode))
4351     DONE;
4352 }")
4353
4354 (define_insn_and_split "*movv4sf_i"
4355   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4356         (match_operand:V4SF 1 "nonimmediate_operand" "f,m,f"))]
4357   "TARGET_SHMEDIA_FPU"
4358   "#"
4359   "&& reload_completed"
4360   [(const_int 0)]
4361   "
4362 {
4363   int i;
4364
4365   for (i = 0; i < 4/2; i++)
4366     {
4367       rtx x, y;
4368
4369       if (GET_CODE (operands[0]) == MEM)
4370         x = gen_rtx_MEM (V2SFmode,
4371                          plus_constant (XEXP (operands[0], 0),
4372                                         i * GET_MODE_SIZE (V2SFmode)));
4373       else
4374         {
4375           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 2);
4376           alter_subreg (&x);
4377         }
4378
4379       if (GET_CODE (operands[1]) == MEM)
4380         y = gen_rtx_MEM (V2SFmode,
4381                          plus_constant (XEXP (operands[1], 0),
4382                                         i * GET_MODE_SIZE (V2SFmode)));
4383       else
4384         {
4385           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 2);
4386           alter_subreg (&y);
4387         }
4388
4389       emit_insn (gen_movv2sf_i (x, y));
4390     }
4391
4392   DONE;
4393 }"
4394   [(set_attr "length" "8")])
4395   
4396 (define_expand "movv4sf"
4397   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4398         (match_operand:V4SF 1 "nonimmediate_operand" "f,m,f"))]
4399   "TARGET_SHMEDIA_FPU"
4400   "
4401 {
4402   if (prepare_move_operands (operands, V4SFmode))
4403     DONE;
4404 }")
4405
4406 (define_insn_and_split "*movv16sf_i"
4407   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4408         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4409   "TARGET_SHMEDIA_FPU"
4410   "#"
4411   "&& reload_completed"
4412   [(const_int 0)]
4413   "
4414 {
4415   int i;
4416
4417   for (i = 0; i < 16/2; i++)
4418     {
4419       rtx x,y;
4420
4421       if (GET_CODE (operands[0]) == MEM)
4422         x = gen_rtx_MEM (V2SFmode,
4423                          plus_constant (XEXP (operands[0], 0),
4424                                         i * GET_MODE_SIZE (V2SFmode)));
4425       else
4426         {
4427           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 2);
4428           alter_subreg (&x);
4429         }
4430
4431       if (GET_CODE (operands[1]) == MEM)
4432         y = gen_rtx_MEM (V2SFmode,
4433                          plus_constant (XEXP (operands[1], 0),
4434                                         i * GET_MODE_SIZE (V2SFmode)));
4435       else
4436         {
4437           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 2);
4438           alter_subreg (&y);
4439         }
4440
4441       emit_insn (gen_movv2sf_i (x, y));
4442     }
4443
4444   DONE;
4445 }"
4446   [(set_attr "length" "32")])
4447   
4448 (define_expand "movv16sf"
4449   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4450         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4451   "TARGET_SHMEDIA_FPU"
4452   "
4453 {
4454   if (prepare_move_operands (operands, V16SFmode))
4455     DONE;
4456 }")
4457
4458 (define_insn "movsf_media"
4459   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4460         (match_operand:SF 1 "general_movsrc_operand" "f,r,f,r,F,m,f,m,r"))]
4461   "TARGET_SHMEDIA_FPU
4462    && (register_operand (operands[0], SFmode)
4463        || register_operand (operands[1], SFmode))"
4464   "@
4465         fmov.s  %1, %0
4466         fmov.ls %1, %0
4467         fmov.sl %1, %0
4468         add     %1, r63, %0
4469         #
4470         fld%M1.s        %m1, %0
4471         fst%M0.s        %m0, %1
4472         ld%M1.l %m1, %0
4473         st%M0.l %m0, %1"
4474   [(set_attr "type" "move,move,move,move,*,load,store,load,store")])
4475
4476 (define_insn "movsf_media_nofpu"
4477   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
4478         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,r"))]
4479   "TARGET_SHMEDIA
4480    && (register_operand (operands[0], SFmode)
4481        || register_operand (operands[1], SFmode))"
4482   "@
4483         add     %1, r63, %0
4484         #
4485         ld%M1.l %m1, %0
4486         st%M0.l %m0, %1"
4487   [(set_attr "type" "move,*,load,store")])
4488
4489 (define_split
4490   [(set (match_operand:SF 0 "arith_reg_operand" "")
4491         (match_operand:SF 1 "immediate_operand" ""))]
4492   "TARGET_SHMEDIA && reload_completed"
4493   [(set (match_dup 3) (match_dup 2))]
4494   "
4495 {
4496   long values;
4497   REAL_VALUE_TYPE value;
4498
4499   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4500   REAL_VALUE_TO_TARGET_SINGLE (value, values);
4501   operands[2] = GEN_INT (values);
4502   
4503   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4504 }")
4505
4506 (define_insn "movsf_i"
4507   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
4508         (match_operand:SF 1 "general_movsrc_operand"  "r,I,FQ,mr,r,r,l"))]
4509   "TARGET_SH1
4510    && (! TARGET_SH3E
4511        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4512        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4513        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4514    && (arith_reg_operand (operands[0], SFmode)
4515        || arith_reg_operand (operands[1], SFmode))"
4516   "@
4517         mov     %1,%0
4518         mov     %1,%0
4519         mov.l   %1,%0
4520         mov.l   %1,%0
4521         mov.l   %1,%0
4522         lds     %1,%0
4523         sts     %1,%0"
4524   [(set_attr "type" "move,move,pcload,load,store,move,move")])
4525
4526 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4527 ;; update_flow_info would not know where to put REG_EQUAL notes
4528 ;; when the destination changes mode.
4529 (define_insn "movsf_ie"
4530   [(set (match_operand:SF 0 "general_movdst_operand"
4531          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
4532         (match_operand:SF 1 "general_movsrc_operand"
4533           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4534    (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c"))
4535    (clobber (match_scratch:SI 3 "=X,X,X,X,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
4536
4537   "TARGET_SH3E
4538    && (arith_reg_operand (operands[0], SFmode)
4539        || arith_reg_operand (operands[1], SFmode)
4540        || arith_reg_operand (operands[3], SImode)
4541        || (fpul_operand (operands[0], SFmode)
4542            && memory_operand (operands[1], SFmode)
4543            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4544        || (fpul_operand (operands[1], SFmode)
4545            && memory_operand (operands[0], SFmode)
4546            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
4547   "@
4548         fmov    %1,%0
4549         mov     %1,%0
4550         fldi0   %0
4551         fldi1   %0
4552         #
4553         fmov.s  %1,%0
4554         fmov.s  %1,%0
4555         mov.l   %1,%0
4556         mov.l   %1,%0
4557         mov.l   %1,%0
4558         fsts    fpul,%0
4559         flds    %1,fpul
4560         lds.l   %1,%0
4561         #
4562         sts     %1,%0
4563         lds     %1,%0
4564         sts.l   %1,%0
4565         lds.l   %1,%0
4566         ! move optimized away"
4567   [(set_attr "type" "fmove,move,fmove,fmove,pcload,load,store,pcload,load,store,fmove,fmove,load,*,gp_fpul,gp_fpul,store,load,nil")
4568    (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,4,2,2,2,2,0")
4569    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4570                                            (const_string "single")
4571                                            (const_string "none")))])
4572
4573 (define_split
4574   [(set (match_operand:SF 0 "register_operand" "")
4575         (match_operand:SF 1 "register_operand" ""))
4576    (use (match_operand:PSI 2 "fpscr_operand" "c"))
4577    (clobber (reg:SI FPUL_REG))]
4578   "TARGET_SH1"
4579   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
4580               (use (match_dup 2))
4581               (clobber (scratch:SI))])
4582    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
4583               (use (match_dup 2))
4584               (clobber (scratch:SI))])]
4585   "")
4586
4587 (define_expand "movsf"
4588   [(set (match_operand:SF 0 "general_movdst_operand" "")
4589         (match_operand:SF 1 "general_movsrc_operand" ""))]
4590   ""
4591   "
4592 {
4593   if (prepare_move_operands (operands, SFmode))
4594     DONE;
4595   if (TARGET_SHMEDIA)
4596     {
4597       if (TARGET_SHMEDIA_FPU)
4598         emit_insn (gen_movsf_media (operands[0], operands[1]));
4599       else
4600         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
4601       DONE;
4602     }
4603   if (TARGET_SH3E)
4604     {
4605       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
4606       DONE;
4607     }
4608 }")
4609
4610 (define_insn "mov_nop"
4611   [(set (match_operand 0 "register_operand" "") (match_dup 0))]
4612   "TARGET_SH3E"
4613   ""
4614   [(set_attr "length" "0")
4615    (set_attr "type" "nil")])
4616
4617 (define_expand "reload_insf"
4618   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
4619                    (match_operand:SF 1 "immediate_operand" "FQ"))
4620               (use (reg:PSI FPSCR_REG))
4621               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4622   "TARGET_SH1"
4623   "")
4624
4625 (define_expand "reload_insi"
4626   [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
4627                    (match_operand:SF 1 "immediate_operand" "FQ"))
4628               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4629   "TARGET_SH1"
4630   "")
4631
4632 (define_insn "*movsi_y"
4633   [(set (match_operand:SI 0 "register_operand" "=y,y")
4634         (match_operand:SI 1 "immediate_operand" "Qi,I"))
4635    (clobber (match_scratch:SI 2 "=&z,r"))]
4636   "TARGET_SH3E
4637    && (reload_in_progress || reload_completed)"
4638   "#"
4639   [(set_attr "length" "4")
4640    (set_attr "type" "pcload,move")])
4641
4642 (define_split
4643   [(set (match_operand:SI 0 "register_operand" "")
4644         (match_operand:SI 1 "immediate_operand" ""))
4645    (clobber (match_operand:SI 2 "register_operand" ""))]
4646   "TARGET_SH1"
4647   [(set (match_dup 2) (match_dup 1))
4648    (set (match_dup 0) (match_dup 2))]
4649   "")
4650
4651 (define_split
4652   [(set (match_operand:SI 0 "register_operand" "")
4653         (match_operand:SI 1 "memory_operand" ""))
4654    (clobber (reg:SI R0_REG))]
4655   "TARGET_SH1"
4656   [(set (match_dup 0) (match_dup 1))]
4657   "")
4658 \f
4659 ;; ------------------------------------------------------------------------
4660 ;; Define the real conditional branch instructions.
4661 ;; ------------------------------------------------------------------------
4662
4663 (define_insn "branch_true"
4664   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
4665                            (label_ref (match_operand 0 "" ""))
4666                            (pc)))]
4667   "TARGET_SH1"
4668   "* return output_branch (1, insn, operands);"
4669   [(set_attr "type" "cbranch")])
4670
4671 (define_insn "branch_false"
4672   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
4673                            (label_ref (match_operand 0 "" ""))
4674                            (pc)))]
4675   "TARGET_SH1"
4676   "* return output_branch (0, insn, operands);"
4677   [(set_attr "type" "cbranch")])
4678
4679 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
4680 ;; which destination is too far away.
4681 ;; The const_int_operand is distinct for each branch target; it avoids
4682 ;; unwanted matches with redundant_insn.
4683 (define_insn "block_branch_redirect"
4684   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
4685   "TARGET_SH1"
4686   ""
4687   [(set_attr "length" "0")])
4688
4689 ;; This one has the additional purpose to record a possible scratch register
4690 ;; for the following branch.
4691 (define_insn "indirect_jump_scratch"
4692   [(set (match_operand 0 "register_operand" "=r")
4693         (unspec [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))]
4694   "TARGET_SH1"
4695   ""
4696   [(set_attr "length" "0")])
4697 \f
4698 ;; Conditional branch insns
4699
4700 (define_expand "beq_media"
4701   [(set (pc)
4702         (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
4703                           (match_operand:DI 2 "arith_operand" "r,O"))
4704                       (label_ref:DI (match_operand 0 "" ""))
4705                       (pc)))]
4706   "TARGET_SHMEDIA"
4707   "")
4708
4709 (define_insn "beq_media_i"
4710   [(set (pc)
4711         (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
4712                           (match_operand:DI 2 "arith_operand" "r,O"))
4713                       (match_operand:DI 0 "target_operand" "b,b")
4714                       (pc)))]
4715   "TARGET_SHMEDIA"
4716   "@
4717         beq     %1, %2, %0
4718         beqi    %1, %2, %0")
4719
4720 (define_expand "bne_media"
4721   [(set (pc)
4722         (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
4723                           (match_operand:DI 2 "arith_operand" "r,O"))
4724                       (label_ref:DI (match_operand 0 "" ""))
4725                       (pc)))]
4726   "TARGET_SHMEDIA"
4727   "")
4728
4729 (define_insn "bne_media_i"
4730   [(set (pc)
4731         (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
4732                           (match_operand:DI 2 "arith_operand" "r,O"))
4733                       (match_operand:DI 0 "target_operand" "b,b")
4734                       (pc)))]
4735   "TARGET_SHMEDIA"
4736   "@
4737         bne     %1, %2, %0
4738         bnei    %1, %2, %0")
4739
4740 (define_expand "bgt_media"
4741   [(set (pc)
4742         (if_then_else (gt (match_operand:DI 1 "arith_reg_operand" "r")
4743                           (match_operand:DI 2 "arith_reg_operand" "r"))
4744                       (label_ref:DI (match_operand 0 "" ""))
4745                       (pc)))]
4746   "TARGET_SHMEDIA"
4747   "")
4748
4749 (define_insn "bgt_media_i"
4750   [(set (pc)
4751         (if_then_else (gt (match_operand:DI 1 "arith_reg_operand" "r")
4752                           (match_operand:DI 2 "arith_reg_operand" "r"))
4753                       (match_operand:DI 0 "target_operand" "b")
4754                       (pc)))]
4755   "TARGET_SHMEDIA"
4756   "bgt  %1, %2, %0")
4757
4758 (define_expand "bge_media"
4759   [(set (pc)
4760         (if_then_else (ge (match_operand:DI 1 "arith_reg_operand" "r")
4761                           (match_operand:DI 2 "arith_reg_operand" "r"))
4762                       (label_ref:DI (match_operand 0 "" ""))
4763                       (pc)))]
4764   "TARGET_SHMEDIA"
4765   "")
4766
4767 (define_insn "bge_media_i"
4768   [(set (pc)
4769         (if_then_else (ge (match_operand:DI 1 "arith_reg_operand" "r")
4770                           (match_operand:DI 2 "arith_reg_operand" "r"))
4771                       (match_operand:DI 0 "target_operand" "b")
4772                       (pc)))]
4773   "TARGET_SHMEDIA"
4774   "bge  %1, %2, %0")
4775
4776 (define_expand "bgtu_media"
4777   [(set (pc)
4778         (if_then_else (gtu (match_operand:DI 1 "arith_reg_operand" "r")
4779                            (match_operand:DI 2 "arith_reg_operand" "r"))
4780                       (label_ref:DI (match_operand 0 "" ""))
4781                       (pc)))]
4782   "TARGET_SHMEDIA"
4783   "")
4784
4785 (define_insn "bgtu_media_i"
4786   [(set (pc)
4787         (if_then_else (gtu (match_operand:DI 1 "arith_reg_operand" "r")
4788                            (match_operand:DI 2 "arith_reg_operand" "r"))
4789                       (match_operand:DI 0 "target_operand" "b")
4790                       (pc)))]
4791   "TARGET_SHMEDIA"
4792   "bgtu %1, %2, %0")
4793
4794 (define_expand "bgeu_media"
4795   [(set (pc)
4796         (if_then_else (geu (match_operand:DI 1 "arith_reg_operand" "r")
4797                            (match_operand:DI 2 "arith_reg_operand" "r"))
4798                       (label_ref:DI (match_operand 0 "" ""))
4799                       (pc)))]
4800   "TARGET_SHMEDIA"
4801   "")
4802
4803 (define_insn "bgeu_media_i"
4804   [(set (pc)
4805         (if_then_else (geu (match_operand:DI 1 "arith_reg_operand" "r")
4806                            (match_operand:DI 2 "arith_reg_operand" "r"))
4807                       (match_operand:DI 0 "target_operand" "b")
4808                       (pc)))]
4809   "TARGET_SHMEDIA"
4810   "bgeu %1, %2, %0")
4811
4812 ;; These are only needed to make invert_jump() happy.
4813 (define_insn "*ble_media_i"
4814   [(set (pc)
4815         (if_then_else (le (match_operand:DI 1 "arith_reg_operand" "r")
4816                           (match_operand:DI 2 "arith_reg_operand" "r"))
4817                       (match_operand:DI 0 "target_operand" "b")
4818                       (pc)))]
4819   "TARGET_SHMEDIA"
4820   "bge  %2, %1, %0")
4821
4822 (define_insn "*blt_media_i"
4823   [(set (pc)
4824         (if_then_else (lt (match_operand:DI 1 "arith_reg_operand" "r")
4825                           (match_operand:DI 2 "arith_reg_operand" "r"))
4826                       (match_operand:DI 0 "target_operand" "b")
4827                       (pc)))]
4828   "TARGET_SHMEDIA"
4829   "bgt  %2, %1, %0")
4830
4831 (define_insn "*bleu_media_i"
4832   [(set (pc)
4833         (if_then_else (leu (match_operand:DI 1 "arith_reg_operand" "r")
4834                            (match_operand:DI 2 "arith_reg_operand" "r"))
4835                       (match_operand:DI 0 "target_operand" "b")
4836                       (pc)))]
4837   "TARGET_SHMEDIA"
4838   "bgeu %2, %1, %0")
4839
4840 (define_insn "*bltu_media_i"
4841   [(set (pc)
4842         (if_then_else (ltu (match_operand:DI 1 "arith_reg_operand" "r")
4843                            (match_operand:DI 2 "arith_reg_operand" "r"))
4844                       (match_operand:DI 0 "target_operand" "b")
4845                       (pc)))]
4846   "TARGET_SHMEDIA"
4847   "bgtu %2, %1, %0")
4848
4849 (define_expand "beq"
4850   [(set (pc)
4851         (if_then_else (ne (reg:SI T_REG) (const_int 0))
4852                       (label_ref (match_operand 0 "" ""))
4853                       (pc)))]
4854   ""
4855   "
4856 {
4857   if (TARGET_SHMEDIA)
4858     {
4859       if (GET_MODE (sh_compare_op0) != DImode)
4860         {
4861           rtx tmp = gen_reg_rtx (DImode);
4862
4863           emit_insn (gen_seq (tmp));
4864           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
4865           DONE;
4866         }
4867
4868       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
4869       emit_jump_insn (gen_beq_media (operands[0],
4870                                      sh_compare_op0, sh_compare_op1));
4871       DONE;
4872     }
4873
4874   from_compare (operands, EQ);
4875 }")
4876
4877 (define_expand "bne"
4878   [(set (pc)
4879         (if_then_else (eq (reg:SI T_REG) (const_int 0))
4880                       (label_ref (match_operand 0 "" ""))
4881                       (pc)))]
4882   ""
4883   "
4884 {
4885   if (TARGET_SHMEDIA)
4886     {
4887       if (GET_MODE (sh_compare_op0) != DImode)
4888         {
4889           rtx tmp = gen_reg_rtx (DImode);
4890
4891           emit_insn (gen_seq (tmp));
4892           emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
4893           DONE;
4894         }
4895
4896       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
4897       emit_jump_insn (gen_bne_media (operands[0],
4898                                      sh_compare_op0, sh_compare_op1));
4899       DONE;
4900     }
4901
4902   from_compare (operands, EQ);
4903 }")
4904
4905 (define_expand "bgt"
4906   [(set (pc)
4907         (if_then_else (ne (reg:SI T_REG) (const_int 0))
4908                       (label_ref (match_operand 0 "" ""))
4909                       (pc)))]
4910   ""
4911   "
4912 {
4913   if (TARGET_SHMEDIA)
4914     {
4915       if (GET_MODE (sh_compare_op0) != DImode)
4916         {
4917           rtx tmp = gen_reg_rtx (DImode);
4918
4919           emit_insn (gen_sgt (tmp));
4920           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
4921           DONE;
4922         }
4923
4924       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
4925       sh_compare_op1 = force_reg (DImode, sh_compare_op1);
4926       emit_jump_insn (gen_bgt_media (operands[0],
4927                                      sh_compare_op0, sh_compare_op1));
4928       DONE;
4929     }
4930
4931   from_compare (operands, GT);
4932 }")
4933
4934 (define_expand "blt"
4935   [(set (pc)
4936         (if_then_else (eq (reg:SI T_REG) (const_int 0))
4937                       (label_ref (match_operand 0 "" ""))
4938                       (pc)))]
4939   ""
4940   "
4941 {
4942   if (TARGET_SHMEDIA)
4943     {
4944       if (GET_MODE (sh_compare_op0) != DImode)
4945         {
4946           rtx tmp = gen_reg_rtx (DImode);
4947
4948           emit_insn (gen_slt (tmp));
4949           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
4950           DONE;
4951         }
4952
4953       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
4954       sh_compare_op1 = force_reg (DImode, sh_compare_op1);
4955       emit_jump_insn (gen_bgt_media (operands[0],
4956                                      sh_compare_op1, sh_compare_op0));
4957       DONE;
4958     }
4959
4960   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
4961     {
4962       rtx tmp = sh_compare_op0;
4963       sh_compare_op0 = sh_compare_op1;
4964       sh_compare_op1 = tmp;
4965       emit_insn (gen_bgt (operands[0]));
4966       DONE;
4967     }
4968   from_compare (operands, GE);
4969 }")
4970
4971 (define_expand "ble"
4972   [(set (pc)
4973         (if_then_else (eq (reg:SI T_REG) (const_int 0))
4974                       (label_ref (match_operand 0 "" ""))
4975                       (pc)))]
4976   ""
4977   "
4978 {
4979   if (TARGET_SHMEDIA)
4980     {
4981       if (GET_MODE (sh_compare_op0) != DImode)
4982         {
4983           rtx tmp = gen_reg_rtx (DImode);
4984
4985           emit_insn (gen_sle (tmp));
4986           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
4987           DONE;
4988         }
4989
4990       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
4991       sh_compare_op1 = force_reg (DImode, sh_compare_op1);
4992       emit_jump_insn (gen_bge_media (operands[0],
4993                                      sh_compare_op1, sh_compare_op0));
4994       DONE;
4995     }
4996
4997   if (TARGET_SH3E
4998       && TARGET_IEEE
4999       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5000     {
5001       rtx tmp = sh_compare_op0;
5002       sh_compare_op0 = sh_compare_op1;
5003       sh_compare_op1 = tmp;
5004       emit_insn (gen_bge (operands[0]));
5005       DONE;
5006     }
5007   from_compare (operands, GT);
5008 }")
5009
5010 (define_expand "bge"
5011   [(set (pc)
5012         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5013                       (label_ref (match_operand 0 "" ""))
5014                       (pc)))]
5015   ""
5016   "
5017 {
5018   if (TARGET_SHMEDIA)
5019     {
5020       if (GET_MODE (sh_compare_op0) != DImode)
5021         {
5022           rtx tmp = gen_reg_rtx (DImode);
5023
5024           emit_insn (gen_sge (tmp));
5025           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5026           DONE;
5027         }
5028
5029       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5030       sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5031       emit_jump_insn (gen_bge_media (operands[0],
5032                                      sh_compare_op0, sh_compare_op1));
5033       DONE;
5034     }
5035
5036   if (TARGET_SH3E
5037       && ! TARGET_IEEE
5038       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5039     {
5040       rtx tmp = sh_compare_op0;
5041       sh_compare_op0 = sh_compare_op1;
5042       sh_compare_op1 = tmp;
5043       emit_insn (gen_ble (operands[0]));
5044       DONE;
5045     }
5046   from_compare (operands, GE);
5047 }")
5048
5049 (define_expand "bgtu"
5050   [(set (pc)
5051         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5052                       (label_ref (match_operand 0 "" ""))
5053                       (pc)))]
5054   ""
5055   "
5056 {
5057   if (TARGET_SHMEDIA)
5058     {
5059       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5060       sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5061       emit_jump_insn (gen_bgtu_media (operands[0],
5062                                       sh_compare_op0, sh_compare_op1));
5063       DONE;
5064     }
5065
5066   from_compare (operands, GTU);
5067 }")
5068
5069 (define_expand "bltu"
5070   [(set (pc)
5071         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5072                       (label_ref (match_operand 0 "" ""))
5073                       (pc)))]
5074   ""
5075   "
5076 {
5077   if (TARGET_SHMEDIA)
5078     {
5079       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5080       sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5081       emit_jump_insn (gen_bgtu_media (operands[0],
5082                                       sh_compare_op1, sh_compare_op0));
5083       DONE;
5084     }
5085
5086   from_compare (operands, GEU);
5087 }")
5088
5089 (define_expand "bgeu"
5090   [(set (pc)
5091         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5092                       (label_ref (match_operand 0 "" ""))
5093                       (pc)))]
5094   ""
5095   "
5096 {
5097   if (TARGET_SHMEDIA)
5098     {
5099       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5100       sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5101       emit_jump_insn (gen_bgeu_media (operands[0],
5102                                       sh_compare_op0, sh_compare_op1));
5103       DONE;
5104     }
5105
5106   from_compare (operands, GEU);
5107 }")
5108
5109 (define_expand "bleu"
5110   [(set (pc)
5111         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5112                       (label_ref (match_operand 0 "" ""))
5113                       (pc)))]
5114   ""
5115   "
5116 {
5117   if (TARGET_SHMEDIA)
5118     {
5119       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5120       sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5121       emit_jump_insn (gen_bgeu_media (operands[0],
5122                                       sh_compare_op1, sh_compare_op0));
5123       DONE;
5124     }
5125
5126   from_compare (operands, GTU);
5127 }")
5128
5129 (define_expand "bunordered"
5130   [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5131    (set (pc)
5132         (if_then_else (ne (match_dup 1) (const_int 0))
5133                       (label_ref:DI (match_operand 0 "" ""))
5134                       (pc)))]
5135   "TARGET_SHMEDIA"
5136   "
5137 {
5138   operands[1] = gen_reg_rtx (DImode);
5139   operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5140   operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5141 }")
5142 \f
5143 ;; ------------------------------------------------------------------------
5144 ;; Jump and linkage insns
5145 ;; ------------------------------------------------------------------------
5146
5147 (define_insn "jump_compact"
5148   [(set (pc)
5149         (label_ref (match_operand 0 "" "")))]
5150   "TARGET_SH1"
5151   "*
5152 {
5153   /* The length is 16 if the delay slot is unfilled.  */
5154   if (get_attr_length(insn) > 4)
5155     return output_far_jump(insn, operands[0]);
5156   else
5157     return   \"bra      %l0%#\";
5158 }"
5159   [(set_attr "type" "jump")
5160    (set_attr "needs_delay_slot" "yes")])
5161
5162 (define_insn "jump_media"
5163   [(set (pc)
5164         (match_operand:DI 0 "target_operand" "b"))]
5165   "TARGET_SHMEDIA"
5166   "blink        %0, r63")
5167
5168 (define_expand "jump"
5169   [(set (pc)
5170         (label_ref (match_operand 0 "" "")))]
5171   ""
5172   "
5173 {
5174   if (TARGET_SH1)
5175     emit_jump_insn (gen_jump_compact (operands[0]));
5176   else if (TARGET_SHMEDIA)
5177     {
5178       if (reload_in_progress || reload_completed)
5179         FAIL;
5180       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5181                                                          operands[0])));
5182     }
5183   DONE;
5184 }")
5185
5186 (define_insn "force_mode_for_call"
5187   [(use (reg:PSI FPSCR_REG))]
5188   "TARGET_SHCOMPACT"
5189   ""
5190   [(set_attr "length" "0")
5191    (set (attr "fp_mode")
5192         (if_then_else (eq_attr "fpu_single" "yes")
5193                       (const_string "single") (const_string "double")))])
5194
5195 (define_insn "calli"
5196   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5197          (match_operand 1 "" ""))
5198    (use (reg:PSI FPSCR_REG))
5199    (clobber (reg:SI PR_REG))]
5200   "TARGET_SH1"
5201   "jsr  @%0%#"
5202   [(set_attr "type" "call")
5203    (set (attr "fp_mode")
5204         (if_then_else (eq_attr "fpu_single" "yes")
5205                       (const_string "single") (const_string "double")))
5206    (set_attr "needs_delay_slot" "yes")])
5207
5208 ;; This is a pc-rel call, using bsrf, for use with PIC.
5209
5210 (define_insn "calli_pcrel"
5211   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5212          (match_operand 1 "" ""))
5213    (use (reg:PSI FPSCR_REG))
5214    (use (reg:SI PIC_REG))
5215    (use (match_operand 2 "" ""))
5216    (clobber (reg:SI PR_REG))]
5217   "TARGET_SH2"
5218   "bsrf %0\\n%O2:%#"
5219   [(set_attr "type" "call")
5220    (set (attr "fp_mode")
5221         (if_then_else (eq_attr "fpu_single" "yes")
5222                       (const_string "single") (const_string "double")))
5223    (set_attr "needs_delay_slot" "yes")])
5224
5225 (define_insn_and_split "call_pcrel"
5226   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5227          (match_operand 1 "" ""))
5228    (use (reg:PSI FPSCR_REG))
5229    (use (reg:SI PIC_REG))
5230    (clobber (reg:SI PR_REG))
5231    (clobber (match_scratch:SI 2 "=r"))]
5232   "TARGET_SH2"
5233   "#"
5234   "reload_completed"
5235   [(const_int 0)]
5236   "
5237 {
5238   rtx lab = PATTERN (gen_call_site ());
5239
5240   if (SYMBOL_REF_FLAG (operands[0]))
5241     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5242   else
5243     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5244   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5245   DONE;
5246 }"
5247   [(set_attr "type" "call")
5248    (set (attr "fp_mode")
5249         (if_then_else (eq_attr "fpu_single" "yes")
5250                       (const_string "single") (const_string "double")))
5251    (set_attr "needs_delay_slot" "yes")])
5252
5253 (define_insn "call_compact"
5254   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5255          (match_operand 1 "" ""))
5256    (match_operand 2 "immediate_operand" "n")
5257    (use (reg:SI R0_REG))
5258    (use (reg:SI R1_REG))
5259    (use (reg:PSI FPSCR_REG))
5260    (clobber (reg:SI PR_REG))]
5261   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5262   "jsr  @%0%#"
5263   [(set_attr "type" "call")
5264    (set (attr "fp_mode")
5265         (if_then_else (eq_attr "fpu_single" "yes")
5266                       (const_string "single") (const_string "double")))
5267    (set_attr "needs_delay_slot" "yes")])
5268
5269 (define_insn "call_compact_rettramp"
5270   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5271          (match_operand 1 "" ""))
5272    (match_operand 2 "immediate_operand" "n")
5273    (use (reg:SI R0_REG))
5274    (use (reg:SI R1_REG))
5275    (use (reg:PSI FPSCR_REG))
5276    (clobber (reg:SI R10_REG))
5277    (clobber (reg:SI PR_REG))]
5278   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5279   "jsr  @%0%#"
5280   [(set_attr "type" "call")
5281    (set (attr "fp_mode")
5282         (if_then_else (eq_attr "fpu_single" "yes")
5283                       (const_string "single") (const_string "double")))
5284    (set_attr "needs_delay_slot" "yes")])
5285
5286 (define_insn "call_media"
5287   [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5288          (match_operand 1 "" ""))
5289    (clobber (reg:DI PR_MEDIA_REG))]
5290   "TARGET_SHMEDIA"
5291   "blink        %0, r18")
5292
5293 (define_insn "call_valuei"
5294   [(set (match_operand 0 "" "=rf")
5295         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5296               (match_operand 2 "" "")))
5297    (use (reg:PSI FPSCR_REG))
5298    (clobber (reg:SI PR_REG))]
5299   "TARGET_SH1"
5300   "jsr  @%1%#"
5301   [(set_attr "type" "call")
5302    (set (attr "fp_mode")
5303         (if_then_else (eq_attr "fpu_single" "yes")
5304                       (const_string "single") (const_string "double")))
5305    (set_attr "needs_delay_slot" "yes")])
5306
5307 (define_insn "call_valuei_pcrel"
5308   [(set (match_operand 0 "" "=rf")
5309         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5310               (match_operand 2 "" "")))
5311    (use (reg:PSI FPSCR_REG))
5312    (use (reg:SI PIC_REG))
5313    (use (match_operand 3 "" ""))
5314    (clobber (reg:SI PR_REG))]
5315   "TARGET_SH2"
5316   "bsrf %1\\n%O3:%#"
5317   [(set_attr "type" "call")
5318    (set (attr "fp_mode")
5319         (if_then_else (eq_attr "fpu_single" "yes")
5320                       (const_string "single") (const_string "double")))
5321    (set_attr "needs_delay_slot" "yes")])
5322
5323 (define_insn_and_split "call_value_pcrel"
5324   [(set (match_operand 0 "" "=rf")
5325         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5326               (match_operand 2 "" "")))
5327    (use (reg:PSI FPSCR_REG))
5328    (use (reg:SI PIC_REG))
5329    (clobber (reg:SI PR_REG))
5330    (clobber (match_scratch:SI 3 "=r"))]
5331   "TARGET_SH2"
5332   "#"
5333   "reload_completed"
5334   [(const_int 0)]
5335   "
5336 {
5337   rtx lab = PATTERN (gen_call_site ());
5338
5339   if (SYMBOL_REF_FLAG (operands[1]))
5340     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5341   else
5342     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5343   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5344                                          operands[2], lab));
5345   DONE;
5346 }"
5347   [(set_attr "type" "call")
5348    (set (attr "fp_mode")
5349         (if_then_else (eq_attr "fpu_single" "yes")
5350                       (const_string "single") (const_string "double")))
5351    (set_attr "needs_delay_slot" "yes")])
5352
5353 (define_insn "call_value_compact"
5354   [(set (match_operand 0 "" "=rf")
5355         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5356               (match_operand 2 "" "")))
5357    (match_operand 3 "immediate_operand" "n")
5358    (use (reg:SI R0_REG))
5359    (use (reg:SI R1_REG))
5360    (use (reg:PSI FPSCR_REG))
5361    (clobber (reg:SI PR_REG))]
5362   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5363   "jsr  @%1%#"
5364   [(set_attr "type" "call")
5365    (set (attr "fp_mode")
5366         (if_then_else (eq_attr "fpu_single" "yes")
5367                       (const_string "single") (const_string "double")))
5368    (set_attr "needs_delay_slot" "yes")])
5369
5370 (define_insn "call_value_compact_rettramp"
5371   [(set (match_operand 0 "" "=rf")
5372         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5373               (match_operand 2 "" "")))
5374    (match_operand 3 "immediate_operand" "n")
5375    (use (reg:SI R0_REG))
5376    (use (reg:SI R1_REG))
5377    (use (reg:PSI FPSCR_REG))
5378    (clobber (reg:SI R10_REG))
5379    (clobber (reg:SI PR_REG))]
5380   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5381   "jsr  @%1%#"
5382   [(set_attr "type" "call")
5383    (set (attr "fp_mode")
5384         (if_then_else (eq_attr "fpu_single" "yes")
5385                       (const_string "single") (const_string "double")))
5386    (set_attr "needs_delay_slot" "yes")])
5387
5388 (define_insn "call_value_media"
5389   [(set (match_operand 0 "" "=rf")
5390         (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5391               (match_operand 2 "" "")))
5392    (clobber (reg:DI PR_MEDIA_REG))]
5393   "TARGET_SHMEDIA"
5394   "blink        %1, r18")
5395
5396 (define_expand "call"
5397   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5398                             (match_operand 1 "" ""))
5399               (match_operand 2 "" "")
5400               (use (reg:PSI FPSCR_REG))
5401               (clobber (reg:SI PR_REG))])]
5402   ""
5403   "
5404 {
5405   if (TARGET_SHMEDIA)
5406     {
5407       operands[0] = XEXP (operands[0], 0);
5408       if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5409         {
5410           if (! SYMBOL_REF_FLAG (operands[0]))
5411             {
5412               rtx reg = gen_reg_rtx (Pmode);
5413               
5414               emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5415               operands[0] = reg;
5416             }
5417           else
5418             {
5419               operands[0] = gen_sym2PIC (operands[0]);
5420               PUT_MODE (operands[0], Pmode);
5421             }
5422         }
5423       if (GET_MODE (operands[0]) == SImode)
5424         {
5425           if (GET_CODE (operands[0]) == REG)
5426             operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5427           else if (GET_CODE (operands[0]) == SUBREG)
5428             {
5429               operands[0] = SUBREG_REG (operands[0]);
5430               if (GET_MODE (operands[0]) != DImode)
5431                 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5432             }
5433           else
5434             {
5435               operands[0] = shallow_copy_rtx (operands[0]);
5436               PUT_MODE (operands[0], DImode);
5437             }
5438         }
5439       if (! target_reg_operand (operands[0], DImode))
5440         operands[0] = copy_to_mode_reg (DImode, operands[0]);
5441       emit_call_insn (gen_call_media (operands[0], operands[1]));
5442       DONE;
5443     }
5444   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5445     {
5446       rtx cookie_rtx = operands[2];
5447       long cookie = INTVAL (cookie_rtx);
5448       rtx func = XEXP (operands[0], 0);
5449       rtx r0, r1;
5450
5451       if (flag_pic)
5452         {
5453           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5454             {
5455               rtx reg = gen_reg_rtx (Pmode);
5456
5457               emit_insn (gen_symGOTPLT2reg (reg, func));
5458               func = reg;
5459             }
5460           else
5461             func = legitimize_pic_address (func, Pmode, 0);
5462         }
5463
5464       r0 = gen_rtx_REG (SImode, R0_REG);
5465       r1 = gen_rtx_REG (SImode, R1_REG);
5466
5467       /* Since such a call function may use all call-clobbered
5468          registers, we force a mode switch earlier, so that we don't
5469          run out of registers when adjusting fpscr for the call.  */
5470       emit_insn (gen_force_mode_for_call ());
5471
5472       operands[0] = gen_rtx_SYMBOL_REF (SImode,
5473                                         \"__GCC_shcompact_call_trampoline\");
5474       if (flag_pic)
5475         {
5476           rtx reg = gen_reg_rtx (Pmode);
5477
5478           emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5479           operands[0] = reg;
5480         }
5481       operands[0] = force_reg (SImode, operands[0]);
5482
5483       emit_move_insn (r0, func);
5484       emit_move_insn (r1, cookie_rtx);
5485
5486       if (cookie & CALL_COOKIE_RET_TRAMP (1))
5487         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5488                                                    operands[2]));
5489       else
5490         emit_call_insn (gen_call_compact (operands[0], operands[1],
5491                                           operands[2]));
5492
5493       DONE;
5494     }
5495   else if (TARGET_SHCOMPACT && flag_pic
5496            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5497            && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
5498     {
5499       rtx reg = gen_reg_rtx (Pmode);
5500
5501       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5502       XEXP (operands[0], 0) = reg;
5503     }
5504   if (flag_pic && TARGET_SH2
5505       && GET_CODE (operands[0]) == MEM
5506       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5507     {
5508       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
5509       DONE;
5510     }
5511   else
5512     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5513
5514   emit_call_insn (gen_calli (operands[0], operands[1]));
5515   DONE;
5516 }")
5517
5518 (define_insn "call_pop_compact"
5519   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5520          (match_operand 1 "" ""))
5521    (match_operand 2 "immediate_operand" "n")
5522    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5523                                  (match_operand 3 "immediate_operand" "n")))
5524    (use (reg:SI R0_REG))
5525    (use (reg:SI R1_REG))
5526    (use (reg:PSI FPSCR_REG))
5527    (clobber (reg:SI PR_REG))]
5528   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5529   "jsr  @%0%#"
5530   [(set_attr "type" "call")
5531    (set (attr "fp_mode")
5532         (if_then_else (eq_attr "fpu_single" "yes")
5533                       (const_string "single") (const_string "double")))
5534    (set_attr "needs_delay_slot" "yes")])
5535
5536 (define_insn "call_pop_compact_rettramp"
5537   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5538          (match_operand 1 "" ""))
5539    (match_operand 2 "immediate_operand" "n")
5540    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5541                                  (match_operand 3 "immediate_operand" "n")))
5542    (use (reg:SI R0_REG))
5543    (use (reg:SI R1_REG))
5544    (use (reg:PSI FPSCR_REG))
5545    (clobber (reg:SI R10_REG))
5546    (clobber (reg:SI PR_REG))]
5547   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5548   "jsr  @%0%#"
5549   [(set_attr "type" "call")
5550    (set (attr "fp_mode")
5551         (if_then_else (eq_attr "fpu_single" "yes")
5552                       (const_string "single") (const_string "double")))
5553    (set_attr "needs_delay_slot" "yes")])
5554
5555 (define_expand "call_pop"
5556   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5557                     (match_operand 1 "" ""))
5558              (match_operand 2 "" "")
5559              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5560                                            (match_operand 3 "" "")))])]
5561   "TARGET_SHCOMPACT"
5562   "
5563 {
5564   if (operands[2] && INTVAL (operands[2]))
5565     {
5566       rtx cookie_rtx = operands[2];
5567       long cookie = INTVAL (cookie_rtx);
5568       rtx func = XEXP (operands[0], 0);
5569       rtx r0, r1;
5570
5571       if (flag_pic)
5572         {
5573           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5574             {
5575               rtx reg = gen_reg_rtx (Pmode);
5576
5577               emit_insn (gen_symGOTPLT2reg (reg, func));
5578               func = reg;
5579             }
5580           else
5581             func = legitimize_pic_address (func, Pmode, 0);
5582         }
5583
5584       r0 = gen_rtx_REG (SImode, R0_REG);
5585       r1 = gen_rtx_REG (SImode, R1_REG);
5586
5587       /* Since such a call function may use all call-clobbered
5588          registers, we force a mode switch earlier, so that we don't
5589          run out of registers when adjusting fpscr for the call.  */
5590       emit_insn (gen_force_mode_for_call ());
5591
5592       operands[0] = gen_rtx_SYMBOL_REF (SImode,
5593                                         \"__GCC_shcompact_call_trampoline\");
5594       if (flag_pic)
5595         {
5596           rtx reg = gen_reg_rtx (Pmode);
5597
5598           emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5599           operands[0] = reg;
5600         }
5601       operands[0] = force_reg (SImode, operands[0]);
5602
5603       emit_move_insn (r0, func);
5604       emit_move_insn (r1, cookie_rtx);
5605
5606       if (cookie & CALL_COOKIE_RET_TRAMP (1))
5607         emit_call_insn (gen_call_pop_compact_rettramp
5608                         (operands[0], operands[1], operands[2], operands[3]));
5609       else
5610         emit_call_insn (gen_call_pop_compact
5611                         (operands[0], operands[1], operands[2], operands[3]));
5612
5613       DONE;
5614     }
5615
5616   abort ();
5617 }")
5618
5619 (define_expand "call_value"
5620   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
5621                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
5622                                  (match_operand 2 "" "")))
5623               (match_operand 3 "" "")
5624               (use (reg:PSI FPSCR_REG))
5625               (clobber (reg:SI PR_REG))])]
5626   ""
5627   "
5628 {
5629   if (TARGET_SHMEDIA)
5630     {
5631       operands[1] = XEXP (operands[1], 0);
5632       if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
5633         {
5634           if (! SYMBOL_REF_FLAG (operands[1]))
5635             {
5636               rtx reg = gen_reg_rtx (Pmode);
5637               
5638               emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
5639               operands[1] = reg;
5640             }
5641           else
5642             {
5643               operands[1] = gen_sym2PIC (operands[1]);
5644               PUT_MODE (operands[1], Pmode);
5645             }
5646         }
5647       if (GET_MODE (operands[1]) == SImode)
5648         {
5649           if (GET_CODE (operands[1]) == REG)
5650             operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5651           else if (GET_CODE (operands[1]) == SUBREG)
5652             {
5653               operands[1] = SUBREG_REG (operands[1]);
5654               if (GET_MODE (operands[1]) != DImode)
5655                 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5656             }
5657           else
5658             {
5659               operands[1] = shallow_copy_rtx (operands[1]);
5660               PUT_MODE (operands[1], DImode);
5661             }
5662         }
5663       if (! target_reg_operand (operands[1], DImode))
5664         operands[1] = copy_to_mode_reg (DImode, operands[1]);
5665       emit_call_insn (gen_call_value_media (operands[0], operands[1],
5666                                             operands[2]));
5667       DONE;
5668     }
5669   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
5670     {
5671       rtx cookie_rtx = operands[3];
5672       long cookie = INTVAL (cookie_rtx);
5673       rtx func = XEXP (operands[1], 0);
5674       rtx r0, r1;
5675
5676       if (flag_pic)
5677         {
5678           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5679             {
5680               rtx reg = gen_reg_rtx (Pmode);
5681
5682               emit_insn (gen_symGOTPLT2reg (reg, func));
5683               func = reg;
5684             }
5685           else
5686             func = legitimize_pic_address (func, Pmode, 0);
5687         }
5688
5689       r0 = gen_rtx_REG (SImode, R0_REG);
5690       r1 = gen_rtx_REG (SImode, R1_REG);
5691
5692       /* Since such a call function may use all call-clobbered
5693          registers, we force a mode switch earlier, so that we don't
5694          run out of registers when adjusting fpscr for the call.  */
5695       emit_insn (gen_force_mode_for_call ());
5696
5697       operands[1] = gen_rtx_SYMBOL_REF (SImode,
5698                                         \"__GCC_shcompact_call_trampoline\");
5699       if (flag_pic)
5700         {
5701           rtx reg = gen_reg_rtx (Pmode);
5702
5703           emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
5704           operands[1] = reg;
5705         }
5706       operands[1] = force_reg (SImode, operands[1]);
5707
5708       emit_move_insn (r0, func);
5709       emit_move_insn (r1, cookie_rtx);
5710
5711       if (cookie & CALL_COOKIE_RET_TRAMP (1))
5712         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
5713                                                          operands[1],
5714                                                          operands[2],
5715                                                          operands[3]));
5716       else
5717         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
5718                                                 operands[2], operands[3]));
5719
5720       DONE;
5721     }
5722   else if (TARGET_SHCOMPACT && flag_pic
5723            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
5724            && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
5725     {
5726       rtx reg = gen_reg_rtx (Pmode);
5727
5728       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
5729       XEXP (operands[1], 0) = reg;
5730     }
5731   if (flag_pic && TARGET_SH2
5732       && GET_CODE (operands[1]) == MEM
5733       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
5734     {
5735       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
5736                                             operands[2]));
5737       DONE;
5738     }
5739   else
5740     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
5741
5742   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
5743   DONE;
5744 }")
5745
5746 (define_insn "sibcalli"
5747   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
5748          (match_operand 1 "" ""))
5749    (use (reg:PSI FPSCR_REG))
5750    (return)]
5751   "TARGET_SH1"
5752   "jmp  @%0%#"
5753   [(set_attr "needs_delay_slot" "yes")
5754    (set (attr "fp_mode")
5755         (if_then_else (eq_attr "fpu_single" "yes")
5756                       (const_string "single") (const_string "double")))
5757    (set_attr "type" "jump_ind")])
5758
5759 (define_insn "sibcalli_pcrel"
5760   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
5761          (match_operand 1 "" ""))
5762    (use (match_operand 2 "" ""))
5763    (use (reg:PSI FPSCR_REG))
5764    (return)]
5765   "TARGET_SH2"
5766   "braf %0\\n%O2:%#"
5767   [(set_attr "needs_delay_slot" "yes")
5768    (set (attr "fp_mode")
5769         (if_then_else (eq_attr "fpu_single" "yes")
5770                       (const_string "single") (const_string "double")))
5771    (set_attr "type" "jump_ind")])
5772
5773 (define_insn_and_split "sibcall_pcrel"
5774   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5775          (match_operand 1 "" ""))
5776    (use (reg:PSI FPSCR_REG))
5777    (clobber (match_scratch:SI 2 "=k"))
5778    (return)]
5779   "TARGET_SH2"
5780   "#"
5781   "reload_completed"
5782   [(const_int 0)]
5783   "
5784 {
5785   rtx lab = PATTERN (gen_call_site ());
5786   rtx call_insn;
5787
5788   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5789   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
5790                                                   lab));
5791   SIBLING_CALL_P (call_insn) = 1;
5792   DONE;
5793 }"
5794   [(set_attr "needs_delay_slot" "yes")
5795    (set (attr "fp_mode")
5796         (if_then_else (eq_attr "fpu_single" "yes")
5797                       (const_string "single") (const_string "double")))
5798    (set_attr "type" "jump_ind")])
5799
5800 (define_insn "sibcall_compact"
5801   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
5802          (match_operand 1 "" ""))
5803    (return)
5804    (use (match_operand 2 "register_operand" "z,x"))
5805    (use (reg:SI R1_REG))
5806    (use (reg:PSI FPSCR_REG))
5807    ;; We want to make sure the `x' above will only match MACH_REG
5808    ;; because sibcall_epilogue may clobber MACL_REG.
5809    (clobber (reg:SI MACL_REG))]
5810   "TARGET_SHCOMPACT"
5811   "@
5812         jmp     @%0%#
5813         jmp     @%0\\n  sts     %2, r0"
5814   [(set_attr "needs_delay_slot" "yes,no")
5815    (set_attr "length" "2,4")
5816    (set (attr "fp_mode") (const_string "single"))
5817    (set_attr "type" "jump_ind")])
5818
5819 (define_insn "sibcall_media"
5820   [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
5821          (match_operand 1 "" ""))
5822    (return)]
5823   "TARGET_SHMEDIA"
5824   "blink        %0, r63")
5825
5826 (define_expand "sibcall"
5827   [(parallel
5828     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5829            (match_operand 1 "" ""))
5830      (match_operand 2 "" "")
5831      (use (reg:PSI FPSCR_REG))
5832      (return)])]
5833   ""
5834   "
5835 {
5836   if (TARGET_SHMEDIA)
5837     {
5838       operands[0] = XEXP (operands[0], 0);
5839       if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5840         {
5841           if (! SYMBOL_REF_FLAG (operands[0]))
5842             {
5843               rtx reg = gen_reg_rtx (Pmode);
5844               
5845               /* We must not use GOTPLT for sibcalls, because PIC_REG
5846                  must be restored before the PLT code gets to run.  */
5847               emit_insn (gen_symGOT2reg (reg, operands[0]));
5848               operands[0] = reg;
5849             }
5850           else
5851             {
5852               operands[0] = gen_sym2PIC (operands[0]);
5853               PUT_MODE (operands[0], Pmode);
5854             }
5855         }
5856       if (GET_MODE (operands[0]) == SImode)
5857         {
5858           if (GET_CODE (operands[0]) == REG)
5859             operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5860           else if (GET_CODE (operands[0]) == SUBREG)
5861             {
5862               operands[0] = SUBREG_REG (operands[0]);
5863               if (GET_MODE (operands[0]) != DImode)
5864                 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5865             }
5866           else
5867             {
5868               operands[0] = shallow_copy_rtx (operands[0]);
5869               PUT_MODE (operands[0], DImode);
5870             }
5871         }
5872       if (! target_reg_operand (operands[0], DImode))
5873         operands[0] = copy_to_mode_reg (DImode, operands[0]);
5874       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
5875       DONE;
5876     }
5877   else if (TARGET_SHCOMPACT && operands[2]
5878            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
5879     {
5880       rtx cookie_rtx = operands[2];
5881       long cookie = INTVAL (cookie_rtx);
5882       rtx func = XEXP (operands[0], 0);
5883       rtx mach, r1;
5884
5885       if (flag_pic)
5886         {
5887           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5888             {
5889               rtx reg = gen_reg_rtx (Pmode);
5890
5891               emit_insn (gen_symGOT2reg (reg, func));
5892               func = reg;
5893             }
5894           else
5895             func = legitimize_pic_address (func, Pmode, 0);
5896         }
5897
5898       /* FIXME: if we could tell whether all argument registers are
5899          already taken, we could decide whether to force the use of
5900          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
5901          simple way to tell.  We could use the CALL_COOKIE, but we
5902          can't currently tell a register used for regular argument
5903          passing from one that is unused.  If we leave it up to reload
5904          to decide which register to use, it seems to always choose
5905          R0_REG, which leaves no available registers in SIBCALL_REGS
5906          to hold the address of the trampoline.  */
5907       mach = gen_rtx_REG (SImode, MACH_REG);
5908       r1 = gen_rtx_REG (SImode, R1_REG);
5909
5910       /* Since such a call function may use all call-clobbered
5911          registers, we force a mode switch earlier, so that we don't
5912          run out of registers when adjusting fpscr for the call.  */
5913       emit_insn (gen_force_mode_for_call ());
5914
5915       operands[0] = gen_rtx_SYMBOL_REF (SImode,
5916                                         \"__GCC_shcompact_call_trampoline\");
5917       if (flag_pic)
5918         {
5919           rtx reg = gen_reg_rtx (Pmode);
5920
5921           emit_insn (gen_symGOT2reg (reg, operands[0]));
5922           operands[0] = reg;
5923         }
5924       operands[0] = force_reg (SImode, operands[0]);
5925
5926       /* We don't need a return trampoline, since the callee will
5927          return directly to the upper caller.  */
5928       if (cookie & CALL_COOKIE_RET_TRAMP (1))
5929         {
5930           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
5931           cookie_rtx = GEN_INT (cookie);
5932         }
5933
5934       emit_move_insn (mach, func);
5935       emit_move_insn (r1, cookie_rtx);
5936
5937       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
5938       DONE;
5939     }
5940   else if (TARGET_SHCOMPACT && flag_pic
5941            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5942            && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
5943     {
5944       rtx reg = gen_reg_rtx (Pmode);
5945
5946       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
5947       XEXP (operands[0], 0) = reg;
5948     }
5949   if (flag_pic && TARGET_SH2
5950       && GET_CODE (operands[0]) == MEM
5951       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5952       /* The PLT needs the PIC register, but the epilogue would have
5953          to restore it, so we can only use PC-relative PIC calls for
5954          static functions.  */
5955       && SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
5956     {
5957       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
5958       DONE;
5959     }
5960   else
5961     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5962
5963   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
5964   DONE;
5965 }")
5966
5967 (define_expand "sibcall_value"
5968   [(set (match_operand 0 "" "")
5969         (call (match_operand 1 "" "")
5970               (match_operand 2 "" "")))
5971    (match_operand 3 "" "")]
5972   ""
5973   "
5974 {
5975   emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
5976   DONE;
5977 }")
5978
5979 (define_insn "call_value_pop_compact"
5980   [(set (match_operand 0 "" "=rf")
5981         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5982               (match_operand 2 "" "")))
5983    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5984                                  (match_operand 4 "immediate_operand" "n")))
5985    (match_operand 3 "immediate_operand" "n")
5986    (use (reg:SI R0_REG))
5987    (use (reg:SI R1_REG))
5988    (use (reg:PSI FPSCR_REG))
5989    (clobber (reg:SI PR_REG))]
5990   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5991   "jsr  @%1%#"
5992   [(set_attr "type" "call")
5993    (set (attr "fp_mode")
5994         (if_then_else (eq_attr "fpu_single" "yes")
5995                       (const_string "single") (const_string "double")))
5996    (set_attr "needs_delay_slot" "yes")])
5997
5998 (define_insn "call_value_pop_compact_rettramp"
5999   [(set (match_operand 0 "" "=rf")
6000         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6001               (match_operand 2 "" "")))
6002    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6003                                  (match_operand 4 "immediate_operand" "n")))
6004    (match_operand 3 "immediate_operand" "n")
6005    (use (reg:SI R0_REG))
6006    (use (reg:SI R1_REG))
6007    (use (reg:PSI FPSCR_REG))
6008    (clobber (reg:SI R10_REG))
6009    (clobber (reg:SI PR_REG))]
6010   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6011   "jsr  @%1%#"
6012   [(set_attr "type" "call")
6013    (set (attr "fp_mode")
6014         (if_then_else (eq_attr "fpu_single" "yes")
6015                       (const_string "single") (const_string "double")))
6016    (set_attr "needs_delay_slot" "yes")])
6017
6018 (define_expand "call_value_pop"
6019   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6020                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6021                                  (match_operand 2 "" "")))
6022               (match_operand 3 "" "")
6023               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6024                                             (match_operand 4 "" "")))])]
6025   "TARGET_SHCOMPACT"
6026   "
6027 {
6028   if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6029     {
6030       rtx cookie_rtx = operands[3];
6031       long cookie = INTVAL (cookie_rtx);
6032       rtx func = XEXP (operands[1], 0);
6033       rtx r0, r1;
6034
6035       if (flag_pic)
6036         {
6037           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
6038             {
6039               rtx reg = gen_reg_rtx (Pmode);
6040
6041               emit_insn (gen_symGOTPLT2reg (reg, func));
6042               func = reg;
6043             }
6044           else
6045             func = legitimize_pic_address (func, Pmode, 0);
6046         }
6047
6048       r0 = gen_rtx_REG (SImode, R0_REG);
6049       r1 = gen_rtx_REG (SImode, R1_REG);
6050
6051       /* Since such a call function may use all call-clobbered
6052          registers, we force a mode switch earlier, so that we don't
6053          run out of registers when adjusting fpscr for the call.  */
6054       emit_insn (gen_force_mode_for_call ());
6055
6056       operands[1] = gen_rtx_SYMBOL_REF (SImode,
6057                                         \"__GCC_shcompact_call_trampoline\");
6058       if (flag_pic)
6059         {
6060           rtx reg = gen_reg_rtx (Pmode);
6061
6062           emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6063           operands[1] = reg;
6064         }
6065       operands[1] = force_reg (SImode, operands[1]);
6066
6067       emit_move_insn (r0, func);
6068       emit_move_insn (r1, cookie_rtx);
6069
6070       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6071         emit_call_insn (gen_call_value_pop_compact_rettramp
6072                         (operands[0], operands[1], operands[2],
6073                          operands[3], operands[4]));
6074       else
6075         emit_call_insn (gen_call_value_pop_compact
6076                         (operands[0], operands[1], operands[2],
6077                          operands[3], operands[4]));
6078
6079       DONE;
6080     }
6081
6082   abort ();
6083 }")
6084
6085 (define_expand "sibcall_epilogue"
6086   [(return)]
6087   ""
6088   "
6089 {
6090   sh_expand_epilogue ();
6091   if (TARGET_SHCOMPACT)
6092     {
6093       rtx insn, set;
6094
6095       /* If epilogue clobbers r0, preserve it in macl.  */
6096       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6097         if ((set = single_set (insn))
6098             && GET_CODE (SET_DEST (set)) == REG
6099             && REGNO (SET_DEST (set)) == R0_REG)
6100           {
6101             rtx r0 = gen_rtx_REG (SImode, R0_REG);
6102             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6103             rtx i;
6104
6105             /* We can't tell at this point whether the sibcall is a
6106                sibcall_compact and, if it is, whether it uses r0 or
6107                mach as operand 2, so let the instructions that
6108                preserve r0 be optimized away if r0 turns out to be
6109                dead.  */
6110             i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6111             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6112                                                REG_NOTES (i));
6113             i = emit_move_insn (r0, tmp);
6114             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6115                                                REG_NOTES (i));
6116             break;
6117           }
6118     }
6119   DONE;
6120 }")
6121
6122 (define_insn "indirect_jump_compact"
6123   [(set (pc)
6124         (match_operand:SI 0 "arith_reg_operand" "r"))]
6125   "TARGET_SH1"
6126   "jmp  @%0%#"
6127   [(set_attr "needs_delay_slot" "yes")
6128    (set_attr "type" "jump_ind")])
6129
6130 (define_expand "indirect_jump"
6131   [(set (pc)
6132         (match_operand 0 "register_operand" ""))]
6133   ""
6134   "
6135 {
6136   if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6137     operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6138 }")
6139
6140 ;; The use of operand 1 / 2 helps us distinguish case table jumps
6141 ;; which can be present in structured code from indirect jumps which can not
6142 ;; be present in structured code.  This allows -fprofile-arcs to work.
6143
6144 ;; For SH1 processors.
6145 (define_insn "casesi_jump_1"
6146   [(set (pc)
6147         (match_operand:SI 0 "register_operand" "r"))
6148    (use (label_ref (match_operand 1 "" "")))]
6149   "TARGET_SH1"
6150   "jmp  @%0%#"
6151   [(set_attr "needs_delay_slot" "yes")
6152    (set_attr "type" "jump_ind")])
6153
6154 ;; For all later processors.
6155 (define_insn "casesi_jump_2"
6156   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
6157                       (label_ref (match_operand 1 "" ""))))
6158    (use (label_ref (match_operand 2 "" "")))]
6159   "TARGET_SH2
6160    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
6161   "braf %0%#"
6162   [(set_attr "needs_delay_slot" "yes")
6163    (set_attr "type" "jump_ind")])
6164
6165 (define_insn "casesi_jump_media"
6166   [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6167    (use (label_ref (match_operand 1 "" "")))]
6168   "TARGET_SHMEDIA"
6169   "blink        %0, r63")
6170   
6171 ;; Call subroutine returning any type.
6172 ;; ??? This probably doesn't work.
6173
6174 (define_expand "untyped_call"
6175   [(parallel [(call (match_operand 0 "" "")
6176                     (const_int 0))
6177               (match_operand 1 "" "")
6178               (match_operand 2 "" "")])]
6179   "TARGET_SH3E || TARGET_SHMEDIA"
6180   "
6181 {
6182   int i;
6183
6184   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
6185
6186   for (i = 0; i < XVECLEN (operands[2], 0); i++)
6187     {
6188       rtx set = XVECEXP (operands[2], 0, i);
6189       emit_move_insn (SET_DEST (set), SET_SRC (set));
6190     }
6191
6192   /* The optimizer does not know that the call sets the function value
6193      registers we stored in the result block.  We avoid problems by
6194      claiming that all hard registers are used and clobbered at this
6195      point.  */
6196   emit_insn (gen_blockage ());
6197
6198   DONE;
6199 }")
6200 \f
6201 ;; ------------------------------------------------------------------------
6202 ;; Misc insns
6203 ;; ------------------------------------------------------------------------
6204
6205 (define_insn "dect"
6206   [(set (reg:SI T_REG)
6207         (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6208    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
6209   "TARGET_SH2"
6210   "dt   %0"
6211   [(set_attr "type" "arith")])
6212
6213 (define_insn "nop"
6214   [(const_int 0)]
6215   ""
6216   "nop")
6217
6218 ;; Load address of a label. This is only generated by the casesi expand,
6219 ;; and by machine_dependent_reorg (fixing up fp moves).
6220 ;; This must use unspec, because this only works for labels that are
6221 ;; within range,
6222
6223 (define_insn "mova"
6224   [(set (reg:SI R0_REG)
6225         (unspec [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
6226   "TARGET_SH1"
6227   "mova %O0,r0"
6228   [(set_attr "in_delay_slot" "no")
6229    (set_attr "type" "arith")])
6230
6231 ;; machine_dependent_reorg() will make this a `mova'.
6232 (define_insn "mova_const"
6233   [(set (reg:SI R0_REG)
6234         (unspec [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
6235   "TARGET_SH1"
6236   "#"
6237   [(set_attr "in_delay_slot" "no")
6238    (set_attr "type" "arith")])
6239
6240 (define_expand "GOTaddr2picreg"
6241   [(set (reg:SI R0_REG)
6242         (unspec [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6243                 UNSPEC_MOVA))
6244    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
6245    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6246   "" "
6247 {
6248   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
6249   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
6250
6251   if (TARGET_SH5)
6252     operands[1] = gen_datalabel_ref (operands[1]);
6253
6254   if (TARGET_SHMEDIA)
6255     {
6256       rtx tr = gen_rtx_REG (DImode, TR0_REG);
6257       rtx dipic = operands[0];
6258       rtx lab = PATTERN (gen_call_site ());
6259       rtx insn, equiv;
6260
6261       equiv = operands[1];
6262       operands[1] = gen_rtx_MINUS (DImode,
6263                                    operands[1],
6264                                    gen_rtx_CONST
6265                                    (DImode,
6266                                     gen_rtx_MINUS (DImode,
6267                                                    gen_rtx_CONST (DImode,
6268                                                                   lab),
6269                                                    pc_rtx)));
6270       operands[1] = gen_sym2PIC (operands[1]);
6271       PUT_MODE (operands[1], DImode);
6272
6273       if (GET_MODE (dipic) != DImode)
6274         dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6275
6276       if (TARGET_SHMEDIA64)
6277         emit_insn (gen_movdi_const (dipic, operands[1]));
6278       else
6279         emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6280
6281       emit_insn (gen_ptrel (tr, dipic, lab));
6282
6283       if (GET_MODE (operands[0]) != GET_MODE (tr))
6284         tr = gen_rtx_SUBREG (GET_MODE (operands[0]), tr, 0);
6285
6286       insn = emit_move_insn (operands[0], tr);
6287       
6288       REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6289                                             REG_NOTES (insn));
6290
6291       DONE;
6292     }
6293 }
6294 ")
6295
6296 ;; When generating PIC, we must match label_refs especially, because
6297 ;; they do not satisfy LEGITIMATE_PIC_OPERAND_P(), and we don't want
6298 ;; them to do, because they can't be loaded directly into
6299 ;; non-branch-target registers.
6300 (define_insn "*pt"
6301   [(set (match_operand:DI 0 "target_reg_operand" "=b*k")
6302         (match_operand:DI 1 "" "T"))]
6303   "TARGET_SHMEDIA && flag_pic
6304    && EXTRA_CONSTRAINT_T (operands[1])"
6305   "pt   %1, %0"
6306   [(set_attr "type" "pt")
6307    (set_attr "length" "*")])
6308
6309 (define_insn "*ptb"
6310   [(set (match_operand:DI 0 "target_reg_operand" "=b*k")
6311         (const:DI (unspec:DI [(match_operand:DI 1 "" "T")]
6312                              UNSPEC_DATALABEL)))]
6313   "TARGET_SHMEDIA && flag_pic
6314    && EXTRA_CONSTRAINT_T (operands[1])"
6315   "ptb/u        datalabel %1, %0"
6316   [(set_attr "type" "pt")
6317    (set_attr "length" "*")])
6318
6319 (define_insn "ptrel"
6320   [(set (match_operand:DI 0 "target_reg_operand" "=bk")
6321         (plus (match_operand:DI 1 "register_operand" "r")
6322               (pc)))
6323    (match_operand:DI 2 "" "")]
6324   "TARGET_SHMEDIA"
6325   "%O2: ptrel/u %1, %0"
6326   [(set_attr "type" "ptabs")])
6327
6328 (define_expand "builtin_setjmp_receiver"
6329   [(match_operand 0 "" "")]
6330   "flag_pic"
6331   "
6332 {
6333   emit_insn (gen_GOTaddr2picreg ());
6334   DONE;
6335 }")
6336
6337 (define_expand "call_site"
6338   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
6339   "TARGET_SH1"
6340   "
6341 {
6342   static HOST_WIDE_INT i = 0;
6343   operands[0] = GEN_INT (i);
6344   i++;
6345 }")
6346
6347 (define_expand "sym_label2reg"
6348   [(set (match_operand:SI 0 "" "")
6349         (const:SI (minus:SI
6350                    (const:SI
6351                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6352                    (const:SI
6353                     (plus:SI
6354                      (match_operand:SI 2 "" "")
6355                      (const_int 2))))))]
6356   "TARGET_SH1" "")
6357
6358 (define_expand "symGOT_load"
6359   [(set (match_dup 2) (match_operand 1 "" ""))
6360    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6361    (set (match_operand 0 "" "") (mem (match_dup 3)))]
6362   ""
6363   "
6364 {
6365   rtx insn;
6366
6367   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6368   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6369
6370   if (TARGET_SHMEDIA)
6371     {
6372       rtx reg = operands[2];
6373       
6374       if (GET_MODE (reg) != DImode)
6375         reg = gen_rtx_SUBREG (DImode, reg, 0);
6376       
6377       if (flag_pic > 1)
6378         emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6379       else
6380         emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6381     }
6382   else
6383     emit_move_insn (operands[2], operands[1]);
6384
6385   emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6386                                              operands[2],
6387                                              gen_rtx_REG (Pmode, PIC_REG)));
6388
6389   insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6390
6391   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6392                                                                   0), 0, 0),
6393                                         REG_NOTES (insn));
6394   
6395   DONE;
6396 }")
6397
6398 (define_expand "sym2GOT"
6399   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6400   ""
6401   "")
6402
6403 (define_expand "symGOT2reg"
6404   [(match_operand 0 "" "") (match_operand 1 "" "")]
6405   ""
6406   "
6407 {
6408   rtx gotsym, insn;
6409
6410   gotsym = gen_sym2GOT (operands[1]);
6411   PUT_MODE (gotsym, Pmode);
6412   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6413
6414   RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
6415
6416   DONE;
6417 }")
6418
6419 (define_expand "sym2GOTPLT"
6420   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6421   ""
6422   "")
6423
6424 (define_expand "symGOTPLT2reg"
6425   [(match_operand 0 "" "") (match_operand 1 "" "")]
6426   ""
6427   "
6428 {
6429   emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6430   DONE;
6431 }")
6432
6433 (define_expand "sym2GOTOFF"
6434   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6435   ""
6436   "")
6437
6438 (define_expand "symGOTOFF2reg"
6439   [(match_operand 0 "" "") (match_operand 1 "" "")]
6440   ""
6441   "
6442 {
6443   rtx gotoffsym, insn;
6444   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6445
6446   gotoffsym = gen_sym2GOTOFF (operands[1]);
6447   PUT_MODE (gotoffsym, Pmode);
6448   emit_move_insn (t, gotoffsym);
6449   insn = emit_move_insn (operands[0],
6450                          gen_rtx_PLUS (Pmode, t,
6451                                        gen_rtx_REG (Pmode, PIC_REG)));
6452
6453   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6454                                         REG_NOTES (insn));
6455
6456   DONE;
6457 }")
6458
6459 (define_expand "symPLT_label2reg"
6460   [(set (match_operand:SI 0 "" "")
6461         (const:SI (minus:SI
6462                    (const:SI
6463                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6464                    (const:SI
6465                     (minus:SI
6466                      (const:SI (plus:SI
6467                                 (match_operand:SI 2 "" "")
6468                                 (const_int 2)))
6469                      (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6470    ;; Even though the PIC register is not really used by the call
6471    ;; sequence in which this is expanded, the PLT code assumes the PIC
6472    ;; register is set, so we must not skip its initialization.  Since
6473    ;; we only use this expand as part of calling sequences, and never
6474    ;; to take the address of a function, this is the best point to
6475    ;; insert the (use).  Using the PLT to take the address of a
6476    ;; function would be wrong, not only because the PLT entry could
6477    ;; then be called from a function that doesn't initialize the PIC
6478    ;; register to the proper GOT, but also because pointers to the
6479    ;; same function might not compare equal, should they be set by
6480    ;; different shared libraries.
6481    (use (reg:SI PIC_REG))]
6482   "TARGET_SH1"
6483   "")
6484
6485 (define_expand "sym2PIC"
6486   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6487   ""
6488   "")
6489
6490 ;; case instruction for switch statements.
6491
6492 ;; Operand 0 is index
6493 ;; operand 1 is the minimum bound
6494 ;; operand 2 is the maximum bound - minimum bound + 1
6495 ;; operand 3 is CODE_LABEL for the table;
6496 ;; operand 4 is the CODE_LABEL to go to if index out of range.
6497
6498 (define_expand "casesi"
6499   [(match_operand:SI 0 "arith_reg_operand" "")
6500    (match_operand:SI 1 "arith_reg_operand" "")
6501    (match_operand:SI 2 "arith_reg_operand" "")
6502    (match_operand 3 "" "") (match_operand 4 "" "")]
6503   ""
6504   "
6505 {
6506   rtx reg = gen_reg_rtx (SImode);
6507   rtx reg2 = gen_reg_rtx (SImode);
6508   if (TARGET_SHMEDIA)
6509     {
6510       rtx reg = gen_reg_rtx (DImode);
6511       rtx reg2 = gen_reg_rtx (DImode);
6512       rtx reg3 = gen_reg_rtx (DImode);
6513       rtx reg4 = gen_reg_rtx (DImode);
6514       rtx reg5 = gen_reg_rtx (DImode);
6515
6516       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
6517       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
6518       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
6519
6520       emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
6521       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
6522       emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
6523       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
6524       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
6525                                                (DImode, operands[3])));
6526       emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
6527       emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
6528       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
6529       emit_barrier ();
6530       DONE;
6531     }
6532   operands[1] = copy_to_mode_reg (SImode, operands[1]);
6533   operands[2] = copy_to_mode_reg (SImode, operands[2]);
6534   /* If optimizing, casesi_worker depends on the mode of the instruction
6535      before label it 'uses' - operands[3].  */
6536   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
6537                            reg));
6538   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
6539   if (TARGET_SH2)
6540     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
6541   else
6542     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
6543   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
6544      operands[3], but to lab.  We will fix this up in
6545      machine_dependent_reorg.  */
6546   emit_barrier ();
6547   DONE;
6548 }")
6549
6550 (define_expand "casesi_0"
6551   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
6552    (set (match_dup 4) (minus:SI (match_dup 4)
6553                                 (match_operand:SI 1 "arith_operand" "")))
6554    (set (reg:SI T_REG)
6555         (gtu:SI (match_dup 4)
6556                 (match_operand:SI 2 "arith_reg_operand" "")))
6557    (set (pc)
6558         (if_then_else (ne (reg:SI T_REG)
6559                           (const_int 0))
6560                       (label_ref (match_operand 3 "" ""))
6561                       (pc)))]
6562   "TARGET_SH1"
6563   "")
6564
6565 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
6566 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
6567 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
6568
6569 (define_insn "casesi_worker_0"
6570   [(set (match_operand:SI 0 "register_operand" "=r,r")
6571         (unspec:SI [(match_operand 1 "register_operand" "0,r")
6572                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6573    (clobber (match_scratch:SI 3 "=X,1"))
6574    (clobber (match_scratch:SI 4 "=&z,z"))]
6575   "TARGET_SH1"
6576   "#")
6577
6578 (define_split
6579   [(set (match_operand:SI 0 "register_operand" "")
6580         (unspec [(match_operand 1 "register_operand" "")
6581                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6582    (clobber (match_scratch:SI 3 ""))
6583    (clobber (match_scratch:SI 4 ""))]
6584   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
6585   [(set (reg:SI R0_REG) (unspec [(label_ref (match_dup 2))] UNSPEC_MOVA))
6586    (parallel [(set (match_dup 0)
6587               (unspec [(reg:SI R0_REG) (match_dup 1)
6588                        (label_ref (match_dup 2))] UNSPEC_CASESI))
6589               (clobber (match_dup 3))])
6590    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6591   "LABEL_NUSES (operands[2])++;")
6592
6593 (define_split
6594   [(set (match_operand:SI 0 "register_operand" "")
6595         (unspec:SI [(match_operand 1 "register_operand" "")
6596                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6597    (clobber (match_scratch:SI 3 ""))
6598    (clobber (match_scratch:SI 4 ""))]
6599   "TARGET_SH2 && reload_completed"
6600   [(set (reg:SI R0_REG) (unspec [(label_ref (match_dup 2))] UNSPEC_MOVA))
6601    (parallel [(set (match_dup 0)
6602               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
6603                        (label_ref (match_dup 2))] UNSPEC_CASESI))
6604               (clobber (match_dup 3))])]
6605   "LABEL_NUSES (operands[2])++;")
6606
6607 (define_insn "*casesi_worker"
6608   [(set (match_operand:SI 0 "register_operand" "=r,r")
6609         (unspec [(reg:SI R0_REG) (match_operand 1 "register_operand" "0,r")
6610                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6611    (clobber (match_scratch:SI 3 "=X,1"))]
6612   "TARGET_SH1"
6613   "*
6614 {
6615   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
6616
6617   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6618     abort ();
6619
6620   switch (GET_MODE (diff_vec))
6621     {
6622     case SImode:
6623       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
6624     case HImode:
6625       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
6626     case QImode:
6627       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
6628         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
6629       return \"mov.b    @(r0,%1),%0\";
6630     default:
6631       abort ();
6632     }
6633 }"
6634   [(set_attr "length" "4")])
6635
6636 (define_insn "casesi_shift_media"
6637   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
6638         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
6639                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
6640                     UNSPEC_CASESI)))]
6641   "TARGET_SHMEDIA"
6642   "*
6643 {
6644   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
6645
6646   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6647     abort ();
6648
6649   switch (GET_MODE (diff_vec))
6650     {
6651     case SImode:
6652       return \"shlli    %1, 2, %0\";
6653     case HImode:
6654       return \"shlli    %1, 1, %0\";
6655     case QImode:
6656       if (rtx_equal_p (operands[0], operands[1]))
6657         return \"\";
6658       return \"add      %1, r63, %0\";
6659     default:
6660       abort ();
6661     }
6662 }")
6663
6664 (define_insn "casesi_load_media"
6665   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
6666         (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
6667                          (match_operand 2 "arith_reg_operand" "r")
6668                          (label_ref:DI (match_operand 3 "" ""))] 2)))]
6669   "TARGET_SHMEDIA"
6670   "*
6671 {
6672   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
6673
6674   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6675     abort ();
6676
6677   switch (GET_MODE (diff_vec))
6678     {
6679     case SImode:
6680       return \"ldx.l    %1, %2, %0\";
6681     case HImode:
6682 #if 0
6683       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
6684         return \"ldx.uw %1, %2, %0\";
6685 #endif
6686       return \"ldx.w    %1, %2, %0\";
6687     case QImode:
6688       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
6689         return \"ldx.ub %1, %2, %0\";
6690       return \"ldx.b    %1, %2, %0\";
6691     default:
6692       abort ();
6693     }
6694 }")
6695
6696 (define_expand "return"
6697   [(return)]
6698   "reload_completed && ! sh_need_epilogue ()"
6699   "
6700 {
6701   if (TARGET_SHMEDIA)
6702     {
6703       emit_jump_insn (gen_return_media ());
6704       DONE;
6705     }
6706
6707   if (TARGET_SHCOMPACT
6708       && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
6709     {
6710       emit_jump_insn (gen_shcompact_return_tramp ());
6711       DONE;
6712     }
6713 }")
6714
6715 (define_insn "*return_i"
6716   [(return)]
6717   "TARGET_SH1 && ! (TARGET_SHCOMPACT
6718                     && (current_function_args_info.call_cookie
6719                         & CALL_COOKIE_RET_TRAMP (1)))
6720    && reload_completed"
6721   "%@   %#"
6722   [(set_attr "type" "return")
6723    (set_attr "needs_delay_slot" "yes")])
6724
6725 (define_expand "shcompact_return_tramp"
6726   [(return)]
6727   "TARGET_SHCOMPACT
6728    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
6729   "
6730 {
6731   rtx reg = gen_rtx_REG (Pmode, R0_REG);
6732   rtx sym = gen_rtx_SYMBOL_REF (Pmode,
6733                                 \"__GCC_shcompact_return_trampoline\");
6734
6735   if (flag_pic)
6736     emit_insn (gen_symGOTPLT2reg (reg, sym));
6737   else
6738     emit_move_insn (reg, sym);
6739
6740   emit_jump_insn (gen_shcompact_return_tramp_i ());
6741   DONE;
6742 }")
6743
6744 (define_insn "shcompact_return_tramp_i"
6745   [(parallel [(return) (use (reg:SI R0_REG))])]
6746   "TARGET_SHCOMPACT
6747    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
6748   "jmp  @r0%#"
6749   [(set_attr "type" "jump_ind")
6750    (set_attr "needs_delay_slot" "yes")])
6751
6752 (define_insn "return_media_i"
6753   [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
6754   "TARGET_SHMEDIA && reload_completed"
6755   "blink        %0, r63")
6756
6757 (define_expand "return_media"
6758   [(return)]
6759   "TARGET_SHMEDIA && reload_completed"
6760   "
6761 {
6762   int tr_regno = sh_media_register_for_return ();
6763   rtx tr;
6764
6765   if (tr_regno < 0)
6766     {
6767       rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
6768
6769       tr_regno = TR0_REG;
6770       tr = gen_rtx_REG (DImode, tr_regno);
6771       emit_move_insn (tr, r18);
6772     }
6773   else
6774     tr = gen_rtx_REG (DImode, tr_regno);
6775
6776   emit_jump_insn (gen_return_media_i (tr));
6777   DONE;
6778 }")
6779
6780 (define_insn "shcompact_preserve_incoming_args"
6781   [(set (match_operand 0 "register_operand" "+r")
6782         (unspec [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
6783   "TARGET_SHCOMPACT"
6784   ""
6785   [(set_attr "length" "0")])
6786
6787 (define_insn "shcompact_incoming_args"
6788   [(set (reg:SI R2_REG) (unspec [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
6789    (set (reg:SI R3_REG) (unspec [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
6790    (set (reg:SI R4_REG) (unspec [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
6791    (set (reg:SI R5_REG) (unspec [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
6792    (set (reg:SI R6_REG) (unspec [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
6793    (set (reg:SI R7_REG) (unspec [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
6794    (set (reg:SI R8_REG) (unspec [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
6795    (set (reg:SI R9_REG) (unspec [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
6796    (set (mem:BLK (reg:SI MACL_REG))
6797         (unspec [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
6798    (use (reg:SI R0_REG))
6799    (clobber (reg:SI R0_REG))
6800    (clobber (reg:SI MACL_REG))
6801    (clobber (reg:SI MACH_REG))
6802    (clobber (reg:SI PR_REG))]
6803   "TARGET_SHCOMPACT"
6804   "jsr  @r0%#"
6805   [(set_attr "needs_delay_slot" "yes")])
6806
6807 (define_insn "shmedia_save_restore_regs_compact"
6808   [(set (reg:SI SP_REG)
6809         (plus:SI (reg:SI SP_REG)
6810                  (match_operand:SI 0 "immediate_operand" "i")))
6811    (use (reg:SI R0_REG))
6812    (clobber (reg:SI PR_REG))]
6813   "TARGET_SHCOMPACT
6814    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
6815        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
6816   "jsr @r0%#"
6817   [(set_attr "needs_delay_slot" "yes")])
6818
6819 (define_expand "prologue"
6820   [(const_int 0)]
6821   ""
6822   "sh_expand_prologue (); DONE;")
6823
6824 (define_expand "epilogue"
6825   [(return)]
6826   ""
6827   "
6828 {
6829   sh_expand_epilogue ();
6830   emit_jump_insn (gen_return ());
6831   DONE;
6832 }")
6833
6834 (define_insn "blockage"
6835   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6836   ""
6837   ""
6838   [(set_attr "length" "0")])
6839 \f
6840 ;; ------------------------------------------------------------------------
6841 ;; Scc instructions
6842 ;; ------------------------------------------------------------------------
6843
6844 (define_insn "movt"
6845   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
6846         (eq:SI (reg:SI T_REG) (const_int 1)))]
6847   "TARGET_SH1"
6848   "movt %0"
6849   [(set_attr "type" "arith")])
6850
6851 (define_expand "seq"
6852   [(set (match_operand:SI 0 "arith_reg_operand" "")
6853         (match_dup 1))]
6854   ""
6855   "
6856 {
6857   if (TARGET_SHMEDIA)
6858     {
6859       if (GET_MODE (operands[0]) != DImode)
6860         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6861       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
6862       if (sh_compare_op1 != const0_rtx)
6863         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
6864                                     ? GET_MODE (sh_compare_op0)
6865                                     : GET_MODE (sh_compare_op1),
6866                                     sh_compare_op1);
6867
6868       switch (GET_MODE (sh_compare_op0))
6869         {
6870         case DImode:
6871           emit_insn (gen_cmpeqdi_media (operands[0],
6872                                         sh_compare_op0, sh_compare_op1));
6873           break;
6874
6875         case SFmode:
6876           if (! TARGET_SHMEDIA_FPU)
6877             FAIL;
6878           emit_insn (gen_cmpeqsf_media (operands[0],
6879                                         sh_compare_op0, sh_compare_op1));
6880           break;
6881
6882         case DFmode:
6883           if (! TARGET_SHMEDIA_FPU)
6884             FAIL;
6885           emit_insn (gen_cmpeqdf_media (operands[0],
6886                                         sh_compare_op0, sh_compare_op1));
6887           break;
6888
6889         default:
6890           FAIL;
6891         }
6892       DONE;
6893     }
6894   operands[1] = prepare_scc_operands (EQ);
6895 }")
6896
6897 (define_expand "slt"
6898   [(set (match_operand:SI 0 "arith_reg_operand" "")
6899         (match_dup 1))]
6900   ""
6901   "
6902 {
6903   if (TARGET_SHMEDIA)
6904     {
6905       if (GET_MODE (operands[0]) != DImode)
6906         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6907       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
6908       if (sh_compare_op1 != const0_rtx)
6909         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
6910                                     ? GET_MODE (sh_compare_op0)
6911                                     : GET_MODE (sh_compare_op1),
6912                                     sh_compare_op1);
6913
6914       switch (GET_MODE (sh_compare_op0))
6915         {
6916         case DImode:
6917           emit_insn (gen_cmpgtdi_media (operands[0],
6918                                         sh_compare_op1, sh_compare_op0));
6919           break;
6920
6921         case SFmode:
6922           if (! TARGET_SHMEDIA_FPU)
6923             FAIL;
6924           emit_insn (gen_cmpgtsf_media (operands[0],
6925                                         sh_compare_op1, sh_compare_op0));
6926           break;
6927
6928         case DFmode:
6929           if (! TARGET_SHMEDIA_FPU)
6930             FAIL;
6931           emit_insn (gen_cmpgtdf_media (operands[0],
6932                                         sh_compare_op1, sh_compare_op0));
6933           break;
6934
6935         default:
6936           FAIL;
6937         }
6938       DONE;
6939     }
6940   operands[1] = prepare_scc_operands (LT);
6941 }")
6942
6943 (define_expand "sle"
6944   [(match_operand:SI 0 "arith_reg_operand" "")]
6945   ""
6946   "
6947 {
6948   rtx tmp = sh_compare_op0;
6949
6950   if (TARGET_SHMEDIA)
6951     {
6952       if (GET_MODE (operands[0]) != DImode)
6953         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6954       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
6955       if (sh_compare_op1 != const0_rtx)
6956         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
6957                                     ? GET_MODE (sh_compare_op0)
6958                                     : GET_MODE (sh_compare_op1),
6959                                     sh_compare_op1);
6960
6961       switch (GET_MODE (sh_compare_op0))
6962         {
6963         case DImode:
6964           {
6965             tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
6966
6967             emit_insn (gen_cmpgtdi_media (tmp,
6968                                           sh_compare_op0, sh_compare_op1));
6969             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
6970             break;
6971           }
6972
6973         case SFmode:
6974           if (! TARGET_SHMEDIA_FPU)
6975             FAIL;
6976           emit_insn (gen_cmpgesf_media (operands[0],
6977                                         sh_compare_op1, sh_compare_op0));
6978           break;
6979
6980         case DFmode:
6981           if (! TARGET_SHMEDIA_FPU)
6982             FAIL;
6983           emit_insn (gen_cmpgedf_media (operands[0],
6984                                         sh_compare_op1, sh_compare_op0));
6985           break;
6986
6987         default:
6988           FAIL;
6989         }
6990       DONE;
6991     }
6992
6993   sh_compare_op0 = sh_compare_op1;
6994   sh_compare_op1 = tmp;
6995   emit_insn (gen_sge (operands[0]));
6996   DONE;
6997 }")
6998
6999 (define_expand "sgt"
7000   [(set (match_operand:SI 0 "arith_reg_operand" "")
7001         (match_dup 1))]
7002   ""
7003   "
7004 {
7005   if (TARGET_SHMEDIA)
7006     {
7007       if (GET_MODE (operands[0]) != DImode)
7008         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7009       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7010       if (sh_compare_op1 != const0_rtx)
7011         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7012                                     ? GET_MODE (sh_compare_op0)
7013                                     : GET_MODE (sh_compare_op1),
7014                                     sh_compare_op1);
7015
7016       switch (GET_MODE (sh_compare_op0))
7017         {
7018         case DImode:
7019           emit_insn (gen_cmpgtdi_media (operands[0],
7020                                         sh_compare_op0, sh_compare_op1));
7021           break;
7022
7023         case SFmode:
7024           if (! TARGET_SHMEDIA_FPU)
7025             FAIL;
7026           emit_insn (gen_cmpgtsf_media (operands[0],
7027                                         sh_compare_op0, sh_compare_op1));
7028           break;
7029
7030         case DFmode:
7031           if (! TARGET_SHMEDIA_FPU)
7032             FAIL;
7033           emit_insn (gen_cmpgtdf_media (operands[0],
7034                                         sh_compare_op0, sh_compare_op1));
7035           break;
7036
7037         default:
7038           FAIL;
7039         }
7040       DONE;
7041     }
7042   operands[1] = prepare_scc_operands (GT);
7043 }")
7044
7045 (define_expand "sge"
7046   [(set (match_operand:SI 0 "arith_reg_operand" "")
7047         (match_dup 1))]
7048   ""
7049   "
7050 {
7051   if (TARGET_SHMEDIA)
7052     {
7053       if (GET_MODE (operands[0]) != DImode)
7054         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7055       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7056       if (sh_compare_op1 != const0_rtx)
7057         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7058                                     ? GET_MODE (sh_compare_op0)
7059                                     : GET_MODE (sh_compare_op1),
7060                                     sh_compare_op1);
7061
7062       switch (GET_MODE (sh_compare_op0))
7063         {
7064         case DImode:
7065           {
7066             rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7067
7068             emit_insn (gen_cmpgtdi_media (tmp,
7069                                           sh_compare_op1, sh_compare_op0));
7070             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7071             break;
7072           }
7073
7074         case SFmode:
7075           if (! TARGET_SHMEDIA_FPU)
7076             FAIL;
7077           emit_insn (gen_cmpgesf_media (operands[0],
7078                                         sh_compare_op0, sh_compare_op1));
7079           break;
7080
7081         case DFmode:
7082           if (! TARGET_SHMEDIA_FPU)
7083             FAIL;
7084           emit_insn (gen_cmpgedf_media (operands[0],
7085                                         sh_compare_op0, sh_compare_op1));
7086           break;
7087
7088         default:
7089           FAIL;
7090         }
7091       DONE;
7092     }
7093
7094   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7095     {
7096       if (TARGET_IEEE)
7097         {
7098           rtx lab = gen_label_rtx ();
7099           prepare_scc_operands (EQ);
7100           emit_jump_insn (gen_branch_true (lab));
7101           prepare_scc_operands (GT);
7102           emit_label (lab);
7103           emit_insn (gen_movt (operands[0]));
7104         }
7105       else
7106         emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
7107       DONE;
7108     }
7109   operands[1] = prepare_scc_operands (GE);
7110 }")
7111
7112 (define_expand "sgtu"
7113   [(set (match_operand:SI 0 "arith_reg_operand" "")
7114         (match_dup 1))]
7115   ""
7116   "
7117 {
7118   if (TARGET_SHMEDIA)
7119     {
7120       if (GET_MODE (operands[0]) != DImode)
7121         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7122       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7123       if (sh_compare_op1 != const0_rtx)
7124         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7125                                     ? GET_MODE (sh_compare_op0)
7126                                     : GET_MODE (sh_compare_op1),
7127                                     sh_compare_op1);
7128
7129       emit_insn (gen_cmpgtudi_media (operands[0],
7130                                      sh_compare_op0, sh_compare_op1));
7131       DONE;
7132     }
7133   operands[1] = prepare_scc_operands (GTU);
7134 }")
7135
7136 (define_expand "sltu"
7137   [(set (match_operand:SI 0 "arith_reg_operand" "")
7138         (match_dup 1))]
7139   ""
7140   "
7141 {
7142   if (TARGET_SHMEDIA)
7143     {
7144       if (GET_MODE (operands[0]) != DImode)
7145         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7146       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7147       if (sh_compare_op1 != const0_rtx)
7148         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7149                                     ? GET_MODE (sh_compare_op0)
7150                                     : GET_MODE (sh_compare_op1),
7151                                     sh_compare_op1);
7152
7153       emit_insn (gen_cmpgtudi_media (operands[0],
7154                                      sh_compare_op1, sh_compare_op0));
7155       DONE;
7156     }
7157   operands[1] = prepare_scc_operands (LTU);
7158 }")
7159
7160 (define_expand "sleu"
7161   [(set (match_operand:SI 0 "arith_reg_operand" "")
7162         (match_dup 1))]
7163   ""
7164   "
7165 {
7166   if (TARGET_SHMEDIA)
7167     {
7168       rtx tmp;
7169
7170       if (GET_MODE (operands[0]) != DImode)
7171         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7172       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7173       if (sh_compare_op1 != const0_rtx)
7174         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7175                                     ? GET_MODE (sh_compare_op0)
7176                                     : GET_MODE (sh_compare_op1),
7177                                     sh_compare_op1);
7178
7179       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7180
7181       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7182       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7183
7184       DONE;
7185     }
7186   operands[1] = prepare_scc_operands (LEU);
7187 }")
7188
7189 (define_expand "sgeu"
7190   [(set (match_operand:SI 0 "arith_reg_operand" "")
7191         (match_dup 1))]
7192   ""
7193   "
7194 {
7195   if (TARGET_SHMEDIA)
7196     {
7197       rtx tmp;
7198
7199       if (GET_MODE (operands[0]) != DImode)
7200         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7201       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7202       if (sh_compare_op1 != const0_rtx)
7203         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7204                                     ? GET_MODE (sh_compare_op0)
7205                                     : GET_MODE (sh_compare_op1),
7206                                     sh_compare_op1);
7207
7208       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7209
7210       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7211       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7212
7213       DONE;
7214     }
7215
7216   operands[1] = prepare_scc_operands (GEU);
7217 }")
7218
7219 ;; sne moves the complement of the T reg to DEST like this:
7220 ;;      cmp/eq ...
7221 ;;      mov    #-1,temp
7222 ;;      negc   temp,dest
7223 ;;   This is better than xoring compare result with 1 because it does
7224 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
7225 ;;   loop.
7226
7227 (define_expand "sne"
7228   [(set (match_dup 2) (const_int -1))
7229    (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7230                    (neg:SI (plus:SI (match_dup 1)
7231                                     (match_dup 2))))
7232               (set (reg:SI T_REG)
7233                    (ne:SI (ior:SI (match_dup 1) (match_dup 2))
7234                           (const_int 0)))])]  
7235   ""
7236   "
7237 {
7238   if (TARGET_SHMEDIA)
7239     {
7240       rtx tmp;
7241
7242       if (GET_MODE (operands[0]) != DImode)
7243         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7244
7245       if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7246         FAIL;
7247
7248       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7249       if (sh_compare_op1 != const0_rtx)
7250         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7251                                     ? GET_MODE (sh_compare_op0)
7252                                     : GET_MODE (sh_compare_op1),
7253                                     sh_compare_op1);
7254
7255       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7256
7257       emit_insn (gen_seq (tmp));
7258       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7259
7260       DONE;
7261     }
7262
7263    operands[1] = prepare_scc_operands (EQ);
7264    operands[2] = gen_reg_rtx (SImode);
7265 }")
7266
7267 (define_expand "sunordered"
7268   [(set (match_operand:DI 0 "arith_reg_operand" "")
7269         (unordered:DI (match_dup 1) (match_dup 2)))]
7270   "TARGET_SHMEDIA_FPU"
7271   "
7272 {
7273   operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7274   operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7275 }")
7276
7277 ;; Use the same trick for FP sle / sge
7278 (define_expand "movnegt"
7279   [(set (match_dup 2) (const_int -1))
7280    (parallel [(set (match_operand 0 "" "")
7281                    (neg:SI (plus:SI (match_dup 1)
7282                                     (match_dup 2))))
7283               (set (reg:SI T_REG)
7284                    (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
7285                           (const_int 0)))])]  
7286   "TARGET_SH1"
7287   "operands[2] = gen_reg_rtx (SImode);")
7288
7289 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
7290 ;; This prevents a regression that occurred when we switched from xor to
7291 ;; mov/neg for sne.
7292
7293 (define_split
7294   [(set (match_operand:SI 0 "arith_reg_operand" "")
7295         (plus:SI (reg:SI T_REG)
7296                  (const_int -1)))]
7297   "TARGET_SH1"
7298   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
7299    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7300   "")
7301
7302 ;; -------------------------------------------------------------------------
7303 ;; Instructions to cope with inline literal tables
7304 ;; -------------------------------------------------------------------------
7305
7306 ; 2 byte integer in line
7307
7308 (define_insn "consttable_2"
7309  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7310                     (match_operand 1 "" "")]
7311                    UNSPECV_CONST2)]
7312  ""
7313  "*
7314 {
7315   if (operands[1] != const0_rtx)
7316     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
7317   return \"\";
7318 }"
7319  [(set_attr "length" "2")
7320  (set_attr "in_delay_slot" "no")])
7321
7322 ; 4 byte integer in line
7323
7324 (define_insn "consttable_4"
7325  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7326                     (match_operand 1 "" "")]
7327                    UNSPECV_CONST4)]
7328  ""
7329  "*
7330 {
7331   if (operands[1] != const0_rtx)
7332     assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
7333   return \"\";
7334 }"
7335  [(set_attr "length" "4")
7336   (set_attr "in_delay_slot" "no")])
7337
7338 ; 8 byte integer in line
7339
7340 (define_insn "consttable_8"
7341  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7342                     (match_operand 1 "" "")]
7343                    UNSPECV_CONST8)]
7344  ""
7345  "*
7346 {
7347   if (operands[1] != const0_rtx)
7348     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
7349   return \"\";
7350 }"
7351  [(set_attr "length" "8")
7352   (set_attr "in_delay_slot" "no")])
7353
7354 ; 4 byte floating point
7355
7356 (define_insn "consttable_sf"
7357  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7358                     (match_operand 1 "" "")]
7359                    UNSPECV_CONST4)]
7360  ""
7361  "*
7362 {
7363   if (operands[1] != const0_rtx)
7364     {
7365       REAL_VALUE_TYPE d;
7366       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7367       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
7368     }
7369   return \"\";
7370 }"
7371  [(set_attr "length" "4")
7372   (set_attr "in_delay_slot" "no")])
7373
7374 ; 8 byte floating point
7375
7376 (define_insn "consttable_df"
7377  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
7378                     (match_operand 1 "" "")]
7379                    UNSPECV_CONST8)]
7380  ""
7381  "*
7382 {
7383   if (operands[1] != const0_rtx)
7384     {
7385       REAL_VALUE_TYPE d;
7386       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7387       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
7388     }
7389   return \"\";
7390 }"
7391  [(set_attr "length" "8")
7392   (set_attr "in_delay_slot" "no")])
7393
7394 ;; Alignment is needed for some constant tables; it may also be added for
7395 ;; Instructions at the start of loops, or after unconditional branches.
7396 ;; ??? We would get more accurate lengths if we did instruction
7397 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
7398 ;; here is too conservative.
7399
7400 ; align to a two byte boundary
7401
7402 (define_expand "align_2"
7403  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
7404  ""
7405  "")
7406
7407 ; align to a four byte boundary
7408 ;; align_4 and align_log are instructions for the starts of loops, or
7409 ;; after unconditional branches, which may take up extra room.
7410
7411 (define_expand "align_4"
7412  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
7413  ""
7414  "")
7415
7416 ; align to a cache line boundary
7417
7418 (define_insn "align_log"
7419  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
7420  ""
7421  ""
7422  [(set_attr "length" "0")
7423   (set_attr "in_delay_slot" "no")])
7424
7425 ; emitted at the end of the literal table, used to emit the
7426 ; 32bit branch labels if needed.
7427
7428 (define_insn "consttable_end"
7429   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
7430   ""
7431   "* return output_jump_label_table ();"
7432   [(set_attr "in_delay_slot" "no")])
7433
7434 ; emitted at the end of the window in the literal table.
7435
7436 (define_insn "consttable_window_end"
7437   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
7438   ""
7439   ""
7440   [(set_attr "length" "0")
7441    (set_attr "in_delay_slot" "no")])
7442
7443 ;; -------------------------------------------------------------------------
7444 ;; Misc
7445 ;; -------------------------------------------------------------------------
7446
7447 ;; String/block move insn.
7448
7449 (define_expand "movstrsi"
7450   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
7451                    (mem:BLK (match_operand:BLK 1 "" "")))
7452               (use (match_operand:SI 2 "nonmemory_operand" ""))
7453               (use (match_operand:SI 3 "immediate_operand" ""))
7454               (clobber (reg:SI PR_REG))
7455               (clobber (reg:SI R4_REG))
7456               (clobber (reg:SI R5_REG))
7457               (clobber (reg:SI R0_REG))])]
7458   "TARGET_SH1 && ! TARGET_SH5"
7459   "
7460 {
7461   if(expand_block_move (operands))
7462      DONE;
7463   else FAIL;
7464 }")
7465
7466 (define_insn "block_move_real"
7467   [(parallel [(set (mem:BLK (reg:SI R4_REG))
7468                    (mem:BLK (reg:SI R5_REG)))
7469               (use (match_operand:SI 0 "arith_reg_operand" "r"))
7470               (clobber (reg:SI PR_REG))
7471               (clobber (reg:SI R0_REG))])]
7472   "TARGET_SH1 && ! TARGET_HARD_SH4"
7473   "jsr  @%0%#"
7474   [(set_attr "type" "sfunc")
7475    (set_attr "needs_delay_slot" "yes")])
7476
7477 (define_insn "block_lump_real"
7478   [(parallel [(set (mem:BLK (reg:SI R4_REG))
7479                    (mem:BLK (reg:SI R5_REG)))
7480               (use (match_operand:SI 0 "arith_reg_operand" "r"))
7481               (use (reg:SI R6_REG))
7482               (clobber (reg:SI PR_REG))
7483               (clobber (reg:SI T_REG))
7484               (clobber (reg:SI R4_REG))
7485               (clobber (reg:SI R5_REG))
7486               (clobber (reg:SI R6_REG))
7487               (clobber (reg:SI R0_REG))])]
7488   "TARGET_SH1 && ! TARGET_HARD_SH4"
7489   "jsr  @%0%#"
7490   [(set_attr "type" "sfunc")
7491    (set_attr "needs_delay_slot" "yes")])
7492
7493 (define_insn "block_move_real_i4"
7494   [(parallel [(set (mem:BLK (reg:SI R4_REG))
7495                    (mem:BLK (reg:SI R5_REG)))
7496               (use (match_operand:SI 0 "arith_reg_operand" "r"))
7497               (clobber (reg:SI PR_REG))
7498               (clobber (reg:SI R0_REG))
7499               (clobber (reg:SI R1_REG))
7500               (clobber (reg:SI R2_REG))])]
7501   "TARGET_HARD_SH4"
7502   "jsr  @%0%#"
7503   [(set_attr "type" "sfunc")
7504    (set_attr "needs_delay_slot" "yes")])
7505
7506 (define_insn "block_lump_real_i4"
7507   [(parallel [(set (mem:BLK (reg:SI R4_REG))
7508                    (mem:BLK (reg:SI R5_REG)))
7509               (use (match_operand:SI 0 "arith_reg_operand" "r"))
7510               (use (reg:SI R6_REG))
7511               (clobber (reg:SI PR_REG))
7512               (clobber (reg:SI T_REG))
7513               (clobber (reg:SI R4_REG))
7514               (clobber (reg:SI R5_REG))
7515               (clobber (reg:SI R6_REG))
7516               (clobber (reg:SI R0_REG))
7517               (clobber (reg:SI R1_REG))
7518               (clobber (reg:SI R2_REG))
7519               (clobber (reg:SI R3_REG))])]
7520   "TARGET_HARD_SH4"
7521   "jsr  @%0%#"
7522   [(set_attr "type" "sfunc")
7523    (set_attr "needs_delay_slot" "yes")])
7524 \f
7525 ;; -------------------------------------------------------------------------
7526 ;; Floating point instructions.
7527 ;; -------------------------------------------------------------------------
7528
7529 ;; ??? All patterns should have a type attribute.
7530
7531 (define_expand "fpu_switch0"
7532   [(set (match_operand:SI 0 "" "") (match_dup 2))
7533    (set (match_dup 1) (mem:PSI (match_dup 0)))]
7534   "TARGET_SH4"
7535   "
7536 {
7537   operands[1] = get_fpscr_rtx ();
7538   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
7539   if (flag_pic)
7540     operands[2] = legitimize_pic_address (operands[2], SImode,
7541                                           no_new_pseudos ? operands[0] : 0);
7542 }")
7543
7544 (define_expand "fpu_switch1"
7545   [(set (match_operand:SI 0 "" "") (match_dup 2))
7546    (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
7547    (set (match_dup 1) (mem:PSI (match_dup 3)))]
7548   "TARGET_SH4"
7549   "
7550 {
7551   operands[1] = get_fpscr_rtx ();
7552   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
7553   if (flag_pic)
7554     operands[2] = legitimize_pic_address (operands[2], SImode,
7555                                           no_new_pseudos ? operands[0] : 0);
7556   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
7557 }")
7558
7559 (define_expand "movpsi"
7560   [(set (match_operand:PSI 0 "register_operand" "")
7561         (match_operand:PSI 1 "general_movsrc_operand" ""))]
7562   "TARGET_SH4"
7563   "")
7564
7565 ;; The c / m alternative is a fake to guide reload to load directly into
7566 ;; fpscr, since reload doesn't know how to use post-increment.
7567 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
7568 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
7569 ;; predicate after reload.
7570 ;; The gp_fpul type for r/!c might look a bit odd, but it actually schedules
7571 ;; like a gpr <-> fpul move.
7572 (define_insn "fpu_switch"
7573   [(set (match_operand:PSI 0 "register_operand" "=c,c,r,c,c,r,m,r")
7574         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c"))]
7575   "TARGET_SH4
7576    && (! reload_completed
7577        || true_regnum (operands[0]) != FPSCR_REG
7578        || GET_CODE (operands[1]) != MEM
7579        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
7580   "@
7581         ! precision stays the same
7582         lds.l   %1,fpscr
7583         mov.l   %1,%0
7584         #
7585         lds     %1,fpscr
7586         mov     %1,%0
7587         mov.l   %1,%0
7588         sts     fpscr,%0"
7589   [(set_attr "length" "0,2,2,4,2,2,2,2")
7590    (set_attr "type" "dfp_conv,dfp_conv,load,dfp_conv,dfp_conv,move,store,gp_fpul")
7591    (set_attr "insn_class" "ldsmem_to_fpscr,*,*,lds_to_fpscr,*,*,*,*")])
7592
7593 (define_split
7594   [(set (reg:PSI FPSCR_REG)
7595         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
7596   "TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
7597   [(set (match_dup 0) (match_dup 0))]
7598   "
7599 {
7600   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
7601                                         gen_rtx (MEM, PSImode,
7602                                                  gen_rtx (POST_INC, Pmode,
7603                                                           operands[0]))));
7604   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
7605 }")
7606
7607 (define_split
7608   [(set (reg:PSI FPSCR_REG)
7609         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
7610   "TARGET_SH4"
7611   [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
7612   "
7613 {
7614   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
7615                                         gen_rtx (MEM, PSImode,
7616                                                  gen_rtx (POST_INC, Pmode,
7617                                                           operands[0]))));
7618   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
7619 }")
7620
7621 ;; ??? This uses the fp unit, but has no type indicating that.
7622 ;; If we did that, this would either give a bogus latency or introduce
7623 ;; a bogus FIFO constraint.
7624 ;; Since this insn is currently only used for prologues/epilogues,
7625 ;; it is probably best to claim no function unit, which matches the
7626 ;; current setting.
7627 (define_insn "toggle_sz"
7628   [(set (reg:PSI FPSCR_REG)
7629         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
7630   "TARGET_SH4"
7631   "fschg")
7632
7633 (define_expand "addsf3"
7634   [(set (match_operand:SF 0 "arith_reg_operand" "")
7635         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
7636                  (match_operand:SF 2 "arith_reg_operand" "")))]
7637   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7638   "
7639 {
7640   if (TARGET_SH3E)
7641     {
7642       expand_sf_binop (&gen_addsf3_i, operands);
7643       DONE;
7644     }
7645 }")
7646
7647 (define_insn "*addsf3_media"
7648   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7649         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
7650                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7651   "TARGET_SHMEDIA_FPU"
7652   "fadd.s       %1, %2, %0")
7653
7654 (define_insn "addsf3_i"
7655   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
7656         (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
7657                  (match_operand:SF 2 "arith_reg_operand" "f")))
7658    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
7659   "TARGET_SH3E"
7660   "fadd %2,%0"
7661   [(set_attr "type" "fp")
7662    (set_attr "fp_mode" "single")])
7663
7664 (define_expand "subsf3"
7665   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
7666         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
7667                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
7668   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7669   "
7670 {
7671   if (TARGET_SH3E)
7672     {
7673       expand_sf_binop (&gen_subsf3_i, operands);
7674       DONE;
7675     }
7676 }")
7677
7678 (define_insn "*subsf3_media"
7679   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7680         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
7681                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7682   "TARGET_SHMEDIA_FPU"
7683   "fsub.s       %1, %2, %0")
7684
7685 (define_insn "subsf3_i"
7686   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7687         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
7688                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
7689    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
7690   "TARGET_SH3E"
7691   "fsub %2,%0"
7692   [(set_attr "type" "fp")
7693    (set_attr "fp_mode" "single")])
7694
7695 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
7696 ;; register in feeding fp instructions.  Thus, we cannot generate fmac for
7697 ;; mixed-precision SH4 targets.  To allow it to be still generated for the
7698 ;; SH3E, we use a separate insn for SH3E mulsf3.
7699
7700 (define_expand "mulsf3"
7701   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
7702         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
7703                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
7704   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7705   "
7706 {
7707   if (TARGET_SH4)
7708     expand_sf_binop (&gen_mulsf3_i4, operands);
7709   else if (TARGET_SH3E)
7710     emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
7711   if (! TARGET_SHMEDIA)
7712     DONE;
7713 }")
7714
7715 (define_insn "*mulsf3_media"
7716   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7717         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
7718                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7719   "TARGET_SHMEDIA_FPU"
7720   "fmul.s       %1, %2, %0")
7721
7722 (define_insn "mulsf3_i4"
7723   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7724         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
7725                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
7726    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
7727   "TARGET_SH3E"
7728   "fmul %2,%0"
7729   [(set_attr "type" "fp")
7730    (set_attr "fp_mode" "single")])
7731
7732 (define_insn "mulsf3_ie"
7733   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7734         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
7735                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7736   "TARGET_SH3E && ! TARGET_SH4"
7737   "fmul %2,%0"
7738   [(set_attr "type" "fp")])
7739
7740 (define_insn "*mac_media"
7741   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7742         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
7743                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
7744                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
7745   "TARGET_SHMEDIA_FPU"
7746   "fmac.s %1, %2, %0")
7747
7748 (define_insn "*macsf3"
7749   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7750         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
7751                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
7752                  (match_operand:SF 3 "arith_reg_operand" "0")))
7753    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
7754   "TARGET_SH3E && ! TARGET_SH4"
7755   "fmac fr0,%2,%0"
7756   [(set_attr "type" "fp")
7757    (set_attr "fp_mode" "single")])
7758
7759 (define_expand "divsf3"
7760   [(set (match_operand:SF 0 "arith_reg_operand" "")
7761         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
7762                 (match_operand:SF 2 "arith_reg_operand" "")))]
7763   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7764   "
7765 {
7766   if (TARGET_SH3E)
7767     {
7768       expand_sf_binop (&gen_divsf3_i, operands);
7769       DONE;
7770     }
7771 }")
7772
7773 (define_insn "*divsf3_media"
7774   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7775         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
7776                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7777   "TARGET_SHMEDIA_FPU"
7778   "fdiv.s       %1, %2, %0")
7779
7780 (define_insn "divsf3_i"
7781   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
7782         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
7783                  (match_operand:SF 2 "arith_reg_operand" "f")))
7784    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
7785   "TARGET_SH3E"
7786   "fdiv %2,%0"
7787   [(set_attr "type" "fdiv")
7788    (set_attr "fp_mode" "single")])
7789
7790 (define_insn "floatdisf2"
7791   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7792         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
7793   "TARGET_SHMEDIA_FPU"
7794   "float.qs %1, %0")
7795
7796 (define_expand "floatsisf2"
7797   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
7798         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
7799   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7800   "
7801 {
7802   if (TARGET_SH4)
7803     {
7804       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
7805       DONE;
7806     }
7807 }")
7808
7809 (define_insn "*floatsisf2_media"
7810   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7811         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
7812   "TARGET_SHMEDIA_FPU"
7813   "float.ls     %1, %0")
7814
7815 (define_insn "floatsisf2_i4"
7816   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7817         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
7818    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
7819   "TARGET_SH4"
7820   "float        %1,%0"
7821   [(set_attr "type" "fp")
7822    (set_attr "fp_mode" "single")])
7823
7824 (define_insn "*floatsisf2_ie"
7825   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7826         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
7827   "TARGET_SH3E && ! TARGET_SH4"
7828   "float        %1,%0"
7829   [(set_attr "type" "fp")])
7830
7831 (define_insn "fix_truncsfdi2"
7832   [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
7833         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
7834   "TARGET_SHMEDIA_FPU"
7835   "ftrc.sq %1, %0")
7836
7837 (define_expand "fix_truncsfsi2"
7838   [(set (match_operand:SI 0 "fpul_operand" "=y")
7839         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
7840   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7841   "
7842 {
7843   if (TARGET_SH4)
7844     {
7845       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
7846       DONE;
7847     }
7848 }")
7849
7850 (define_insn "*fix_truncsfsi2_media"
7851   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
7852         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
7853   "TARGET_SHMEDIA_FPU"
7854   "ftrc.sl      %1, %0")
7855
7856 (define_insn "fix_truncsfsi2_i4"
7857   [(set (match_operand:SI 0 "fpul_operand" "=y")
7858         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
7859    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
7860   "TARGET_SH4"
7861   "ftrc %1,%0"
7862   [(set_attr "type" "fp")
7863    (set_attr "fp_mode" "single")])
7864
7865 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
7866 ;; fix_truncsfsi2_i4.
7867 ;; (define_insn "fix_truncsfsi2_i4_2"
7868 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7869 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
7870 ;;   (use (reg:PSI FPSCR_REG))
7871 ;;   (clobber (reg:SI FPUL_REG))]
7872 ;;  "TARGET_SH4"
7873 ;;  "#"
7874 ;;  [(set_attr "length" "4")
7875 ;;   (set_attr "fp_mode" "single")])
7876
7877 ;;(define_split
7878 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7879 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
7880 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
7881 ;;   (clobber (reg:SI FPUL_REG))]
7882 ;;  "TARGET_SH4"
7883 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
7884 ;;            (use (match_dup 2))])
7885 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
7886
7887 (define_insn "*fixsfsi"
7888   [(set (match_operand:SI 0 "fpul_operand" "=y")
7889         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
7890   "TARGET_SH3E && ! TARGET_SH4"
7891   "ftrc %1,%0"
7892   [(set_attr "type" "fp")])
7893
7894 (define_insn "cmpgtsf_t"
7895   [(set (reg:SI T_REG)
7896         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
7897                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
7898   "TARGET_SH3E && ! TARGET_SH4"
7899   "fcmp/gt      %1,%0"
7900   [(set_attr "type" "fp")
7901    (set_attr "fp_mode" "single")])
7902
7903 (define_insn "cmpeqsf_t"
7904   [(set (reg:SI T_REG)
7905         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
7906                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
7907   "TARGET_SH3E && ! TARGET_SH4"
7908   "fcmp/eq      %1,%0"
7909   [(set_attr "type" "fp")
7910    (set_attr "fp_mode" "single")])
7911
7912 (define_insn "ieee_ccmpeqsf_t"
7913   [(set (reg:SI T_REG)
7914         (ior:SI (reg:SI T_REG)
7915                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
7916                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
7917   "TARGET_SH3E && TARGET_IEEE && ! TARGET_SH4"
7918   "* return output_ieee_ccmpeq (insn, operands);"
7919   [(set_attr "length" "4")])
7920
7921
7922 (define_insn "cmpgtsf_t_i4"
7923   [(set (reg:SI T_REG)
7924         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
7925                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
7926    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
7927   "TARGET_SH4"
7928   "fcmp/gt      %1,%0"
7929   [(set_attr "type" "fp")
7930    (set_attr "fp_mode" "single")])
7931
7932 (define_insn "cmpeqsf_t_i4"
7933   [(set (reg:SI T_REG)
7934         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
7935                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
7936    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
7937   "TARGET_SH4"
7938   "fcmp/eq      %1,%0"
7939   [(set_attr "type" "fp")
7940    (set_attr "fp_mode" "single")])
7941
7942 (define_insn "*ieee_ccmpeqsf_t_4"
7943   [(set (reg:SI T_REG)
7944         (ior:SI (reg:SI T_REG)
7945                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
7946                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
7947    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
7948   "TARGET_IEEE && TARGET_SH4"
7949   "* return output_ieee_ccmpeq (insn, operands);"
7950   [(set_attr "length" "4")
7951    (set_attr "fp_mode" "single")])
7952
7953 (define_insn "cmpeqsf_media"
7954   [(set (match_operand:DI 0 "register_operand" "=r")
7955         (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
7956                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7957   "TARGET_SHMEDIA_FPU"
7958   "fcmpeq.s     %1, %2, %0")
7959
7960 (define_insn "cmpgtsf_media"
7961   [(set (match_operand:DI 0 "register_operand" "=r")
7962         (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
7963                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7964   "TARGET_SHMEDIA_FPU"
7965   "fcmpgt.s     %1, %2, %0")
7966
7967 (define_insn "cmpgesf_media"
7968   [(set (match_operand:DI 0 "register_operand" "=r")
7969         (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
7970                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7971   "TARGET_SHMEDIA_FPU"
7972   "fcmpge.s     %1, %2, %0")
7973
7974 (define_insn "cmpunsf_media"
7975   [(set (match_operand:DI 0 "register_operand" "=r")
7976         (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
7977                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7978   "TARGET_SHMEDIA_FPU"
7979   "fcmpun.s     %1, %2, %0")
7980
7981 (define_expand "cmpsf"
7982   [(set (reg:SI T_REG)
7983         (compare (match_operand:SF 0 "arith_operand" "")
7984                  (match_operand:SF 1 "arith_operand" "")))]
7985   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7986   "
7987 {
7988   sh_compare_op0 = operands[0];
7989   sh_compare_op1 = operands[1];
7990   DONE;
7991 }")
7992
7993 (define_expand "negsf2"
7994   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
7995         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
7996   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7997   "
7998 {
7999   if (TARGET_SH3E)
8000     {
8001       expand_sf_unop (&gen_negsf2_i, operands);
8002       DONE;
8003     }
8004 }")
8005
8006 (define_insn "*negsf2_media"
8007   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8008         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8009   "TARGET_SHMEDIA_FPU"
8010   "fneg.s       %1, %0")
8011
8012 (define_insn "negsf2_i"
8013   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8014         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8015    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8016   "TARGET_SH3E"
8017   "fneg %0"
8018   [(set_attr "type" "fmove")
8019    (set_attr "fp_mode" "single")])
8020
8021 (define_expand "sqrtsf2"
8022   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8023         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8024   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8025   "
8026 {
8027   if (TARGET_SH3E)
8028     {
8029       expand_sf_unop (&gen_sqrtsf2_i, operands);
8030       DONE;
8031     }
8032 }")
8033
8034 (define_insn "*sqrtsf2_media"
8035   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8036         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8037   "TARGET_SHMEDIA_FPU"
8038   "fsqrt.s      %1, %0")
8039
8040 (define_insn "sqrtsf2_i"
8041   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8042         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8043    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8044   "TARGET_SH3E"
8045   "fsqrt        %0"
8046   [(set_attr "type" "fdiv")
8047    (set_attr "fp_mode" "single")])
8048
8049 (define_expand "abssf2"
8050   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8051         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8052   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8053   "
8054 {
8055   if (TARGET_SH3E)
8056     {
8057       expand_sf_unop (&gen_abssf2_i, operands);
8058       DONE;
8059     }
8060 }")
8061
8062 (define_insn "*abssf2_media"
8063   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8064         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8065   "TARGET_SHMEDIA_FPU"
8066   "fabs.s       %1, %0")
8067
8068 (define_insn "abssf2_i"
8069   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8070         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8071    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8072   "TARGET_SH3E"
8073   "fabs %0"
8074   [(set_attr "type" "fmove")
8075    (set_attr "fp_mode" "single")])
8076
8077 (define_expand "adddf3"
8078   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8079         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8080                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8081   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8082   "
8083 {
8084   if (TARGET_SH4)
8085     {
8086       expand_df_binop (&gen_adddf3_i, operands);
8087       DONE;
8088     }
8089 }")
8090
8091 (define_insn "*adddf3_media"
8092   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8093         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8094                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8095   "TARGET_SHMEDIA_FPU"
8096   "fadd.d       %1, %2, %0")
8097
8098 (define_insn "adddf3_i"
8099   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8100         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8101                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8102    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8103   "TARGET_SH4"
8104   "fadd %2,%0"
8105   [(set_attr "type" "dfp_arith")
8106    (set_attr "fp_mode" "double")])
8107
8108 (define_expand "subdf3"
8109   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8110         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8111                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8112   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8113   "
8114 {
8115   if (TARGET_SH4)
8116     {
8117       expand_df_binop (&gen_subdf3_i, operands);
8118       DONE;
8119     }
8120 }")
8121
8122 (define_insn "*subdf3_media"
8123   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8124         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8125                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8126   "TARGET_SHMEDIA_FPU"
8127   "fsub.d       %1, %2, %0")
8128
8129 (define_insn "subdf3_i"
8130   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8131         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8132                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8133    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8134   "TARGET_SH4"
8135   "fsub %2,%0"
8136   [(set_attr "type" "dfp_arith")
8137    (set_attr "fp_mode" "double")])
8138
8139 (define_expand "muldf3"
8140   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8141         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8142                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8143   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8144   "
8145 {
8146   if (TARGET_SH4)
8147     {
8148       expand_df_binop (&gen_muldf3_i, operands);
8149       DONE;
8150     }
8151 }")
8152
8153 (define_insn "*muldf3_media"
8154   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8155         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8156                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8157   "TARGET_SHMEDIA_FPU"
8158   "fmul.d       %1, %2, %0")
8159
8160 (define_insn "muldf3_i"
8161   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8162         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8163                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8164    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8165   "TARGET_SH4"
8166   "fmul %2,%0"
8167   [(set_attr "type" "dfp_arith")
8168    (set_attr "fp_mode" "double")])
8169
8170 (define_expand "divdf3"
8171   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8172         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8173                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8174   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8175   "
8176 {
8177   if (TARGET_SH4)
8178     {
8179       expand_df_binop (&gen_divdf3_i, operands);
8180       DONE;
8181     }
8182 }")
8183
8184 (define_insn "*divdf3_media"
8185   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8186         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8187                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8188   "TARGET_SHMEDIA_FPU"
8189   "fdiv.d       %1, %2, %0")
8190
8191 (define_insn "divdf3_i"
8192   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8193         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8194                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8195    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8196   "TARGET_SH4"
8197   "fdiv %2,%0"
8198   [(set_attr "type" "dfdiv")
8199    (set_attr "fp_mode" "double")])
8200
8201 (define_insn "floatdidf2"
8202   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8203         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8204   "TARGET_SHMEDIA_FPU"
8205   "float.qd     %1, %0")
8206
8207 (define_expand "floatsidf2"
8208   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8209         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
8210   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8211   "
8212 {
8213   if (TARGET_SH4)
8214     {
8215       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
8216                                       get_fpscr_rtx ()));
8217       DONE;
8218     }
8219 }")
8220
8221 (define_insn "*floatsidf2_media"
8222   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8223         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8224   "TARGET_SHMEDIA_FPU"
8225   "float.ld     %1, %0")
8226
8227 (define_insn "floatsidf2_i"
8228   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8229         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
8230    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8231   "TARGET_SH4"
8232   "float        %1,%0"
8233   [(set_attr "type" "dfp_conv")
8234    (set_attr "fp_mode" "double")])
8235
8236 (define_insn "fix_truncdfdi2"
8237   [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8238         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8239   "TARGET_SHMEDIA_FPU"
8240   "ftrc.dq      %1, %0")
8241
8242 (define_expand "fix_truncdfsi2"
8243   [(set (match_operand:SI 0 "fpul_operand" "")
8244         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8245   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8246   "
8247 {
8248   if (TARGET_SH4)
8249     {
8250       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
8251                                           get_fpscr_rtx ()));
8252       DONE;
8253     }
8254 }")
8255
8256 (define_insn "*fix_truncdfsi2_media"
8257   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8258         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8259   "TARGET_SHMEDIA_FPU"
8260   "ftrc.dl      %1, %0")
8261
8262 (define_insn "fix_truncdfsi2_i"
8263   [(set (match_operand:SI 0 "fpul_operand" "=y")
8264         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8265    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8266   "TARGET_SH4"
8267   "ftrc %1,%0"
8268   [(set_attr "type" "dfp_conv")
8269    (set_attr "fp_mode" "double")])
8270
8271 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
8272 ;; fix_truncdfsi2_i.
8273 ;; (define_insn "fix_truncdfsi2_i4"
8274 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8275 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8276 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
8277 ;;    (clobber (reg:SI FPUL_REG))]
8278 ;;   "TARGET_SH4"
8279 ;;   "#"
8280 ;;   [(set_attr "length" "4")
8281 ;;    (set_attr "fp_mode" "double")])
8282 ;; 
8283 ;; (define_split
8284 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8285 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8286 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
8287 ;;    (clobber (reg:SI FPUL_REG))]
8288 ;;   "TARGET_SH4"
8289 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8290 ;;            (use (match_dup 2))])
8291 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
8292
8293 (define_insn "cmpgtdf_t"
8294   [(set (reg:SI T_REG)
8295         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
8296                (match_operand:DF 1 "arith_reg_operand" "f")))
8297    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8298   "TARGET_SH4"
8299   "fcmp/gt      %1,%0"
8300   [(set_attr "type" "dfp_cmp")
8301    (set_attr "fp_mode" "double")])
8302
8303 (define_insn "cmpeqdf_t"
8304   [(set (reg:SI T_REG)
8305         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8306                (match_operand:DF 1 "arith_reg_operand" "f")))
8307    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8308   "TARGET_SH4"
8309   "fcmp/eq      %1,%0"
8310   [(set_attr "type" "dfp_cmp")
8311    (set_attr "fp_mode" "double")])
8312
8313 (define_insn "*ieee_ccmpeqdf_t"
8314   [(set (reg:SI T_REG)
8315         (ior:SI (reg:SI T_REG)
8316                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8317                        (match_operand:DF 1 "arith_reg_operand" "f"))))
8318    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8319   "TARGET_IEEE && TARGET_SH4"
8320   "* return output_ieee_ccmpeq (insn, operands);"
8321   [(set_attr "length" "4")
8322    (set_attr "fp_mode" "double")])
8323    
8324 (define_insn "cmpeqdf_media"
8325   [(set (match_operand:DI 0 "register_operand" "=r")
8326         (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8327                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8328   "TARGET_SHMEDIA_FPU"
8329   "fcmpeq.d     %1,%2,%0")
8330
8331 (define_insn "cmpgtdf_media"
8332   [(set (match_operand:DI 0 "register_operand" "=r")
8333         (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8334                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8335   "TARGET_SHMEDIA_FPU"
8336   "fcmpgt.d     %1,%2,%0")
8337
8338 (define_insn "cmpgedf_media"
8339   [(set (match_operand:DI 0 "register_operand" "=r")
8340         (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8341                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8342   "TARGET_SHMEDIA_FPU"
8343   "fcmpge.d     %1,%2,%0")
8344
8345 (define_insn "cmpundf_media"
8346   [(set (match_operand:DI 0 "register_operand" "=r")
8347         (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8348                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8349   "TARGET_SHMEDIA_FPU"
8350   "fcmpun.d     %1,%2,%0")
8351
8352 (define_expand "cmpdf"
8353   [(set (reg:SI T_REG)
8354         (compare (match_operand:DF 0 "arith_operand" "")
8355                  (match_operand:DF 1 "arith_operand" "")))]
8356   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8357   "
8358 {
8359   sh_compare_op0 = operands[0];
8360   sh_compare_op1 = operands[1];
8361   DONE;
8362 }")
8363
8364 (define_expand "negdf2"
8365   [(set (match_operand:DF 0 "arith_reg_operand" "")
8366         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8367   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8368   "
8369 {
8370   if (TARGET_SH4)
8371     {
8372       expand_df_unop (&gen_negdf2_i, operands);
8373       DONE;
8374     }
8375 }")
8376
8377 (define_insn "*negdf2_media"
8378   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8379         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8380   "TARGET_SHMEDIA_FPU"
8381   "fneg.d       %1, %0")
8382
8383 (define_insn "negdf2_i"
8384   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8385         (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8386    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8387   "TARGET_SH4"
8388   "fneg %0"
8389   [(set_attr "type" "fmove")
8390    (set_attr "fp_mode" "double")])
8391
8392 (define_expand "sqrtdf2"
8393   [(set (match_operand:DF 0 "arith_reg_operand" "")
8394         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8395   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8396   "
8397 {
8398   if (TARGET_SH4)
8399     {
8400       expand_df_unop (&gen_sqrtdf2_i, operands);
8401       DONE;
8402     }
8403 }")
8404
8405 (define_insn "*sqrtdf2_media"
8406   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8407         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8408   "TARGET_SHMEDIA_FPU"
8409   "fsqrt.d      %1, %0")
8410
8411 (define_insn "sqrtdf2_i"
8412   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8413         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8414    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8415   "TARGET_SH4"
8416   "fsqrt        %0"
8417   [(set_attr "type" "dfdiv")
8418    (set_attr "fp_mode" "double")])
8419
8420 (define_expand "absdf2"
8421   [(set (match_operand:DF 0 "arith_reg_operand" "")
8422         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8423   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8424   "
8425 {
8426   if (TARGET_SH4)
8427     {
8428       expand_df_unop (&gen_absdf2_i, operands);
8429       DONE;
8430     }
8431 }")
8432
8433 (define_insn "*absdf2_media"
8434   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8435         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8436   "TARGET_SHMEDIA_FPU"
8437   "fabs.d       %1, %0")
8438
8439 (define_insn "absdf2_i"
8440   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8441         (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8442    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8443   "TARGET_SH4"
8444   "fabs %0"
8445   [(set_attr "type" "fmove")
8446    (set_attr "fp_mode" "double")])
8447
8448 (define_expand "extendsfdf2"
8449   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8450         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
8451   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8452   "
8453 {
8454   if (TARGET_SH4)
8455     {
8456       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
8457                                         get_fpscr_rtx ()));
8458       DONE;
8459     }
8460 }")
8461
8462 (define_insn "*extendsfdf2_media"
8463   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8464         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8465   "TARGET_SHMEDIA_FPU"
8466   "fcnv.sd      %1, %0")
8467
8468 (define_insn "extendsfdf2_i4"
8469   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8470         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
8471    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8472   "TARGET_SH4"
8473   "fcnvsd  %1,%0"
8474   [(set_attr "type" "fp")
8475    (set_attr "fp_mode" "double")])
8476
8477 (define_expand "truncdfsf2"
8478   [(set (match_operand:SF 0 "fpul_operand" "")
8479         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8480   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8481   "
8482 {
8483   if (TARGET_SH4)
8484     {
8485       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
8486                                        get_fpscr_rtx ()));
8487       DONE;
8488     }
8489 }")
8490
8491 (define_insn "*truncdfsf2_media"
8492   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8493         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8494   "TARGET_SHMEDIA_FPU"
8495   "fcnv.ds      %1, %0")
8496
8497 (define_insn "truncdfsf2_i4"
8498   [(set (match_operand:SF 0 "fpul_operand" "=y")
8499         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8500    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8501   "TARGET_SH4"
8502   "fcnvds  %1,%0"
8503   [(set_attr "type" "fp")
8504    (set_attr "fp_mode" "double")])
8505 \f
8506 ;; Bit field extract patterns.  These give better code for packed bitfields,
8507 ;; because they allow auto-increment addresses to be generated.
8508
8509 (define_expand "insv"
8510   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
8511                          (match_operand:SI 1 "immediate_operand" "")
8512                          (match_operand:SI 2 "immediate_operand" ""))
8513         (match_operand:SI 3 "general_operand" ""))]
8514   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
8515   "
8516 {
8517   rtx addr_target, orig_address, shift_reg, qi_val;
8518   HOST_WIDE_INT bitsize, size, v;
8519   rtx x = operands[3];
8520
8521   /* ??? expmed doesn't care for non-register predicates.  */
8522   if (! memory_operand (operands[0], VOIDmode)
8523       || ! immediate_operand (operands[1], VOIDmode)
8524       || ! immediate_operand (operands[2], VOIDmode)
8525       || ! general_operand (x, VOIDmode))
8526     FAIL;
8527   /* If this isn't a 16 / 24 / 32 bit field, or if
8528      it doesn't start on a byte boundary, then fail.  */
8529   bitsize = INTVAL (operands[1]);
8530   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
8531       || (INTVAL (operands[2]) % 8) != 0)
8532     FAIL;
8533
8534   size = bitsize / 8;
8535   orig_address = XEXP (operands[0], 0);
8536   shift_reg = gen_reg_rtx (SImode);
8537   if (GET_CODE (x) == CONST_INT)
8538     {
8539       v = INTVAL (x);
8540       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
8541     }
8542   else
8543     {
8544       emit_insn (gen_movsi (shift_reg, operands[3]));
8545       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
8546     }
8547   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
8548
8549   operands[0] = replace_equiv_address (operands[0], addr_target);
8550   emit_insn (gen_movqi (operands[0], qi_val));
8551
8552   while (size -= 1)
8553     {
8554       if (GET_CODE (x) == CONST_INT)
8555         qi_val
8556           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
8557       else
8558         {
8559           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
8560           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
8561         }
8562       emit_insn (gen_addsi3 (addr_target, addr_target, GEN_INT (-1)));
8563       emit_insn (gen_movqi (operands[0], qi_val));
8564     }
8565
8566   DONE;
8567 }")
8568 \f
8569 ;; -------------------------------------------------------------------------
8570 ;; Peepholes
8571 ;; -------------------------------------------------------------------------
8572
8573 ;; This matches cases where a stack pointer increment at the start of the
8574 ;; epilogue combines with a stack slot read loading the return value.
8575
8576 (define_peephole
8577   [(set (match_operand:SI 0 "arith_reg_operand" "")
8578         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
8579    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
8580   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
8581   "mov.l        @%1+,%0")
8582
8583 ;; See the comment on the dt combiner pattern above.
8584
8585 (define_peephole
8586   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8587         (plus:SI (match_dup 0)
8588                  (const_int -1)))
8589    (set (reg:SI T_REG)
8590         (eq:SI (match_dup 0)
8591                (const_int 0)))]
8592   "TARGET_SH2"
8593   "dt   %0")
8594
8595 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
8596 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
8597 ;; reload when the constant is too large for a reg+offset address.
8598
8599 ;; ??? We would get much better code if this was done in reload.  This would
8600 ;; require modifying find_reloads_address to recognize that if the constant
8601 ;; is out-of-range for an immediate add, then we get better code by reloading
8602 ;; the constant into a register than by reloading the sum into a register,
8603 ;; since the former is one instruction shorter if the address does not need
8604 ;; to be offsettable.  Unfortunately this does not work, because there is
8605 ;; only one register, r0, that can be used as an index register.  This register
8606 ;; is also the function return value register.  So, if we try to force reload
8607 ;; to use double-reg addresses, then we end up with some instructions that
8608 ;; need to use r0 twice.  The only way to fix this is to change the calling
8609 ;; convention so that r0 is not used to return values.
8610
8611 (define_peephole
8612   [(set (match_operand:SI 0 "register_operand" "=r")
8613         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
8614    (set (mem:SI (match_dup 0))
8615         (match_operand:SI 2 "general_movsrc_operand" ""))]
8616   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
8617   "mov.l        %2,@(%0,%1)")
8618
8619 (define_peephole
8620   [(set (match_operand:SI 0 "register_operand" "=r")
8621         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
8622    (set (match_operand:SI 2 "general_movdst_operand" "")
8623         (mem:SI (match_dup 0)))]
8624   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
8625   "mov.l        @(%0,%1),%2")
8626
8627 (define_peephole
8628   [(set (match_operand:SI 0 "register_operand" "=r")
8629         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
8630    (set (mem:HI (match_dup 0))
8631         (match_operand:HI 2 "general_movsrc_operand" ""))]
8632   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
8633   "mov.w        %2,@(%0,%1)")
8634
8635 (define_peephole
8636   [(set (match_operand:SI 0 "register_operand" "=r")
8637         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
8638    (set (match_operand:HI 2 "general_movdst_operand" "")
8639         (mem:HI (match_dup 0)))]
8640   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
8641   "mov.w        @(%0,%1),%2")
8642
8643 (define_peephole
8644   [(set (match_operand:SI 0 "register_operand" "=r")
8645         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
8646    (set (mem:QI (match_dup 0))
8647         (match_operand:QI 2 "general_movsrc_operand" ""))]
8648   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
8649   "mov.b        %2,@(%0,%1)")
8650
8651 (define_peephole
8652   [(set (match_operand:SI 0 "register_operand" "=r")
8653         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
8654    (set (match_operand:QI 2 "general_movdst_operand" "")
8655         (mem:QI (match_dup 0)))]
8656   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
8657   "mov.b        @(%0,%1),%2")
8658
8659 (define_peephole
8660   [(set (match_operand:SI 0 "register_operand" "=r")
8661         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
8662    (set (mem:SF (match_dup 0))
8663         (match_operand:SF 2 "general_movsrc_operand" ""))]
8664   "TARGET_SH1 && REGNO (operands[0]) == 0
8665    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
8666        || (GET_CODE (operands[2]) == SUBREG
8667            && REGNO (SUBREG_REG (operands[2])) < 16))
8668    && reg_unused_after (operands[0], insn)"
8669   "mov.l        %2,@(%0,%1)")
8670
8671 (define_peephole
8672   [(set (match_operand:SI 0 "register_operand" "=r")
8673         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
8674    (set (match_operand:SF 2 "general_movdst_operand" "")
8675
8676         (mem:SF (match_dup 0)))]
8677   "TARGET_SH1 && REGNO (operands[0]) == 0
8678    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
8679        || (GET_CODE (operands[2]) == SUBREG
8680            && REGNO (SUBREG_REG (operands[2])) < 16))
8681    && reg_unused_after (operands[0], insn)"
8682   "mov.l        @(%0,%1),%2")
8683
8684 (define_peephole
8685   [(set (match_operand:SI 0 "register_operand" "=r")
8686         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
8687    (set (mem:SF (match_dup 0))
8688         (match_operand:SF 2 "general_movsrc_operand" ""))]
8689   "TARGET_SH3E && REGNO (operands[0]) == 0
8690    && ((GET_CODE (operands[2]) == REG
8691         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
8692        || (GET_CODE (operands[2]) == SUBREG
8693            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
8694    && reg_unused_after (operands[0], insn)"
8695   "fmov{.s|}    %2,@(%0,%1)")
8696
8697 (define_peephole
8698   [(set (match_operand:SI 0 "register_operand" "=r")
8699         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
8700    (set (match_operand:SF 2 "general_movdst_operand" "")
8701
8702         (mem:SF (match_dup 0)))]
8703   "TARGET_SH3E && REGNO (operands[0]) == 0
8704    && ((GET_CODE (operands[2]) == REG
8705         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
8706        || (GET_CODE (operands[2]) == SUBREG
8707            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
8708    && reg_unused_after (operands[0], insn)"
8709   "fmov{.s|}    @(%0,%1),%2")
8710
8711 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
8712 (define_insn "sp_switch_1"
8713   [(const_int 1)]
8714   "TARGET_SH1"
8715   "*
8716 {
8717   rtx xoperands[1];
8718
8719   xoperands[0] = sp_switch;
8720   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
8721   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
8722   return \"mov r0,r15\";
8723 }"
8724   [(set_attr "length" "10")])
8725
8726 ;; Switch back to the original stack for interrupt functions with the
8727 ;; sp_switch attribute.  */
8728 (define_insn "sp_switch_2"
8729   [(const_int 2)]
8730   "TARGET_SH1"
8731   "mov.l @r15+,r15\;mov.l @r15+,r0"
8732   [(set_attr "length" "4")])
8733
8734 ;; Integer vector moves
8735
8736 (define_expand "movv8qi"
8737   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
8738         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
8739   "TARGET_SHMEDIA"
8740   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
8741
8742 (define_insn "movv8qi_i"
8743   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
8744         (match_operand:V8QI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
8745   "TARGET_SHMEDIA
8746    && (register_operand (operands[0], V8QImode)
8747        || register_operand (operands[1], V8QImode))"
8748   "@
8749         add     %1, r63, %0
8750         movi    %1, %0
8751         #
8752         ld%M1.q %m1, %0
8753         st%M0.q %m0, %1"
8754   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
8755    (set_attr "length" "4,4,16,4,4")])
8756
8757 (define_split
8758   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
8759         (subreg:V8QI (const_int 0) 0))]
8760   "TARGET_SHMEDIA"
8761   [(set (match_dup 0)
8762         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
8763                             (const_int 0) (const_int 0) (const_int 0)
8764                             (const_int 0) (const_int 0)]))])
8765
8766 (define_split
8767   [(set (match_operand 0 "arith_reg_dest" "")
8768         (match_operand 1 "sh_rep_vec" ""))]
8769   "TARGET_SHMEDIA && reload_completed
8770    && GET_MODE (operands[0]) == GET_MODE (operands[1])
8771    && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
8772    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
8773    && (XVECEXP (operands[1], 0, 0) != const0_rtx
8774        || XVECEXP (operands[1], 0, 1) != const0_rtx)"
8775   [(set (match_dup 0) (match_dup 1))
8776    (match_dup 2)]
8777   "
8778 {
8779   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
8780   rtx elt1 = XVECEXP (operands[1], 0, 1);
8781
8782   if (unit_size > 2)
8783     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
8784   else
8785     operands[2] = gen_mperm_w0 (operands[0], operands[0]);
8786   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
8787   operands[1] = XVECEXP (operands[1], 0, 0);
8788   if (unit_size < 2)
8789     {
8790       if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
8791         operands[1] = GEN_INT (TARGET_LITTLE_ENDIAN
8792                                ? INTVAL (operands[1]) + (INTVAL (elt1) << 8)
8793                                : (INTVAL (operands[1]) << 8) + INTVAL (elt1));
8794       else
8795         {
8796           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
8797           operands[1]
8798             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
8799         }
8800     }
8801 }")
8802
8803 (define_split
8804   [(set (match_operand 0 "arith_reg_dest" "")
8805         (match_operand 1 "sh_const_vec" ""))]
8806   "TARGET_SHMEDIA && reload_completed
8807    && GET_MODE (operands[0]) == GET_MODE (operands[1])
8808    && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
8809    && XVECEXP (operands[1], 0, 0) != const0_rtx
8810    && (HOST_BITS_PER_WIDE_INT >= 64
8811        || HOST_BITS_PER_WIDE_INT >= GET_MODE_BITSIZE (GET_MODE (operands[0]))
8812        || sh_1el_vec (operands[1], VOIDmode))"
8813   [(set (match_dup 0) (match_dup 1))]
8814   "
8815 {
8816   rtx v = operands[1];
8817   enum machine_mode new_mode
8818     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
8819
8820   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
8821   operands[1]
8822     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[0]), 0);
8823 }")
8824
8825 (define_expand "movv2hi"
8826   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
8827         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
8828   "TARGET_SHMEDIA"
8829   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
8830
8831 (define_insn "movv2hi_i"
8832   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
8833         (match_operand:V2HI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
8834   "TARGET_SHMEDIA
8835    && (register_operand (operands[0], V2HImode)
8836        || register_operand (operands[1], V2HImode))"
8837   "@
8838         addz.l  %1, r63, %0
8839         movi    %1, %0
8840         #
8841         ld%M1.l %m1, %0
8842         st%M0.l %m0, %1"
8843   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
8844    (set_attr "length" "4,4,16,4,4")])
8845
8846 (define_expand "movv4hi"
8847   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
8848         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
8849   "TARGET_SHMEDIA"
8850   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
8851
8852 (define_insn "movv4hi_i"
8853   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
8854         (match_operand:V4HI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
8855   "TARGET_SHMEDIA
8856    && (register_operand (operands[0], V4HImode)
8857        || register_operand (operands[1], V4HImode))"
8858   "@
8859         add     %1, r63, %0
8860         movi    %1, %0
8861         #
8862         ld%M1.q %m1, %0
8863         st%M0.q %m0, %1"
8864   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
8865    (set_attr "length" "4,4,16,4,4")])
8866
8867 (define_expand "movv2si"
8868   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
8869         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
8870   "TARGET_SHMEDIA"
8871   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
8872
8873 (define_insn "movv2si_i"
8874   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
8875         (match_operand:V2SI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
8876   "TARGET_SHMEDIA
8877    && (register_operand (operands[0], V2SImode)
8878        || register_operand (operands[1], V2SImode))"
8879   "@
8880         add     %1, r63, %0
8881         movi    %1, %0
8882         #
8883         ld%M1.q %m1, %0
8884         st%M0.q %m0, %1"
8885   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
8886    (set_attr "length" "4,4,16,4,4")])
8887
8888 ;; Multimedia Intrinsics
8889
8890 (define_insn "absv2si2"
8891   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
8892         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
8893   "TARGET_SHMEDIA"
8894   "mabs.l       %1, %0"
8895   [(set_attr "type" "mcmp_media")])
8896
8897 (define_insn "absv4hi2"
8898   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
8899         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
8900   "TARGET_SHMEDIA"
8901   "mabs.w       %1, %0"
8902   [(set_attr "type" "mcmp_media")])
8903
8904 (define_insn "addv2si3"
8905   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
8906         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
8907                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
8908   "TARGET_SHMEDIA"
8909   "madd.l       %1, %2, %0"
8910   [(set_attr "type" "arith_media")])
8911
8912 (define_insn "addv4hi3"
8913   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
8914         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
8915                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
8916   "TARGET_SHMEDIA"
8917   "madd.w       %1, %2, %0"
8918   [(set_attr "type" "arith_media")])
8919
8920 (define_insn "ssaddv2si3"
8921   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
8922         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
8923                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
8924   "TARGET_SHMEDIA"
8925   "madds.l      %1, %2, %0"
8926   [(set_attr "type" "mcmp_media")])
8927
8928 (define_insn "usaddv8qi3"
8929   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
8930         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
8931                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
8932   "TARGET_SHMEDIA"
8933   "madds.ub     %1, %2, %0"
8934   [(set_attr "type" "mcmp_media")])
8935
8936 (define_insn "ssaddv4hi3"
8937   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
8938         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
8939                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
8940   "TARGET_SHMEDIA"
8941   "madds.w      %1, %2, %0"
8942   [(set_attr "type" "mcmp_media")])
8943
8944 (define_insn "negcmpeqv8qi"
8945   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
8946         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rU")
8947                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))))]
8948   "TARGET_SHMEDIA"
8949   "mcmpeq.b     %N1, %N2, %0"
8950   [(set_attr "type" "mcmp_media")])
8951
8952 (define_insn "negcmpeqv2si"
8953   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
8954         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rU")
8955                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
8956   "TARGET_SHMEDIA"
8957   "mcmpeq.l     %N1, %N2, %0"
8958   [(set_attr "type" "mcmp_media")])
8959
8960 (define_insn "negcmpeqv4hi"
8961   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
8962         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rU")
8963                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
8964   "TARGET_SHMEDIA"
8965   "mcmpeq.w     %N1, %N2, %0"
8966   [(set_attr "type" "mcmp_media")])
8967
8968 (define_insn "negcmpgtuv8qi"
8969   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
8970         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rU")
8971                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))))]
8972   "TARGET_SHMEDIA"
8973   "mcmpgt.ub    %N1, %N2, %0"
8974   [(set_attr "type" "mcmp_media")])
8975
8976 (define_insn "negcmpgtv2si"
8977   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
8978         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rU")
8979                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
8980   "TARGET_SHMEDIA"
8981   "mcmpgt.l     %N1, %N2, %0"
8982   [(set_attr "type" "mcmp_media")])
8983
8984 (define_insn "negcmpgtv4hi"
8985   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
8986         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rU")
8987                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
8988   "TARGET_SHMEDIA"
8989   "mcmpgt.w     %N1, %N2, %0"
8990   [(set_attr "type" "mcmp_media")])
8991
8992 (define_insn "mcmv"
8993   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
8994         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
8995                         (match_operand:DI 2 "arith_reg_operand" "r"))
8996                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
8997                         (not:DI (match_dup 2)))))]
8998   "TARGET_SHMEDIA"
8999   "mcmv %N1, %2, %0"
9000   [(set_attr "type" "arith_media")])
9001
9002 (define_insn "mcnvs_lw"
9003   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9004         (vec_concat:V4HI
9005          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU"))
9006          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9007   "TARGET_SHMEDIA"
9008   "mcnvs.lw     %N1, %N2, %0"
9009   [(set_attr "type" "mcmp_media")])
9010
9011 (define_insn "mcnvs_wb"
9012   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9013         (vec_concat:V8QI
9014          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU"))
9015          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9016   "TARGET_SHMEDIA"
9017   "mcnvs.wb     %N1, %N2, %0"
9018   [(set_attr "type" "mcmp_media")])
9019
9020 (define_insn "mcnvs_wub"
9021   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9022         (vec_concat:V8QI
9023          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU"))
9024          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9025   "TARGET_SHMEDIA"
9026   "mcnvs.wub    %N1, %N2, %0"
9027   [(set_attr "type" "mcmp_media")])
9028
9029 (define_insn "mextr_rl"
9030   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9031         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9032                              (match_operand:HI 3 "mextr_bit_offset" "i"))
9033                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9034                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9035   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9036   "*
9037 {
9038   static char templ[16];
9039
9040   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9041            (int) INTVAL (operands[3]) >> 3);
9042   return templ;
9043 }"
9044   [(set_attr "type" "arith_media")])
9045
9046 (define_insn "*mextr_lr"
9047   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9048         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9049                            (match_operand:HI 3 "mextr_bit_offset" "i"))
9050                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9051                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9052   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9053   "*
9054 {
9055   static char templ[16];
9056
9057   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9058            (int) INTVAL (operands[4]) >> 3);
9059   return templ;
9060 }"
9061   [(set_attr "type" "arith_media")])
9062
9063 ; mextrN can be modelled with vec_select / vec_concat, but the selection
9064 ; vector then varies depending on endianness.
9065 (define_expand "mextr1"
9066   [(match_operand:V8QI 0 "arith_reg_dest" "")
9067    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9068    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9069   "TARGET_SHMEDIA"
9070   "
9071 {
9072   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[3],
9073                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
9074   DONE;
9075 }")
9076
9077 (define_expand "mextr2"
9078   [(match_operand:V8QI 0 "arith_reg_dest" "")
9079    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9080    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9081   "TARGET_SHMEDIA"
9082   "
9083 {
9084   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[3],
9085                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
9086   DONE;
9087 }")
9088
9089 (define_expand "mextr3"
9090   [(match_operand:V8QI 0 "arith_reg_dest" "")
9091    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9092    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9093   "TARGET_SHMEDIA"
9094   "
9095 {
9096   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[3],
9097                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
9098   DONE;
9099 }")
9100
9101 (define_expand "mextr4"
9102   [(match_operand:V8QI 0 "arith_reg_dest" "")
9103    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9104    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9105   "TARGET_SHMEDIA"
9106   "
9107 {
9108   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[3],
9109                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
9110   DONE;
9111 }")
9112
9113 (define_expand "mextr5"
9114   [(match_operand:V8QI 0 "arith_reg_dest" "")
9115    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9116    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9117   "TARGET_SHMEDIA"
9118   "
9119 {
9120   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[3],
9121                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
9122   DONE;
9123 }")
9124
9125 (define_expand "mextr6"
9126   [(match_operand:V8QI 0 "arith_reg_dest" "")
9127    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9128    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9129   "TARGET_SHMEDIA"
9130   "
9131 {
9132   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[3],
9133                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
9134   DONE;
9135 }")
9136
9137 (define_expand "mextr7"
9138   [(match_operand:V8QI 0 "arith_reg_dest" "")
9139    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9140    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9141   "TARGET_SHMEDIA"
9142   "
9143 {
9144   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[3],
9145                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
9146   DONE;
9147 }")
9148
9149 (define_expand "mmacfx_wl"
9150   [(match_operand:V2SI 0 "arith_reg_dest" "")
9151    (match_operand:V2HI 1 "extend_reg_operand" "")
9152    (match_operand:V2HI 2 "extend_reg_operand" "")
9153    (match_operand:V2SI 3 "arith_reg_operand" "")]
9154   "TARGET_SHMEDIA"
9155   "
9156 {
9157   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
9158                               operands[1], operands[2]));
9159   DONE;
9160 }")
9161
9162 (define_insn "mmacfx_wl_i"
9163   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9164         (ss_plus:V2SI
9165          (match_operand:V2SI 1 "arith_reg_operand" "0")
9166          (ss_truncate:V2SI
9167           (ashift:V2DI
9168            (sign_extend:V2DI
9169             (mult:V2SI
9170              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9171              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9172            (const_int 1)))))]
9173   "TARGET_SHMEDIA"
9174   "mmacfx.wl    %2, %3, %0"
9175   [(set_attr "type" "mac_media")])
9176
9177 (define_expand "mmacnfx_wl"
9178   [(match_operand:V2SI 0 "arith_reg_dest" "")
9179    (match_operand:V2HI 1 "extend_reg_operand" "")
9180    (match_operand:V2HI 2 "extend_reg_operand" "")
9181    (match_operand:V2SI 3 "arith_reg_operand" "")]
9182   "TARGET_SHMEDIA"
9183   "
9184 {
9185   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
9186                                operands[1], operands[2]));
9187   DONE;
9188 }")
9189
9190 (define_insn "mmacnfx_wl_i"
9191   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9192         (ss_minus:V2SI
9193          (match_operand:V2SI 1 "arith_reg_operand" "0")
9194          (ss_truncate:V2SI
9195           (ashift:V2DI
9196            (sign_extend:V2DI
9197             (mult:V2SI
9198              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9199              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9200            (const_int 1)))))]
9201   "TARGET_SHMEDIA"
9202   "mmacnfx.wl   %2, %3, %0"
9203   [(set_attr "type" "mac_media")])
9204
9205 (define_insn "mulv2si3"
9206   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9207         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9208                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9209   "TARGET_SHMEDIA"
9210   "mmul.l       %1, %2, %0"
9211   [(set_attr "type" "d2mpy_media")])
9212
9213 (define_insn "mulv4hi3"
9214   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9215         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9216                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9217   "TARGET_SHMEDIA"
9218   "mmul.w       %1, %2, %0"
9219   [(set_attr "type" "dmpy_media")])
9220
9221 (define_insn "mmulfx_l"
9222   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9223         (ss_truncate:V2SI
9224          (ashiftrt:V2DI
9225           (mult:V2DI
9226            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9227            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
9228           (const_int 31))))]
9229   "TARGET_SHMEDIA"
9230   "mmulfx.l     %1, %2, %0"
9231   [(set_attr "type" "d2mpy_media")])
9232
9233 (define_insn "mmulfx_w"
9234   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9235         (ss_truncate:V4HI
9236          (ashiftrt:V4SI
9237           (mult:V4SI
9238            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9239            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9240           (const_int 15))))]
9241   "TARGET_SHMEDIA"
9242   "mmulfx.w     %1, %2, %0"
9243   [(set_attr "type" "dmpy_media")])
9244
9245 (define_insn "mmulfxrp_w"
9246   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9247         (ss_truncate:V4HI
9248          (ashiftrt:V4SI
9249           (plus:V4SI
9250            (mult:V4SI
9251             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9252             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9253            (const_int 16384))
9254           (const_int 15))))]
9255   "TARGET_SHMEDIA"
9256   "mmulfxrp.w   %1, %2, %0"
9257   [(set_attr "type" "dmpy_media")])
9258
9259 (define_expand "mmulhi_wl"
9260   [(match_operand:V2SI 0 "arith_reg_dest" "")
9261    (match_operand:V4HI 1 "arith_reg_operand" "")
9262    (match_operand:V4HI 2 "arith_reg_operand" "")]
9263   "TARGET_SHMEDIA"
9264   "
9265 {
9266   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
9267              (operands[0], operands[1], operands[2]));
9268   DONE;
9269 }")
9270
9271 (define_expand "mmullo_wl"
9272   [(match_operand:V2SI 0 "arith_reg_dest" "")
9273    (match_operand:V4HI 1 "arith_reg_operand" "")
9274    (match_operand:V4HI 2 "arith_reg_operand" "")]
9275   "TARGET_SHMEDIA"
9276   "
9277 {
9278   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
9279              (operands[0], operands[1], operands[2]));
9280   DONE;
9281 }")
9282
9283 (define_insn "mmul23_wl"
9284   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9285         (vec_select:V2SI
9286          (mult:V4SI
9287           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9288           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9289          (const_vector [(const_int 2) (const_int 3)])))]
9290   "TARGET_SHMEDIA"
9291   "* return (TARGET_LITTLE_ENDIAN
9292              ? \"mmulhi.wl      %1, %2, %0\"
9293              : \"mmullo.wl      %1, %2, %0\");"
9294   [(set_attr "type" "dmpy_media")])
9295
9296 (define_insn "mmul01_wl"
9297   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9298         (vec_select:V2SI
9299          (mult:V4SI
9300           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9301           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9302          (const_vector [(const_int 0) (const_int 1)])))]
9303   "TARGET_SHMEDIA"
9304   "* return (TARGET_LITTLE_ENDIAN
9305              ? \"mmullo.wl      %1, %2, %0\"
9306              : \"mmulhi.wl      %1, %2, %0\");"
9307   [(set_attr "type" "dmpy_media")])
9308
9309 (define_expand "mmulsum_wq"
9310   [(match_operand:DI 0 "arith_reg_dest" "")
9311    (match_operand:V4HI 1 "arith_reg_operand" "")
9312    (match_operand:V4HI 2 "arith_reg_operand" "")
9313    (match_operand:DI 3 "arith_reg_operand" "")]
9314   "TARGET_SHMEDIA"
9315   "
9316 {
9317   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
9318                                operands[1], operands[2]));
9319   DONE;
9320 }")
9321
9322 (define_insn "mmulsum_wq_i"
9323   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9324         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
9325          (plus:DI
9326           (plus:DI
9327            (vec_select:DI
9328             (mult:V4DI
9329              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
9330              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
9331             (const_vector [(const_int 0)]))
9332            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9333                                      (sign_extend:V4DI (match_dup 3)))
9334                           (const_vector [(const_int 1)])))
9335           (plus:DI
9336            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9337                                      (sign_extend:V4DI (match_dup 3)))
9338                           (const_vector [(const_int 2)]))
9339            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9340                                      (sign_extend:V4DI (match_dup 3)))
9341                           (const_vector [(const_int 3)]))))))]
9342   "TARGET_SHMEDIA"
9343   "mmulsum.wq   %2, %3, %0"
9344   [(set_attr "type" "mac_media")])
9345
9346 (define_expand "mperm_w"
9347   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
9348    (match_operand:V4HI 1 "arith_reg_operand" "r")
9349    (match_operand:QI 2 "extend_reg_or_0_operand" "rU")]
9350   "TARGET_SHMEDIA"
9351   "
9352 {
9353   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
9354              (operands[0], operands[1], operands[2]));
9355 }")
9356
9357 ; This use of vec_select isn't exactly correct according to rtl.texi
9358 ; (because not constant), but it seems a straightforward extension.
9359 (define_insn "mperm_w_little"
9360   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9361         (vec_select:V4HI
9362          (match_operand:V4HI 1 "arith_reg_operand" "r")
9363          (parallel
9364           [(zero_extract (match_operand:QI 2 "extend_reg_or_0_operand" "rU")
9365                          (const_int 2) (const_int 0))
9366            (zero_extract (match_dup 2) (const_int 2) (const_int 2))
9367            (zero_extract (match_dup 2) (const_int 2) (const_int 4))
9368            (zero_extract (match_dup 2) (const_int 2) (const_int 6))])))]
9369   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
9370   "mperm.w      %1, %N2, %0"
9371   [(set_attr "type" "arith_media")])
9372
9373 (define_insn "mperm_w_big"
9374   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9375         (vec_select:V4HI
9376          (match_operand:V4HI 1 "arith_reg_operand" "r")
9377          (parallel
9378           [(zero_extract (not:QI (match_operand:QI 2
9379                                   "extend_reg_or_0_operand" "rU"))
9380                          (const_int 2) (const_int 0))
9381            (zero_extract (not:QI (match_dup 2)) (const_int 2) (const_int 2))
9382            (zero_extract (not:QI (match_dup 2)) (const_int 2) (const_int 4))
9383            (zero_extract (not:QI (match_dup 2)) (const_int 2) (const_int 6))])))]
9384   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
9385   "mperm.w      %1, %N2, %0"
9386   [(set_attr "type" "arith_media")])
9387
9388 (define_insn "mperm_w0"
9389   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9390         (vec_duplicate:V4HI (truncate:HI (match_operand 1
9391                                           "extend_reg_operand" "r"))))]
9392   "TARGET_SHMEDIA"
9393   "mperm.w      %1, r63, %0"
9394   [(set_attr "type" "arith_media")])
9395
9396 (define_expand "msad_ubq"
9397   [(match_operand:DI 0 "arith_reg_dest" "")
9398    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
9399    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
9400    (match_operand:DI 3 "arith_reg_operand" "")]
9401   "TARGET_SHMEDIA"
9402   "
9403 {
9404   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
9405                              operands[1], operands[2]));
9406   DONE;
9407 }")
9408
9409 (define_insn "msad_ubq_i"
9410   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9411         (plus:DI
9412          (plus:DI
9413           (plus:DI
9414            (plus:DI
9415             (match_operand:DI 1 "arith_reg_operand" "0")
9416             (abs:DI (vec_select:DI
9417                      (minus:V8DI
9418                       (zero_extend:V8DI
9419                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "r"))
9420                       (zero_extend:V8DI
9421                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "r")))
9422                      (const_vector [(const_int 0)]))))
9423            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9424                                               (zero_extend:V8DI (match_dup 3)))
9425                                   (const_vector [(const_int 1)]))))
9426           (plus:DI
9427            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9428                                               (zero_extend:V8DI (match_dup 3)))
9429                                   (const_vector [(const_int 2)])))
9430            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9431                                               (zero_extend:V8DI (match_dup 3)))
9432                                   (const_vector [(const_int 3)])))))
9433          (plus:DI
9434           (plus:DI
9435            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9436                                               (zero_extend:V8DI (match_dup 3)))
9437                                   (const_vector [(const_int 4)])))
9438            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9439                                               (zero_extend:V8DI (match_dup 3)))
9440                                   (const_vector [(const_int 5)]))))
9441           (plus:DI
9442            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9443                                               (zero_extend:V8DI (match_dup 3)))
9444                                   (const_vector [(const_int 6)])))
9445            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9446                                               (zero_extend:V8DI (match_dup 3)))
9447                                   (const_vector [(const_int 7)])))))))]
9448   "TARGET_SHMEDIA"
9449   "msad.ubq     %N2, %N3, %0"
9450   [(set_attr "type" "mac_media")])
9451
9452 (define_insn "mshalds_l"
9453   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9454         (ss_truncate:V2SI
9455          (ashift:V2DI
9456           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9457           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
9458                   (const_int 31)))))]
9459   "TARGET_SHMEDIA"
9460   "mshalds.l    %1, %2, %0"
9461   [(set_attr "type" "mcmp_media")])
9462
9463 (define_insn "mshalds_w"
9464   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9465         (ss_truncate:V4HI
9466          (ashift:V4SI
9467           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9468           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
9469                   (const_int 15)))))]
9470   "TARGET_SHMEDIA"
9471   "mshalds.w    %1, %2, %0"
9472   [(set_attr "type" "mcmp_media")])
9473
9474 (define_insn "ashrv2si3"
9475   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9476         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9477                        (match_operand:DI 2 "arith_reg_operand" "r")))]
9478   "TARGET_SHMEDIA"
9479   "mshard.l     %1, %2, %0"
9480   [(set_attr "type" "arith_media")])
9481
9482 (define_insn "ashrv4hi3"
9483   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9484         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9485                        (match_operand:DI 2 "arith_reg_operand" "r")))]
9486   "TARGET_SHMEDIA"
9487   "mshard.w     %1, %2, %0"
9488   [(set_attr "type" "arith_media")])
9489
9490 (define_insn "mshards_q"
9491   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
9492         (ss_truncate:HI
9493          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
9494                       (match_operand:DI 2 "arith_reg_or_0_operand" "rU"))))]
9495   "TARGET_SHMEDIA"
9496   "mshards.q    %1, %N2, %0"
9497   [(set_attr "type" "mcmp_media")])
9498
9499 (define_expand "mshfhi_b"
9500   [(match_operand:V8QI 0 "arith_reg_dest" "")
9501    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9502    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9503   "TARGET_SHMEDIA"
9504   "
9505 {
9506   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
9507              (operands[0], operands[1], operands[2]));
9508 }")
9509
9510 (define_expand "mshflo_b"
9511   [(match_operand:V8QI 0 "arith_reg_dest" "")
9512    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9513    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9514   "TARGET_SHMEDIA"
9515   "
9516 {
9517   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
9518              (operands[0], operands[1], operands[2]));
9519 }")
9520
9521 (define_insn "mshf4_b"
9522   [(set
9523     (match_operand:V8QI 0 "arith_reg_dest" "=r")
9524     (vec_select:V8QI
9525      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9526                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))
9527      (const_vector [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
9528                     (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
9529   "TARGET_SHMEDIA"
9530   "* return (TARGET_LITTLE_ENDIAN
9531              ? \"mshfhi.b       %N1, %N2, %0\"
9532              : \"mshflo.b       %N1, %N2, %0\");"
9533   [(set_attr "type" "arith_media")])
9534
9535 (define_insn "mshf0_b"
9536   [(set
9537     (match_operand:V8QI 0 "arith_reg_dest" "=r")
9538     (vec_select:V8QI
9539      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9540                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))
9541      (const_vector [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
9542                     (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
9543   "TARGET_SHMEDIA"
9544   "* return (TARGET_LITTLE_ENDIAN
9545              ? \"mshflo.b       %N1, %N2, %0\"
9546              : \"mshfhi.b       %N1, %N2, %0\");"
9547   [(set_attr "type" "arith_media")])
9548
9549 (define_expand "mshfhi_l"
9550   [(match_operand:V2SI 0 "arith_reg_dest" "")
9551    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
9552    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU")]
9553   "TARGET_SHMEDIA"
9554   "
9555 {
9556   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
9557              (operands[0], operands[1], operands[2]));
9558 }")
9559
9560 (define_expand "mshflo_l"
9561   [(match_operand:V2SI 0 "arith_reg_dest" "")
9562    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
9563    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU")]
9564   "TARGET_SHMEDIA"
9565   "
9566 {
9567   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
9568              (operands[0], operands[1], operands[2]));
9569 }")
9570
9571 (define_insn "mshf4_l"
9572   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9573         (vec_select:V2SI
9574          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
9575                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))
9576          (const_vector [(const_int 1) (const_int 3)])))]
9577   "TARGET_SHMEDIA"
9578   "* return (TARGET_LITTLE_ENDIAN
9579              ? \"mshfhi.l       %N1, %N2, %0\"
9580              : \"mshflo.l       %N1, %N2, %0\");"
9581   [(set_attr "type" "arith_media")])
9582
9583 (define_insn "mshf0_l"
9584   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9585         (vec_select:V2SI
9586          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
9587                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))
9588          (const_vector [(const_int 0) (const_int 2)])))]
9589   "TARGET_SHMEDIA"
9590   "* return (TARGET_LITTLE_ENDIAN
9591              ? \"mshflo.l       %N1, %N2, %0\"
9592              : \"mshfhi.l       %N1, %N2, %0\");"
9593   [(set_attr "type" "arith_media")])
9594
9595 (define_expand "mshfhi_w"
9596   [(match_operand:V4HI 0 "arith_reg_dest" "")
9597    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
9598    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU")]
9599   "TARGET_SHMEDIA"
9600   "
9601 {
9602   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
9603              (operands[0], operands[1], operands[2]));
9604 }")
9605
9606 (define_expand "mshflo_w"
9607   [(match_operand:V4HI 0 "arith_reg_dest" "")
9608    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
9609    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU")]
9610   "TARGET_SHMEDIA"
9611   "
9612 {
9613   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
9614              (operands[0], operands[1], operands[2]));
9615 }")
9616
9617 (define_insn "mshf4_w"
9618   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9619         (vec_select:V4HI
9620          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
9621                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))
9622          (const_vector [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
9623   "TARGET_SHMEDIA"
9624   "* return (TARGET_LITTLE_ENDIAN
9625              ? \"mshfhi.w       %N1, %N2, %0\"
9626              : \"mshflo.w       %N1, %N2, %0\");"
9627   [(set_attr "type" "arith_media")])
9628
9629 (define_insn "mshf0_w"
9630   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9631         (vec_select:V4HI
9632          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
9633                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))
9634          (const_vector [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
9635   "TARGET_SHMEDIA"
9636   "* return (TARGET_LITTLE_ENDIAN
9637              ? \"mshflo.w       %N1, %N2, %0\"
9638              : \"mshfhi.w       %N1, %N2, %0\");"
9639   [(set_attr "type" "arith_media")])
9640
9641 /* These are useful to expand ANDs and as combiner patterns.  */
9642 (define_insn "mshfhi_l_di"
9643   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9644         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU") 
9645                              (const_int 32))
9646                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9647                         (const_int -4294967296))))]
9648   "TARGET_SHMEDIA"
9649   "mshfhi.l     %N1, %N2, %0"
9650   [(set_attr "type" "arith_media")])
9651
9652 (define_insn "*mshfhi_l_di_rev"
9653   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9654         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9655                         (const_int -4294967296))
9656                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU") 
9657                              (const_int 32))))]
9658   "TARGET_SHMEDIA"
9659   "mshfhi.l     %N2, %N1, %0"
9660   [(set_attr "type" "arith_media")])
9661
9662 (define_insn "mshflo_l_di"
9663   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9664         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9665                         (const_int 4294967295))
9666                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9667                            (const_int 32))))]
9668                                 
9669   "TARGET_SHMEDIA"
9670   "mshflo.l     %N1, %N2, %0"
9671   [(set_attr "type" "arith_media")])
9672
9673 (define_insn "*mshflo_l_di_rev"
9674   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9675         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9676                            (const_int 32))
9677                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9678                         (const_int 4294967295))))]
9679                                 
9680   "TARGET_SHMEDIA"
9681   "mshflo.l     %N2, %N1, %0"
9682   [(set_attr "type" "arith_media")])
9683
9684 (define_insn "*mshflo_l_di_x"
9685   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9686         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand" "rU"))
9687                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9688                            (const_int 32))))]
9689                                 
9690   "TARGET_SHMEDIA"
9691   "mshflo.l     %N1, %N2, %0"
9692   [(set_attr "type" "arith_media")])
9693
9694 (define_insn "*mshflo_l_di_x_rev"
9695   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9696         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9697                            (const_int 32))
9698                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rU"))))]
9699                                 
9700   "TARGET_SHMEDIA"
9701   "mshflo.l     %N2, %N1, %0"
9702   [(set_attr "type" "arith_media")])
9703
9704 (define_insn "ashlv2si3"
9705   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9706         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9707                      (match_operand:DI 2 "arith_reg_operand" "r")))]
9708   "TARGET_SHMEDIA"
9709   "mshlld.l     %1, %2, %0"
9710   [(set_attr "type" "arith_media")])
9711
9712 (define_insn "ashlv4hi3"
9713   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9714         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9715                      (match_operand:DI 2 "arith_reg_operand" "r")))]
9716   "TARGET_SHMEDIA"
9717   "mshlld.w     %1, %2, %0"
9718   [(set_attr "type" "arith_media")])
9719
9720 (define_insn "lshrv2si3"
9721   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9722         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9723                        (match_operand:DI 2 "arith_reg_operand" "r")))]
9724   "TARGET_SHMEDIA"
9725   "mshlrd.l     %1, %2, %0"
9726   [(set_attr "type" "arith_media")])
9727
9728 (define_insn "lshrv4hi3"
9729   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9730         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9731                        (match_operand:DI 2 "arith_reg_operand" "r")))]
9732   "TARGET_SHMEDIA"
9733   "mshlrd.w     %1, %2, %0"
9734   [(set_attr "type" "arith_media")])
9735
9736 (define_insn "subv2si3"
9737   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9738         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
9739                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9740   "TARGET_SHMEDIA"
9741   "msub.l       %N1, %2, %0"
9742   [(set_attr "type" "arith_media")])
9743
9744 (define_insn "subv4hi3"
9745   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9746         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
9747                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9748   "TARGET_SHMEDIA"
9749   "msub.w       %N1, %2, %0"
9750   [(set_attr "type" "arith_media")])
9751
9752 (define_insn "sssubv2si3"
9753   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9754         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
9755                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9756   "TARGET_SHMEDIA"
9757   "msubs.l      %N1, %2, %0"
9758   [(set_attr "type" "mcmp_media")])
9759
9760 (define_insn "ussubv8qi3"
9761   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9762         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
9763                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9764   "TARGET_SHMEDIA"
9765   "msubs.ub     %1, %2, %0"
9766   [(set_attr "type" "mcmp_media")])
9767
9768 (define_insn "sssubv4hi3"
9769   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9770         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
9771                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9772   "TARGET_SHMEDIA"
9773   "msubs.w      %N1, %2, %0"
9774   [(set_attr "type" "mcmp_media")])
9775
9776 ;; Floating Point Intrinsics
9777
9778 (define_insn "fcosa_s"
9779   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9780         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
9781                    UNSPEC_FCOSA))]
9782   "TARGET_SHMEDIA"
9783   "fcosa.s      %1, %0"
9784   [(set_attr "type" "atrans_media")])
9785
9786 (define_insn "fsina_s"
9787   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9788         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
9789                    UNSPEC_FSINA))]
9790   "TARGET_SHMEDIA"
9791   "fsina.s      %1, %0"
9792   [(set_attr "type" "atrans_media")])
9793
9794 (define_insn "fipr"
9795   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9796         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
9797                                                     "fp_arith_reg_operand" "f")
9798                                                    (match_operand:V4SF 2
9799                                                     "fp_arith_reg_operand" "f"))
9800                                          (const_vector [(const_int 0)]))
9801                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
9802                                          (const_vector [(const_int 1)])))
9803                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
9804                                          (const_vector [(const_int 2)]))
9805                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
9806                                          (const_vector [(const_int 3)])))))]
9807   "TARGET_SHMEDIA"
9808   "fipr %1, %2, %0"
9809   [(set_attr "type" "fparith_media")])
9810
9811 (define_insn "fsrra_s"
9812   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9813         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
9814                    UNSPEC_FSRRA))]
9815   "TARGET_SHMEDIA"
9816   "fsrra.s      %1, %0"
9817   [(set_attr "type" "atrans_media")])
9818
9819 (define_insn "ftrv"
9820   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
9821         (plus:V4SF
9822          (plus:V4SF
9823           (mult:V4SF
9824            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
9825                             (const_vector [(const_int 0) (const_int 5)
9826                                            (const_int 10) (const_int 15)]))
9827            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
9828           (mult:V4SF
9829            (vec_select:V4SF (match_dup 1)
9830                             (const_vector [(const_int 4) (const_int 9)
9831                                            (const_int 14) (const_int 3)]))
9832            (vec_select:V4SF (match_dup 2)
9833                             (const_vector [(const_int 1) (const_int 2)
9834                                            (const_int 3) (const_int 0)]))))
9835          (plus:V4SF
9836           (mult:V4SF
9837            (vec_select:V4SF (match_dup 1)
9838                             (const_vector [(const_int 8) (const_int 13)
9839                                            (const_int 2) (const_int 7)]))
9840            (vec_select:V4SF (match_dup 2)
9841                             (const_vector [(const_int 2) (const_int 3)
9842                                            (const_int 0) (const_int 1)])))
9843           (mult:V4SF
9844            (vec_select:V4SF (match_dup 1)
9845                             (const_vector [(const_int 12) (const_int 1)
9846                                            (const_int 6) (const_int 11)]))
9847            (vec_select:V4SF (match_dup 2)
9848                             (const_vector [(const_int 3) (const_int 0)
9849                                            (const_int 1) (const_int 2)]))))))]
9850   "TARGET_SHMEDIA"
9851   "ftrv %1, %2, %0"
9852   [(set_attr "type" "fparith_media")])
9853
9854 ;; The following description  models the
9855 ;; SH4 pipeline using the DFA based scheduler. 
9856 ;; The DFA based description is better way to model 
9857 ;; a superscalar pipeline as compared to function unit
9858 ;; reservation model.   
9859 ;; 1. The function unit based model is oriented to describe at most one 
9860 ;;    unit reservation by each insn. It is difficult to model unit reservations in multiple 
9861 ;;    pipeline units by same insn. This can be done using DFA based description.
9862 ;; 2. The execution performance of DFA based scheduler does not depend on processor complexity.
9863 ;; 3. Writing all unit reservations for an instruction class is more natural description 
9864 ;;    of the pipeline and makes interface of the hazard recognizer simpler than the 
9865 ;;    old function unit based model.
9866 ;; 4. The DFA model is richer and is a part of greater overall framework of RCSP.
9867
9868
9869 ;; Two automata are defined to reduce number of states
9870 ;; which a single large automaton will have.(Factoring)
9871
9872 (define_automaton "inst_pipeline,fpu_pipe")
9873
9874 ;; This unit is basically the decode unit of the processor.
9875 ;; Since SH4 is a dual issue machine,it is as if there are two 
9876 ;; units so that any insn can be processed by either one
9877 ;; of the decoding unit.
9878
9879 (define_cpu_unit "pipe_01,pipe_02" "inst_pipeline")
9880
9881
9882 ;; The fixed point arithmetic calculator(?? EX Unit).
9883
9884 (define_cpu_unit  "int" "inst_pipeline")
9885
9886 ;; f1_1 and f1_2 are floating point units.Actually there is
9887 ;; a f1 unit which can overlap with other f1 unit but
9888 ;; not another F1 unit.It is as though there were two
9889 ;; f1 units.
9890
9891 (define_cpu_unit "f1_1,f1_2" "fpu_pipe")
9892
9893 ;; The floating point units.
9894
9895 (define_cpu_unit "F1,F2,F3,FS" "fpu_pipe")
9896
9897 ;; This is basically the MA unit of SH4
9898 ;; used in LOAD/STORE pipeline.
9899
9900 (define_cpu_unit "memory" "inst_pipeline")
9901
9902 ;; The address calculator used for branch instructions.
9903 ;; This will be reserved with "issue" of branch instructions
9904 ;; and this is to make sure that  no two branch instructions 
9905 ;; can be issued in parallel. 
9906
9907 (define_cpu_unit "pcr_addrcalc" "inst_pipeline")
9908
9909 ;; ----------------------------------------------------
9910 ;; This reservation is to simplify the dual issue description.
9911
9912 (define_reservation  "issue"  "pipe_01|pipe_02")
9913
9914 ;; This is to express the locking of D stage.
9915
9916 (define_reservation  "d_lock" "pipe_01+pipe_02")
9917
9918 ;; This is to simplify description where F1,F2,FS
9919 ;; are used simultaneously.
9920
9921 (define_reservation "fpu" "F1+F2+FS")
9922
9923 ;; This is to highlight the fact that f1 
9924 ;; cannot overlap with F1.
9925
9926 (exclusion_set  "f1_1,f1_2" "F1")
9927
9928 ;; Although reg moves have a latency of zero 
9929 ;; we need to highlight that they use D stage
9930 ;; for one cycle.
9931
9932 (define_insn_reservation "reg_mov" 0
9933                (eq_attr "type" "move,fmove")
9934               "issue")
9935
9936 ;; Other MT  group intructions(1 step operations)
9937 ;; Group:       MT
9938 ;; Latency:     1
9939 ;; Issue Rate:  1
9940
9941 (define_insn_reservation "mt" 1
9942                       (eq_attr "insn_class" "mt_group")
9943                       "issue,nothing")
9944
9945 ;; Fixed Point Arithmetic Instructions(1 step operations)
9946 ;; Group:       EX
9947 ;; Latency:     1
9948 ;; Issue Rate:  1
9949
9950 (define_insn_reservation "simple_arith" 1 
9951             (eq_attr "insn_class" "ex_group")
9952             "issue,int")
9953
9954 ;; Load Store instructions. (MOV.[BWL]@(d,GBR)
9955 ;; Group:       LS
9956 ;; Latency:     2
9957 ;; Issue Rate:  1
9958
9959 (define_insn_reservation "load_store" 2
9960        (eq_attr "type" "load,load_si,pcload,pcload_si,store")
9961        "issue,memory*2")
9962
9963 ;; Branch (BF,BF/S,BT,BT/S,BRA)
9964 ;; Group:       BR
9965 ;; Latency:     2 (or 1) Actually Observed to be 5/7
9966 ;; Issue Rate:  1
9967 ;; The latency is 1 when displacement is 0.
9968 ;; This reservation can be further broken into 2
9969 ;;    1. branch_zero : One with latency 1 and in the TEST 
9970 ;;       part it also checks for 0 (ZERO) displacement 
9971 ;;    2. branch: Latency 2.
9972
9973 (define_insn_reservation "branch_zero"  5
9974              (and (eq_attr "type" "cbranch")
9975                   (eq_attr "length" "2"))
9976              "(issue+pcr_addrcalc),pcr_addrcalc,nothing")
9977
9978 (define_insn_reservation "branch"  7
9979              (eq_attr "type" "cbranch")
9980              "(issue+pcr_addrcalc),pcr_addrcalc,nothing")
9981
9982 ;; Branch Far (JMP,RTS,BRAF)
9983 ;; Group:       CO
9984 ;; Latency:     3
9985 ;; Issue Rate:  2
9986 ;;    Since issue stage (D stage) is blocked for 2nd cycle, 
9987 ;;    cpu_unit  int  is reserved since it might be required for far
9988 ;;    address calculation.
9989
9990 (define_insn_reservation "branch_far" 12
9991          (and (eq_attr "type" "jump,return")
9992               (eq_attr "length" "6"))
9993          "d_lock*2,int+pcr_addrcalc,pcr_addrcalc")
9994
9995 ;; RTE
9996 ;; Group:       CO
9997 ;; atency:      5
9998 ;; Issue Rate:  5
9999 ;; this instruction can be executed in any of the pipelines 
10000 ;; and blocks the pipeline for next 4 stages.
10001
10002 (define_insn_reservation "return_from_exp" 5
10003           (eq_attr "type" "rte")
10004          "(issue+pcr_addrcalc),d_lock*4,int+pcr_addrcalc,nothing")
10005
10006 ;; OCBP, OCBWB
10007 ;; Group:       CO
10008 ;; Latency:     5
10009 ;; Issue Rate:  1
10010
10011 (define_insn_reservation "ocbwb"  5
10012           (eq_attr "insn_class" "cwb") 
10013            "issue,(int+memory),memory*5")
10014                 
10015 ;; LDS to PR,JSR
10016 ;; Group:       CO
10017 ;; Latency:     3
10018 ;; Issue Rate:  2
10019 ;; The SX stage is blocked for last 2 cycles.
10020
10021 (define_insn_reservation "lds_to_pr" 3 
10022           (eq_attr "type" "prset,call,sfunc") 
10023           "(issue+pcr_addrcalc),(issue+int+pcr_addrcalc),(int+pcr_addrcalc)*2")
10024
10025 ;; LDS.L to PR 
10026 ;; Group:       CO
10027 ;; Latency:     3
10028 ;; Issue Rate:  2
10029 ;; The SX unit is blocked for last 2 cycles.
10030  
10031 (define_insn_reservation "ldsmem_to_pr"  3
10032       (eq_attr "type" "pload") 
10033      "(issue+pcr_addrcalc),(issue+int+pcr_addrcalc),(int+memory+pcr_addrcalc),(int+pcr_addrcalc)")
10034
10035 ;; STS from PR
10036 ;; Group:       CO
10037 ;; Latency:     2
10038 ;; Issue Rate:  2
10039 ;; The SX unit in second and third cycles.
10040
10041 (define_insn_reservation "sts_from_pr" 2
10042         (eq_attr "type" "prget")
10043        "(issue+pcr_addrcalc),(pipe_01+int+pcr_addrcalc),(int+pcr_addrcalc),nothing")
10044
10045 ;; STS.L from PR
10046 ;; Group:       CO
10047 ;; Latency:     2
10048 ;; Issue Rate:  2
10049
10050 (define_insn_reservation "prload_mem" 2 
10051           (eq_attr "type" "pstore")
10052            "(issue+pcr_addrcalc),(pipe_01+int+pcr_addrcalc),(int+memory+pcr_addrcalc),memory")
10053
10054 ;; LDS to FPSCR
10055 ;; Group:       CO
10056 ;; Latency:     4
10057 ;; Issue Rate:  1
10058 ;; F1 is blocked for last three cycles. 
10059
10060 (define_insn_reservation "fpscr_store" 4
10061         (eq_attr "insn_class" "lds_to_fpscr")
10062        "issue,int,F1*3")
10063
10064 ;; LDS.L to FPSCR
10065 ;; Group:       CO
10066 ;; Latency:     1 / 4
10067 ;; Latency to update Rn is 1 and latency to update FPSCR is 4
10068 ;; Issue Rate:  1
10069 ;; F1 is blocked for last three cycles.
10070
10071 (define_insn_reservation "fpscr_store_mem" 4
10072         (eq_attr "insn_class"  "ldsmem_to_fpscr") 
10073         "issue,(int+memory),(F1+memory),F1*2")
10074
10075 \f
10076 ;; Fixed point multiplication (DMULS.L DMULU.L MUL.L MULS.W,MULU.W)
10077 ;; Group:       CO
10078 ;; Latency:     4 / 4
10079 ;; Issue Rate:  1
10080
10081 (define_insn_reservation "multi" 4
10082         (eq_attr "type" "smpy,dmpy")
10083         "issue,(issue+int+f1_1),(int+f1_1),(f1_1|f1_2)*2,F2,FS")
10084
10085
10086 ;; Single precision floating point computation FCMP/EQ,
10087 ;; FCP/GT, FADD, FLOAT, FMAC, FMUL, FSUB, FTRC, FRVHG, FSCHG
10088 ;; Group:       FE
10089 ;; Latency:     4
10090 ;; Issue Rate:  1
10091
10092 (define_insn_reservation "fp_arith"  4
10093               (eq_attr "type" "fp")
10094               "issue,F1,F2,FS")
10095
10096 ;; Single Precision FDIV/SQRT
10097 ;; Group:       FE
10098 ;; Latency:     12/13
10099 ;; Issue Rate:  1
10100
10101 (define_insn_reservation "fp_div" 13
10102                (eq_attr "type" "fdiv")
10103                "issue,F1+F3,F1+F2+F3,F3*7,F1+F3,F2,FS")
10104
10105 ;; Double Precision floating point computation
10106 ;; (FCNVDS, FCNVSD, FLOAT, FTRC)
10107 ;; Group:       FE
10108 ;; Latency:     (3,4)/5
10109 ;; Issue Rate:  1
10110
10111 (define_insn_reservation "dp_float" 5
10112          (eq_attr "type" "dfp_conv")
10113          "issue,F1,F1+F2,F2+FS,FS")
10114
10115 ;; Double-precision floating-point (FADD ,FMUL,FSUB) 
10116 ;; Group:       FE
10117 ;; Latency:     (7,8)/9
10118 ;; Issue Rate:  1
10119
10120 (define_insn_reservation "fp_double_arith" 9
10121         (eq_attr "type" "dfp_arith")
10122         "issue,F1,F1+F2,fpu*4,F2+FS,FS")
10123
10124 ;; Double-precision FCMP (FCMP/EQ,FCMP/GT) 
10125 ;; Group:       FE
10126 ;; Latency:     3/5
10127 ;; Issue Rate:  2
10128
10129 (define_insn_reservation "fp_double_cmp" 5 
10130         (eq_attr "type" "dfp_cmp")
10131         "issue,(issue+F1),F1+F2,F2+FS,FS")
10132
10133 ;; Double precision FDIV/SQRT
10134 ;; Group:       FE
10135 ;; Latency:     (24,25)/26
10136 ;; Issue Rate:  1
10137
10138 (define_insn_reservation "dp_div" 26
10139         (eq_attr "type" "dfdiv")
10140         "issue,F1+F3,F1+F2+F3,F2+F3+FS,F3*16,F1+F3,F1+F2+F3,fpu+F3,F2+FS,FS")
10141