OSDN Git Service

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