OSDN Git Service

* sh.h (LOAD_EXTEND_OP): QImode zero-extends on SHmedia.
[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 ;; pipeline model
172 (define_attr "pipe_model" "sh1,sh4,sh5media"
173   (const
174    (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
175           (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
176          (const_string "sh1"))))
177
178 ;; cbranch      conditional branch instructions
179 ;; jump         unconditional jumps
180 ;; arith        ordinary arithmetic
181 ;; arith3       a compound insn that behaves similarly to a sequence of
182 ;;              three insns of type arith
183 ;; arith3b      like above, but might end with a redirected branch
184 ;; load         from memory
185 ;; load_si      Likewise, SImode variant for general register.
186 ;; store        to memory
187 ;; move         register to register
188 ;; fmove        register to register, floating point
189 ;; smpy         word precision integer multiply
190 ;; dmpy         longword or doublelongword precision integer multiply
191 ;; return       rts
192 ;; pload        load of pr reg, which can't be put into delay slot of rts
193 ;; prset        copy register to pr reg, ditto
194 ;; pstore       store of pr reg, which can't be put into delay slot of jsr
195 ;; prget        copy pr to register, ditto
196 ;; pcload       pc relative load of constant value
197 ;; pcload_si    Likewise, SImode variant for general register.
198 ;; rte          return from exception
199 ;; sfunc        special function call with known used registers
200 ;; call         function call
201 ;; fp           floating point
202 ;; fdiv         floating point divide (or square root)
203 ;; gp_fpul      move between general purpose register and fpul
204 ;; dfp_arith, dfp_cmp,dfp_conv
205 ;; dfdiv        double precision floating point divide (or square root)
206 ;; arith_media  SHmedia arithmetic, logical, and shift instructions
207 ;; cbranch_media SHmedia conditional branch instructions
208 ;; cmp_media    SHmedia compare instructions
209 ;; dfdiv_media  SHmedia double precision divide and square root
210 ;; dfmul_media  SHmedia double precision multiply instruction
211 ;; dfparith_media SHmedia double precision floating point arithmetic
212 ;; dfpconv_media SHmedia double precision floating point conversions
213 ;; dmpy_media   SHmedia longword multiply
214 ;; fcmp_media   SHmedia floating point compare instructions
215 ;; fdiv_media   SHmedia single precision divide and square root
216 ;; fload_media  SHmedia floating point register load instructions
217 ;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
218 ;; fparith_media SHmedia single precision floating point arithmetic
219 ;; fpconv_media SHmedia single precision floating point conversions
220 ;; fstore_media SHmedia floating point register store instructions
221 ;; gettr_media  SHmedia gettr instruction
222 ;; invalidate_line_media SHmedia invaldiate_line sequence
223 ;; jump_media   SHmedia unconditional branch instructions
224 ;; load_media   SHmedia general register load instructions
225 ;; pt_media     SHmedia pt instruction (expanded by assembler)
226 ;; ptabs_media  SHmedia ptabs instruction
227 ;; store_media  SHmedia general register store instructions
228 ;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
229 ;; mac_media    SHmedia mac-style fixed point operations
230 ;; d2mpy_media  SHmedia: two 32 bit integer multiplies
231 ;; atrans       SHmedia approximate transcendential functions
232 ;; ustore_media SHmedia unaligned stores
233 ;; nil          no-op move, will be deleted.
234
235 (define_attr "type"
236  "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_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
237   (const_string "other"))
238
239 ;; We define a new attribute namely "insn_class".We use
240 ;; this for DFA based pipeline description.
241 ;; Although the "type" attribute covers almost all insn 
242 ;; classes,it is more convenient to define new attribute
243 ;; for certain reservations.
244 ;;
245 ;; mt_group      SH4 "mt" group instructions.
246 ;;
247 ;; ex_group      SH4 "ex" group instructions.They mostly
248 ;;               overlap with arithmetic instructions but
249 ;;               new attribute defined to distinguish from
250 ;;               mt group instructions.
251 ;;
252 ;; lds_to_fpscr  The "type" attribute couldn't sufficiently
253 ;;               distinguish it from others.It is part of 
254 ;;               new attribute.Similar case with ldsmem_to_fpscr
255 ;;               and cwb. 
256
257 (define_attr "insn_class"
258              "mt_group,ex_group,lds_to_fpscr,ldsmem_to_fpscr,cwb,none"
259              (const_string "none"))
260
261 ;; Indicate what precision must be selected in fpscr for this insn, if any.
262
263 (define_attr "fp_mode" "single,double,none" (const_string "none"))
264
265 ; If a conditional branch destination is within -252..258 bytes away
266 ; from the instruction it can be 2 bytes long.  Something in the
267 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
268 ; branches are initially assumed to be 16 bytes long.
269 ; In machine_dependent_reorg, we split all branches that are longer than
270 ; 2 bytes.
271
272 ;; The maximum range used for SImode constant pool entries is 1018.  A final
273 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
274 ;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
275 ;; instruction around the pool table, 2 bytes of alignment before the table,
276 ;; and 30 bytes of alignment after the table.  That gives a maximum total
277 ;; pool size of 1058 bytes.
278 ;; Worst case code/pool content size ratio is 1:2 (using asms).
279 ;; Thus, in the worst case, there is one instruction in front of a maximum
280 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
281 ;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
282 ;; If we have a forward branch, the initial table will be put after the
283 ;; unconditional branch.
284 ;;
285 ;; ??? We could do much better by keeping track of the actual pcloads within
286 ;; the branch range and in the pcload range in front of the branch range.
287
288 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
289 ;; inside an le.
290 (define_attr "short_cbranch_p" "no,yes"
291   (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
292          (const_string "no")
293          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
294          (const_string "yes")
295          (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
296          (const_string "no")
297          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
298          (const_string "yes")
299          ] (const_string "no")))
300
301 (define_attr "med_branch_p" "no,yes"
302   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
303               (const_int 1988))
304          (const_string "yes")
305          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
306          (const_string "no")
307          (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
308               (const_int 8186))
309          (const_string "yes")
310          ] (const_string "no")))
311
312 (define_attr "med_cbranch_p" "no,yes"
313   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
314               (const_int 1986))
315          (const_string "yes")
316          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
317          (const_string "no")
318          (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
319                (const_int 8184))
320          (const_string "yes")
321          ] (const_string "no")))
322
323 (define_attr "braf_branch_p" "no,yes"
324   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
325          (const_string "no")
326          (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
327               (const_int 20660))
328          (const_string "yes")
329          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
330          (const_string "no")
331          (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
332               (const_int 65530))
333          (const_string "yes")
334          ] (const_string "no")))
335
336 (define_attr "braf_cbranch_p" "no,yes"
337   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
338          (const_string "no")
339          (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
340               (const_int 20658))
341          (const_string "yes")
342          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
343          (const_string "no")
344          (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
345               (const_int 65528))
346          (const_string "yes")
347          ] (const_string "no")))
348
349 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
350 ; For wider ranges, we need a combination of a code and a data part.
351 ; If we can get a scratch register for a long range jump, the code
352 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
353 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
354 ; long; otherwise, it must be 6 bytes long.
355
356 ; All other instructions are two bytes long by default.
357
358 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
359 ;; but getattrtab doesn't understand this.
360 (define_attr "length" ""
361   (cond [(eq_attr "type" "cbranch")
362          (cond [(eq_attr "short_cbranch_p" "yes")
363                 (const_int 2)
364                 (eq_attr "med_cbranch_p" "yes")
365                 (const_int 6)
366                 (eq_attr "braf_cbranch_p" "yes")
367                 (const_int 12)
368 ;; ??? using pc is not computed transitively.
369                 (ne (match_dup 0) (match_dup 0))
370                 (const_int 14)
371                 (ne (symbol_ref ("flag_pic")) (const_int 0))
372                 (const_int 24)
373                 ] (const_int 16))
374          (eq_attr "type" "jump")
375          (cond [(eq_attr "med_branch_p" "yes")
376                 (const_int 2)
377                 (and (eq (symbol_ref "GET_CODE (PREV_INSN (insn))")
378                          (symbol_ref "INSN"))
379                      (eq (symbol_ref "INSN_CODE (PREV_INSN (insn))")
380                          (symbol_ref "code_for_indirect_jump_scratch")))
381                 (if_then_else (eq_attr "braf_branch_p" "yes")
382                               (const_int 6)
383                               (const_int 10))
384                 (eq_attr "braf_branch_p" "yes")
385                 (const_int 10)
386 ;; ??? using pc is not computed transitively.
387                 (ne (match_dup 0) (match_dup 0))
388                 (const_int 12)
389                 (ne (symbol_ref ("flag_pic")) (const_int 0))
390                 (const_int 22)
391                 ] (const_int 14))
392          (eq_attr "type" "pt_media")
393          (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
394                        (const_int 20) (const_int 12))
395          ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
396                          (const_int 4)
397                          (const_int 2))))
398
399 ;; (define_function_unit {name} {num-units} {n-users} {test}
400 ;;                       {ready-delay} {issue-delay} [{conflict-list}])
401
402 ;; Load and store instructions save a cycle if they are aligned on a
403 ;; four byte boundary.  Using a function unit for stores encourages
404 ;; gcc to separate load and store instructions by one instruction,
405 ;; which makes it more likely that the linker will be able to word
406 ;; align them when relaxing.
407
408 ;; Loads have a latency of two.
409 ;; However, call insns can have a delay slot, so that we want one more
410 ;; insn to be scheduled between the load of the function address and the call.
411 ;; This is equivalent to a latency of three.
412 ;; We cannot use a conflict list for this, because we need to distinguish
413 ;; between the actual call address and the function arguments.
414 ;; ADJUST_COST can only properly handle reductions of the cost, so we
415 ;; use a latency of three here.
416 ;; We only do this for SImode loads of general registers, to make the work
417 ;; for ADJUST_COST easier.
418 (define_function_unit "memory" 1 0
419   (and (eq_attr "pipe_model" "sh1")
420        (eq_attr "type" "load_si,pcload_si"))
421   3 2)
422 (define_function_unit "memory" 1 0
423   (and (eq_attr "pipe_model" "sh1")
424        (eq_attr "type" "load,pcload,pload,store,pstore"))
425   2 2)
426
427 (define_function_unit "int"    1 0
428   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "arith3,arith3b")) 3 3)
429
430 (define_function_unit "int"    1 0
431   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dyn_shift")) 2 2)
432
433 (define_function_unit "int"    1 0
434   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "!arith3,arith3b,dyn_shift")) 1 1)
435
436 ;; ??? These are approximations.
437 (define_function_unit "mpy"    1 0
438   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "smpy")) 2 2)
439 (define_function_unit "mpy"    1 0
440   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dmpy")) 3 3)
441
442 (define_function_unit "fp"     1 0
443   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fp,fmove")) 2 1)
444 (define_function_unit "fp"     1 0
445   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fdiv")) 13 12)
446
447
448 ;; SH4 scheduling
449 ;; The SH4 is a dual-issue implementation, thus we have to multiply all
450 ;; costs by at least two.
451 ;; There will be single increments of the modeled that don't correspond
452 ;; to the actual target ;; whenever two insns to be issued depend one a
453 ;; single resource, and the scheduler picks to be the first one.
454 ;; If we multiplied the costs just by two, just two of these single
455 ;; increments would amount to an actual cycle.  By picking a larger
456 ;; factor, we can ameliorate the effect; However, we then have to make sure
457 ;; that only two insns are modeled as issued per actual cycle.
458 ;; Moreover, we need a way to specify the latency of insns that don't
459 ;; use an actual function unit.
460 ;; We use an 'issue' function unit to do that, and a cost factor of 10.
461
462 (define_function_unit "issue" 2 0
463   (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "!nil,arith3"))
464   10 10)
465
466 (define_function_unit "issue" 2 0
467   (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "arith3"))
468   30 30)
469
470 ;; There is no point in providing exact scheduling information about branches,
471 ;; because they are at the starts / ends of basic blocks anyways.
472
473 ;; Some insns cannot be issued before/after another insn in the same cycle,
474 ;; irrespective of the type of the other insn.
475
476 ;; default is dual-issue, but can't be paired with an insn that
477 ;; uses multiple function units.
478 (define_function_unit "single_issue"     1 0
479   (and (eq_attr "pipe_model" "sh4")
480        (eq_attr "type" "!smpy,dmpy,pload,pstore,dfp_cmp,gp_fpul,call,sfunc,arith3,arith3b"))
481   1 10
482   [(eq_attr "type" "smpy,dmpy,pload,pstore,dfp_cmp,gp_fpul")])
483
484 (define_function_unit "single_issue"     1 0
485   (and (eq_attr "pipe_model" "sh4")
486        (eq_attr "type" "smpy,dmpy,pload,pstore,dfp_cmp,gp_fpul"))
487   10 10
488   [(const_int 1)])
489
490 ;; arith3 insns are always pairable at the start, but not inecessarily at
491 ;; the end; however, there doesn't seem to be a way to express that.
492 (define_function_unit "single_issue"     1 0
493   (and (eq_attr "pipe_model" "sh4")
494        (eq_attr "type" "arith3"))
495   30 20
496   [(const_int 1)])
497
498 ;; arith3b insn are pairable at the end and have latency that prevents pairing
499 ;; with the following branch, but we don't want this latency be respected;
500 ;; When the following branch is immediately adjacent, we can redirect the
501 ;; internal branch, which is likly to be a larger win.
502 (define_function_unit "single_issue"     1 0
503   (and (eq_attr "pipe_model" "sh4")
504        (eq_attr "type" "arith3b"))
505   20 20
506   [(const_int 1)])
507
508 ;; calls introduce a longisch delay that is likely to flush the pipelines.
509 (define_function_unit "single_issue"     1 0
510   (and (eq_attr "pipe_model" "sh4")
511        (eq_attr "type" "call,sfunc"))
512   160 160
513   [(eq_attr "type" "!call") (eq_attr "type" "call")])
514
515 ;; Load and store instructions have no alignment peculiarities for the SH4,
516 ;; but they use the load-store unit, which they share with the fmove type
517 ;; insns (fldi[01]; fmov frn,frm; flds; fsts; fabs; fneg) .
518 ;; Loads have a latency of two.
519 ;; However, call insns can only paired with a preceding insn, and have
520 ;; a delay slot, so that we want two more insns to be scheduled between the
521 ;; load of the function address and the call.  This is equivalent to a
522 ;; latency of three.
523 ;; We cannot use a conflict list for this, because we need to distinguish
524 ;; between the actual call address and the function arguments.
525 ;; ADJUST_COST can only properly handle reductions of the cost, so we
526 ;; use a latency of three here, which gets multiplied by 10 to yield 30.
527 ;; We only do this for SImode loads of general registers, to make the work
528 ;; for ADJUST_COST easier.
529
530 ;; When specifying different latencies for different insns using the
531 ;; the same function unit, genattrtab.c assumes a 'FIFO constraint'
532 ;; so that the blockage is at least READY-COST (E) + 1 - READY-COST (C)
533 ;; for an executing insn E and a candidate insn C.
534 ;; Therefore, we define three different function units for load_store:
535 ;; load_store, load and load_si.
536
537 (define_function_unit "load_si" 1 0
538   (and (eq_attr "pipe_model" "sh4")
539        (eq_attr "type" "load_si,pcload_si")) 30 10)
540 (define_function_unit "load" 1 0
541   (and (eq_attr "pipe_model" "sh4")
542        (eq_attr "type" "load,pcload,pload")) 20 10)
543 (define_function_unit "load_store" 1 0
544   (and (eq_attr "pipe_model" "sh4")
545        (eq_attr "type" "load_si,pcload_si,load,pcload,pload,store,pstore,fmove"))
546   10 10)
547
548 (define_function_unit "int"    1 0
549   (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "arith,dyn_shift")) 10 10)
550
551 ;; Again, we have to pretend a lower latency for the "int" unit to avoid a
552 ;; spurious FIFO constraint; the multiply instructions use the "int"
553 ;; unit actually only for two cycles.
554 (define_function_unit "int"    1 0
555   (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "smpy,dmpy")) 20 20)
556
557 ;; We use a fictous "mpy" unit to express the actual latency.
558 (define_function_unit "mpy"    1 0
559   (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "smpy,dmpy")) 40 20)
560
561 ;; Again, we have to pretend a lower latency for the "int" unit to avoid a
562 ;; spurious FIFO constraint.
563 (define_function_unit "int"     1 0
564   (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "gp_fpul")) 10 10)
565
566 ;; We use a fictous "gp_fpul" unit to express the actual latency.
567 (define_function_unit "gp_fpul"     1 0
568   (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "gp_fpul")) 20 10)
569
570 ;; ??? multiply uses the floating point unit, but with a two cycle delay.
571 ;; Thus, a simple single-precision fp operation could finish if issued in
572 ;; the very next cycle, but stalls when issued two or three cycles later.
573 ;; Similarily, a divide / sqrt can work without stalls if issued in
574 ;; the very next cycle, while it would have to block if issued two or
575 ;; three cycles later.
576 ;; There is no way to model this with gcc's function units.  This problem is
577 ;; actually mentioned in md.texi.  Tackling this problem requires first that
578 ;; it is possible to speak about the target in an open discussion.
579 ;;
580 ;; However, simple double-precision operations always conflict.
581
582 (define_function_unit "fp"    1 0
583   (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "smpy,dmpy")) 40 40
584   [(eq_attr "type" "dfp_cmp,dfp_conv,dfp_arith")])
585
586 ;; The "fp" unit is for pipeline stages F1 and F2.
587
588 (define_function_unit "fp"     1 0
589   (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "fp")) 30 10)
590
591 ;; Again, we have to pretend a lower latency for the "fp" unit to avoid a
592 ;; spurious FIFO constraint; the bulk of the fdiv type insns executes in
593 ;; the F3 stage.
594 (define_function_unit "fp"     1 0
595   (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "fdiv")) 30 10)
596
597 ;; The "fdiv" function unit models the aggregate effect of the F1, F2 and F3
598 ;; pipeline stages on the pipelining of fdiv/fsqrt insns.
599 ;; We also use it to give the actual latency here.
600 ;; fsqrt is actually one cycle faster than fdiv (and the value used here),
601 ;; but that will hardly matter in practice for scheduling.
602 (define_function_unit "fdiv"     1 0
603   (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "fdiv")) 120 100)
604
605 ;; There is again a late use of the "fp" unit by [d]fdiv type insns
606 ;; that we can't express.
607
608 (define_function_unit "fp"     1 0
609   (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "dfp_cmp,dfp_conv")) 40 20)
610
611 (define_function_unit "fp"     1 0
612   (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "dfp_arith")) 80 60)
613
614 (define_function_unit "fp"     1 0
615   (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "dfdiv")) 230 10)
616
617 (define_function_unit "fdiv"     1 0
618   (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "dfdiv")) 230 210)
619
620 ;; SH-5 SHmedia scheduling
621 ;; When executing SHmedia code, the SH-5 is a fairly straightforward
622 ;; single-issue machine.  It has four pipelines, the branch unit (br),
623 ;; the integer and multimedia unit (imu), the load/store unit (lsu), and
624 ;; the floating point unit (fpu).
625 ;; Here model the instructions with a latency greater than one cycle.
626
627 ;; Every instruction on SH-5 occupies the issue resource for at least one
628 ;; cycle.
629 (define_function_unit "sh5issue" 1 0
630   (and (eq_attr "pipe_model" "sh5media")
631        (eq_attr "type" "!pt_media,ptabs_media,invalidate_line_media,dmpy_media,load_media,fload_media,fcmp_media,fmove_media,fparith_media,dfparith_media,fpconv_media,dfpconv_media,dfmul_media,store_media,fstore_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media")) 1 1)
632
633 ;; Specify the various types of instruction which have latency > 1
634 (define_function_unit "sh5issue" 1 0
635   (and (eq_attr "pipe_model" "sh5media")
636        (eq_attr "type" "mcmp_media")) 2 1)
637
638 (define_function_unit "sh5issue" 1 0
639   (and (eq_attr "pipe_model" "sh5media")
640        (eq_attr "type" "dmpy_media,load_media,fcmp_media,mac_media")) 3 1)
641 ;; but see sh_adjust_cost for mac_media exception.
642
643 (define_function_unit "sh5issue" 1 0
644   (and (eq_attr "pipe_model" "sh5media")
645        (eq_attr "type" "fload_media,fmove_media")) 4 1)
646
647 (define_function_unit "sh5issue" 1 0
648   (and (eq_attr "pipe_model" "sh5media")
649        (eq_attr "type" "d2mpy_media")) 4 2)
650
651 (define_function_unit "sh5issue" 1 0
652   (and (eq_attr "pipe_model" "sh5media")
653        (eq_attr "type" "pt_media,ptabs_media")) 5 1)
654
655 (define_function_unit "sh5issue" 1 0
656   (and (eq_attr "pipe_model" "sh5media")
657        (eq_attr "type" "fparith_media,dfparith_media,fpconv_media,dfpconv_media")) 6 1)
658
659 (define_function_unit "sh5issue" 1 0
660   (and (eq_attr "pipe_model" "sh5media")
661        (eq_attr "type" "invalidate_line_media")) 7 7)
662
663 (define_function_unit "sh5issue" 1 0
664   (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfmul_media")) 9 4)
665
666 (define_function_unit "sh5issue" 1 0
667   (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "atrans_media")) 10 5)
668
669 ;; Floating-point divide and square-root occupy an additional resource,
670 ;; which is not internally pipelined.  However, other instructions
671 ;; can continue to issue.
672 (define_function_unit "sh5fds" 1 0
673   (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "fdiv_media"))  19 19)
674
675 (define_function_unit "sh5fds" 1 0
676   (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfdiv_media")) 35 35)
677
678 ; Definitions for filling branch delay slots.
679
680 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
681
682 ;; ??? This should be (nil) instead of (const_int 0)
683 (define_attr "hit_stack" "yes,no"
684         (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
685                    (const_int 0))
686                (const_string "no")]
687               (const_string "yes")))
688
689 (define_attr "interrupt_function" "no,yes"
690   (const (symbol_ref "current_function_interrupt")))
691
692 (define_attr "in_delay_slot" "yes,no"
693   (cond [(eq_attr "type" "cbranch") (const_string "no")
694          (eq_attr "type" "pcload,pcload_si") (const_string "no")
695          (eq_attr "needs_delay_slot" "yes") (const_string "no")
696          (eq_attr "length" "2") (const_string "yes")
697          ] (const_string "no")))
698
699 (define_attr "is_sfunc" ""
700   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
701
702 (define_attr "is_mac_media" ""
703   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
704
705 (define_delay
706   (eq_attr "needs_delay_slot" "yes")
707   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
708
709 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
710 ;; and thus we can't put a pop instruction in its delay slot.
711 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
712 ;; instruction can go in the delay slot.
713
714 ;; Since a normal return (rts) implicitly uses the PR register,
715 ;; we can't allow PR register loads in an rts delay slot.
716
717 (define_delay
718   (eq_attr "type" "return")
719   [(and (eq_attr "in_delay_slot" "yes")
720         (ior (and (eq_attr "interrupt_function" "no")
721                   (eq_attr "type" "!pload,prset"))
722              (and (eq_attr "interrupt_function" "yes")
723                   (ior
724                    (ne (symbol_ref "TARGET_SH3") (const_int 0))
725                    (eq_attr "hit_stack" "no"))))) (nil) (nil)])
726
727 ;; Since a call implicitly uses the PR register, we can't allow
728 ;; a PR register store in a jsr delay slot.
729
730 (define_delay
731   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
732   [(and (eq_attr "in_delay_slot" "yes")
733         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
734
735 ;; Say that we have annulled true branches, since this gives smaller and
736 ;; faster code when branches are predicted as not taken.
737
738 (define_delay
739   (and (eq_attr "type" "cbranch")
740        (ne (symbol_ref "TARGET_SH2") (const_int 0)))
741   [(eq_attr "in_delay_slot" "yes") (eq_attr "in_delay_slot" "yes") (nil)])
742 \f
743 ;; -------------------------------------------------------------------------
744 ;; SImode signed integer comparisons
745 ;; -------------------------------------------------------------------------
746
747 (define_insn ""
748   [(set (reg:SI T_REG)
749         (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
750                        (match_operand:SI 1 "arith_operand" "L,r"))
751                (const_int 0)))]
752   "TARGET_SH1"
753   "tst  %1,%0"
754   [(set_attr "insn_class" "mt_group")])
755
756 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
757 ;; That would still allow reload to create cmpi instructions, but would
758 ;; perhaps allow forcing the constant into a register when that is better.
759 ;; Probably should use r0 for mem/imm compares, but force constant into a
760 ;; register for pseudo/imm compares.
761
762 (define_insn "cmpeqsi_t"
763   [(set (reg:SI T_REG)
764         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
765                (match_operand:SI 1 "arith_operand" "N,rI,r")))]
766   "TARGET_SH1"
767   "@
768         tst     %0,%0
769         cmp/eq  %1,%0
770         cmp/eq  %1,%0"
771    [(set_attr "insn_class" "mt_group,mt_group,mt_group")])
772
773 (define_insn "cmpgtsi_t"
774   [(set (reg:SI T_REG)
775         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
776                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
777   "TARGET_SH1"
778   "@
779         cmp/gt  %1,%0
780         cmp/pl  %0"
781    [(set_attr "insn_class" "mt_group,mt_group")])
782
783 (define_insn "cmpgesi_t"
784   [(set (reg:SI T_REG)
785         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
786                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
787   "TARGET_SH1"
788   "@
789         cmp/ge  %1,%0
790         cmp/pz  %0"
791    [(set_attr "insn_class" "mt_group,mt_group")])
792
793 ;; -------------------------------------------------------------------------
794 ;; SImode unsigned integer comparisons
795 ;; -------------------------------------------------------------------------
796
797 (define_insn "cmpgeusi_t"
798   [(set (reg:SI T_REG)
799         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
800                 (match_operand:SI 1 "arith_reg_operand" "r")))]
801   "TARGET_SH1"
802   "cmp/hs       %1,%0"
803    [(set_attr "insn_class" "mt_group")])
804
805 (define_insn "cmpgtusi_t"
806   [(set (reg:SI T_REG)
807         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
808                 (match_operand:SI 1 "arith_reg_operand" "r")))]
809   "TARGET_SH1"
810   "cmp/hi       %1,%0"
811    [(set_attr "insn_class" "mt_group")])
812
813 ;; We save the compare operands in the cmpxx patterns and use them when
814 ;; we generate the branch.
815
816 (define_expand "cmpsi"
817   [(set (reg:SI T_REG)
818         (compare (match_operand:SI 0 "arith_operand" "")
819                  (match_operand:SI 1 "arith_operand" "")))]
820   "TARGET_SH1"
821   "
822 {
823   sh_compare_op0 = operands[0];
824   sh_compare_op1 = operands[1];
825   DONE;
826 }")
827 \f
828 ;; -------------------------------------------------------------------------
829 ;; DImode signed integer comparisons
830 ;; -------------------------------------------------------------------------
831
832 ;; ??? Could get better scheduling by splitting the initial test from the
833 ;; rest of the insn after reload.  However, the gain would hardly justify
834 ;; the sh.md size increase necessary to do that.
835
836 (define_insn ""
837   [(set (reg:SI T_REG)
838         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
839                        (match_operand:DI 1 "arith_operand" "r"))
840                (const_int 0)))]
841   "TARGET_SH1"
842   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
843                                  insn, operands);"
844   [(set_attr "length" "6")
845    (set_attr "type" "arith3b")])
846
847 (define_insn "cmpeqdi_t"
848   [(set (reg:SI T_REG)
849         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
850                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
851   "TARGET_SH1"
852   "@
853         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
854         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
855   [(set_attr "length" "6")
856    (set_attr "type" "arith3b")])
857
858 (define_split
859   [(set (reg:SI T_REG)
860         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
861                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
862 ;; If we applied this split when not optimizing, it would only be
863 ;; applied during the machine-dependent reorg, when no new basic blocks
864 ;; may be created.
865   "TARGET_SH1 && reload_completed && optimize"
866   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
867    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
868                            (label_ref (match_dup 6))
869                            (pc)))
870    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
871    (match_dup 6)]
872   "
873 {
874   operands[2]
875     = gen_rtx_REG (SImode,
876                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
877   operands[3]
878     = (operands[1] == const0_rtx
879        ? const0_rtx
880        : gen_rtx_REG (SImode,
881                       true_regnum (operands[1])
882                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
883   operands[4] = gen_lowpart (SImode, operands[0]);
884   operands[5] = gen_lowpart (SImode, operands[1]);
885   operands[6] = gen_label_rtx ();
886 }")
887
888 (define_insn "cmpgtdi_t"
889   [(set (reg:SI T_REG)
890         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
891                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
892   "TARGET_SH2"
893   "@
894         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
895         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
896   [(set_attr "length" "8")
897    (set_attr "type" "arith3")])
898
899 (define_insn "cmpgedi_t"
900   [(set (reg:SI T_REG)
901         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
902                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
903   "TARGET_SH2"
904   "@
905         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
906         cmp/pz\\t%S0"
907   [(set_attr "length" "8,2")
908    (set_attr "type" "arith3,arith")])
909 \f
910 ;; -------------------------------------------------------------------------
911 ;; DImode unsigned integer comparisons
912 ;; -------------------------------------------------------------------------
913
914 (define_insn "cmpgeudi_t"
915   [(set (reg:SI T_REG)
916         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
917                 (match_operand:DI 1 "arith_reg_operand" "r")))]
918   "TARGET_SH2"
919   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
920   [(set_attr "length" "8")
921    (set_attr "type" "arith3")])
922
923 (define_insn "cmpgtudi_t"
924   [(set (reg:SI T_REG)
925         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
926                 (match_operand:DI 1 "arith_reg_operand" "r")))]
927   "TARGET_SH2"
928   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
929   [(set_attr "length" "8")
930    (set_attr "type" "arith3")])
931
932 (define_insn "cmpeqdi_media"
933   [(set (match_operand:DI 0 "register_operand" "=r")
934         (eq:DI (match_operand:DI 1 "register_operand" "%r")
935                (match_operand:DI 2 "arith_reg_or_0_operand" "Nr")))]
936   "TARGET_SHMEDIA"
937   "cmpeq        %1, %N2, %0"
938   [(set_attr "type" "cmp_media")])
939
940 (define_insn "cmpgtdi_media"
941   [(set (match_operand:DI 0 "register_operand" "=r")
942         (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
943                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
944   "TARGET_SHMEDIA"
945   "cmpgt        %N1, %N2, %0"
946   [(set_attr "type" "cmp_media")])
947
948 (define_insn "cmpgtudi_media"
949   [(set (match_operand:DI 0 "register_operand" "=r")
950         (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
951                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
952   "TARGET_SHMEDIA"
953   "cmpgtu       %N1, %N2, %0"
954   [(set_attr "type" "cmp_media")])
955
956 ;; We save the compare operands in the cmpxx patterns and use them when
957 ;; we generate the branch.
958
959 (define_expand "cmpdi"
960   [(set (reg:SI T_REG)
961         (compare (match_operand:DI 0 "arith_operand" "")
962                  (match_operand:DI 1 "arith_operand" "")))]
963   "TARGET_SH2 || TARGET_SHMEDIA"
964   "
965 {
966   sh_compare_op0 = operands[0];
967   sh_compare_op1 = operands[1];
968   DONE;
969 }")
970 ;; -------------------------------------------------------------------------
971 ;; Conditional move instructions
972 ;; -------------------------------------------------------------------------
973
974 ;; The insn names may seem reversed, but note that cmveq performs the move
975 ;; if op1 == 0, and cmvne does it if op1 != 0.
976
977 (define_insn "movdicc_false"
978   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
979         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
980                              (const_int 0))
981          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
982          (match_operand:DI 3 "arith_reg_operand" "0")))]
983   "TARGET_SHMEDIA"
984   "cmveq        %1, %N2, %0"
985   [(set_attr "type" "arith_media")])
986
987 (define_insn "movdicc_true"
988   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
989         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
990                              (const_int 0))
991          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
992          (match_operand:DI 3 "arith_reg_operand" "0")))]
993   "TARGET_SHMEDIA"
994   "cmvne        %1, %N2, %0"
995   [(set_attr "type" "arith_media")])
996
997 (define_expand "movdicc"
998   [(set (match_operand:DI 0 "register_operand" "")
999         (if_then_else:DI (match_operand 1 "comparison_operator" "")
1000                          (match_operand:DI 2 "register_operand" "")
1001                          (match_operand:DI 3 "register_operand" "")))]
1002   "TARGET_SHMEDIA"
1003   "
1004 {
1005   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1006       && GET_MODE (sh_compare_op0) == DImode
1007       && sh_compare_op1 == const0_rtx)
1008     operands[1] = gen_rtx (GET_CODE (operands[1]), VOIDmode,
1009                            sh_compare_op0, sh_compare_op1);
1010   else
1011     {
1012       rtx tmp;
1013
1014       if (no_new_pseudos)
1015         FAIL;
1016
1017       tmp = gen_reg_rtx (DImode);
1018
1019       switch (GET_CODE (operands[1]))
1020         {
1021         case EQ:
1022           emit_insn (gen_seq (tmp));
1023           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
1024           break;
1025
1026         case NE:
1027           emit_insn (gen_seq (tmp));
1028           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
1029           break;
1030
1031         case GT:
1032           emit_insn (gen_sgt (tmp));
1033           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
1034           break;
1035
1036         case LT:
1037           emit_insn (gen_slt (tmp));
1038           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
1039           break;
1040
1041         case GE:
1042           emit_insn (gen_slt (tmp));
1043           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
1044           break;
1045
1046         case LE:
1047           emit_insn (gen_sgt (tmp));
1048           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
1049           break;
1050
1051         case GTU:
1052           emit_insn (gen_sgtu (tmp));
1053           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
1054           break;
1055
1056         case LTU:
1057           emit_insn (gen_sltu (tmp));
1058           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
1059           break;
1060
1061         case GEU:
1062           emit_insn (gen_sltu (tmp));
1063           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
1064           break;
1065
1066         case LEU:
1067           emit_insn (gen_sgtu (tmp));
1068           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
1069           break;
1070
1071         case UNORDERED:
1072           emit_insn (gen_sunordered (tmp));
1073           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
1074           break;
1075
1076         case ORDERED:
1077           emit_insn (gen_sunordered (tmp));
1078           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
1079           break;
1080
1081         case UNEQ:
1082         case UNGE:
1083         case UNGT:
1084         case UNLE:
1085         case UNLT:
1086         case LTGT:
1087           FAIL;
1088
1089         default:
1090           abort ();
1091         }
1092     }
1093 }")
1094 \f
1095 ;; -------------------------------------------------------------------------
1096 ;; Addition instructions
1097 ;; -------------------------------------------------------------------------
1098
1099 (define_expand "adddi3"
1100   [(set (match_operand:DI 0 "arith_reg_operand" "")
1101         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1102                  (match_operand:DI 2 "arith_operand" "")))]
1103   ""
1104   "
1105 {
1106   if (TARGET_SH1)
1107     {
1108       if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
1109         FAIL;
1110       operands[2] = force_reg (DImode, operands[2]);
1111       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1112       DONE;
1113     }
1114 }")
1115
1116 (define_insn "*adddi3_media"
1117   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1118         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1119                  (match_operand:DI 2 "arith_operand" "r,P")))]
1120   "TARGET_SHMEDIA"
1121   "@
1122         add     %1, %2, %0
1123         addi    %1, %2, %0"
1124   [(set_attr "type" "arith_media")])
1125
1126 (define_insn "adddi3z_media"
1127   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1128         (zero_extend:DI
1129          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1130                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1131   "TARGET_SHMEDIA"
1132   "addz.l       %1, %N2, %0"
1133   [(set_attr "type" "arith_media")])
1134
1135 (define_insn "adddi3_compact"
1136   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1137         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1138                  (match_operand:DI 2 "arith_reg_operand" "r")))
1139    (clobber (reg:SI T_REG))]
1140   "TARGET_SH1"
1141   "#"
1142   [(set_attr "length" "6")])
1143
1144 (define_split
1145   [(set (match_operand:DI 0 "arith_reg_operand" "")
1146         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1147                  (match_operand:DI 2 "arith_reg_operand" "")))
1148    (clobber (reg:SI T_REG))]
1149   "TARGET_SH1 && reload_completed"
1150   [(const_int 0)]
1151   "
1152 {
1153   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1154   high0 = gen_rtx_REG (SImode,
1155                        true_regnum (operands[0])
1156                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1157   high2 = gen_rtx_REG (SImode,
1158                        true_regnum (operands[2])
1159                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1160   emit_insn (gen_clrt ());
1161   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1162   emit_insn (gen_addc1 (high0, high0, high2));
1163   DONE;
1164 }")
1165
1166 (define_insn "addc"
1167   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1168         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1169                           (match_operand:SI 2 "arith_reg_operand" "r"))
1170                  (reg:SI T_REG)))
1171    (set (reg:SI T_REG)
1172         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1173   "TARGET_SH1"
1174   "addc %2,%0"
1175   [(set_attr "type" "arith")
1176    (set_attr "insn_class" "ex_group")])
1177
1178 (define_insn "addc1"
1179   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1180         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1181                           (match_operand:SI 2 "arith_reg_operand" "r"))
1182                  (reg:SI T_REG)))
1183    (clobber (reg:SI T_REG))]
1184   "TARGET_SH1"
1185   "addc %2,%0"
1186   [(set_attr "type" "arith")
1187    (set_attr "insn_class" "ex_group")])
1188
1189 (define_expand "addsi3"
1190   [(set (match_operand:SI 0 "arith_reg_operand" "")
1191         (plus:SI (match_operand:SI 1 "arith_operand" "")
1192                  (match_operand:SI 2 "arith_operand" "")))]
1193   ""
1194   "
1195 {
1196   if (TARGET_SHMEDIA)
1197     operands[1] = force_reg (SImode, operands[1]);
1198 }")
1199
1200 (define_insn "addsi3_media"
1201   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
1202         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1203                  (match_operand:SI 2 "arith_operand" "r,P")))]
1204   "TARGET_SHMEDIA"
1205   "@
1206         add.l   %1, %2, %0
1207         addi.l  %1, %2, %0"
1208   [(set_attr "type" "arith_media")])
1209
1210 (define_insn "*addsi3_compact"
1211   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1212         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1213                  (match_operand:SI 2 "arith_operand" "rI")))]
1214   "TARGET_SH1"
1215   "add  %2,%0"
1216   [(set_attr "type" "arith")
1217    (set_attr "insn_class" "ex_group")])
1218
1219 ;; -------------------------------------------------------------------------
1220 ;; Subtraction instructions
1221 ;; -------------------------------------------------------------------------
1222
1223 (define_expand "subdi3"
1224   [(set (match_operand:DI 0 "arith_reg_operand" "")
1225         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1226                   (match_operand:DI 2 "arith_reg_operand" "")))]
1227   ""
1228   "
1229 {
1230   if (TARGET_SH1)
1231     {
1232       operands[1] = force_reg (DImode, operands[1]);
1233       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1234       DONE;
1235     }
1236 }")
1237
1238 (define_insn "*subdi3_media"
1239   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1240         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1241                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1242   "TARGET_SHMEDIA"
1243   "sub  %N1, %2, %0"
1244   [(set_attr "type" "arith_media")])
1245
1246 (define_insn "subdi3_compact"
1247   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1248         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1249                  (match_operand:DI 2 "arith_reg_operand" "r")))
1250    (clobber (reg:SI T_REG))]
1251   "TARGET_SH1"
1252   "#"
1253   [(set_attr "length" "6")])
1254
1255 (define_split
1256   [(set (match_operand:DI 0 "arith_reg_operand" "")
1257         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1258                   (match_operand:DI 2 "arith_reg_operand" "")))
1259    (clobber (reg:SI T_REG))]
1260   "TARGET_SH1 && reload_completed"
1261   [(const_int 0)]
1262   "
1263 {
1264   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1265   high0 = gen_rtx_REG (SImode,
1266                        true_regnum (operands[0])
1267                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1268   high2 = gen_rtx_REG (SImode,
1269                        true_regnum (operands[2])
1270                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1271   emit_insn (gen_clrt ());
1272   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1273   emit_insn (gen_subc1 (high0, high0, high2));
1274   DONE;
1275 }")
1276
1277 (define_insn "subc"
1278   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1279         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1280                             (match_operand:SI 2 "arith_reg_operand" "r"))
1281                   (reg:SI T_REG)))
1282    (set (reg:SI T_REG)
1283         (gtu:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1284   "TARGET_SH1"
1285   "subc %2,%0"
1286   [(set_attr "type" "arith")
1287    (set_attr "insn_class" "ex_group")])
1288
1289 (define_insn "subc1"
1290   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1291         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1292                             (match_operand:SI 2 "arith_reg_operand" "r"))
1293                   (reg:SI T_REG)))
1294    (clobber (reg:SI T_REG))]
1295   "TARGET_SH1"
1296   "subc %2,%0"
1297   [(set_attr "type" "arith")
1298    (set_attr "insn_class" "ex_group")])
1299
1300 (define_insn "*subsi3_internal"
1301   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1302         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1303                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1304   "TARGET_SH1"
1305   "sub  %2,%0"
1306   [(set_attr "type" "arith")
1307    (set_attr "insn_class" "ex_group")])
1308
1309 (define_insn "*subsi3_media"
1310   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1311         (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN")
1312                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1313   "TARGET_SHMEDIA"
1314   "sub.l        %N1, %2, %0"
1315   [(set_attr "type" "arith_media")])
1316
1317 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1318 ;; will sometimes save one instruction.  Otherwise we might get
1319 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1320 ;; are the same.
1321
1322 (define_expand "subsi3"
1323   [(set (match_operand:SI 0 "arith_reg_operand" "")
1324         (minus:SI (match_operand:SI 1 "arith_operand" "")
1325                   (match_operand:SI 2 "arith_reg_operand" "")))]
1326   ""
1327   "
1328 {
1329   if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1330     {
1331       emit_insn (gen_negsi2 (operands[0], operands[2]));
1332       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1333       DONE;
1334     }
1335   if (TARGET_SHMEDIA)
1336     {
1337       if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1338         FAIL;
1339       if (operands[1] != const0_rtx)
1340         operands[1] = force_reg (SImode, operands[1]);
1341     }
1342 }")
1343 \f
1344 ;; -------------------------------------------------------------------------
1345 ;; Division instructions
1346 ;; -------------------------------------------------------------------------
1347
1348 ;; We take advantage of the library routines which don't clobber as many
1349 ;; registers as a normal function call would.
1350
1351 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1352 ;; also has an effect on the register that holds the address of the sfunc.
1353 ;; To make this work, we have an extra dummy insn that shows the use
1354 ;; of this register for reorg.
1355
1356 (define_insn "use_sfunc_addr"
1357   [(set (reg:SI PR_REG)
1358         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1359   "TARGET_SH1"
1360   ""
1361   [(set_attr "length" "0")])
1362
1363 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1364 ;; hard register 0.  If we used hard register 0, then the next instruction
1365 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1366 ;; gets allocated to a stack slot that needs its address reloaded, then
1367 ;; there is nothing to prevent reload from using r0 to reload the address.
1368 ;; This reload would clobber the value in r0 we are trying to store.
1369 ;; If we let reload allocate r0, then this problem can never happen.
1370
1371 (define_insn "udivsi3_i1"
1372   [(set (match_operand:SI 0 "register_operand" "=z")
1373         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1374    (clobber (reg:SI T_REG))
1375    (clobber (reg:SI PR_REG))
1376    (clobber (reg:SI R4_REG))
1377    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1378   "TARGET_SH1 && ! TARGET_SH4"
1379   "jsr  @%1%#"
1380   [(set_attr "type" "sfunc")
1381    (set_attr "needs_delay_slot" "yes")])
1382
1383 ; Since shmedia-nofpu code could be linked against shcompact code, and
1384 ; the udivsi3 libcall has the same name, we must consider all registers
1385 ; clobbered that are in the union of the registers clobbered by the
1386 ; shmedia and the shcompact implementation.  Note, if the shcompact
1387 ; implemenation actually used shcompact code, we'd need to clobber
1388 ; also r23 and fr23.
1389 (define_insn "udivsi3_i1_media"
1390   [(set (match_operand:SI 0 "register_operand" "=z")
1391         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1392    (clobber (reg:SI T_MEDIA_REG))
1393    (clobber (reg:SI PR_MEDIA_REG))
1394    (clobber (reg:SI R20_REG))
1395    (clobber (reg:SI R21_REG))
1396    (clobber (reg:SI R22_REG))
1397    (clobber (reg:DI TR0_REG))
1398    (clobber (reg:DI TR1_REG))
1399    (clobber (reg:DI TR2_REG))
1400    (use (match_operand:DI 1 "target_operand" "b"))]
1401   "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1402   "blink        %1, r18"
1403   [(set_attr "type" "sfunc")
1404    (set_attr "needs_delay_slot" "yes")])
1405
1406 (define_expand "udivsi3_i4_media"
1407   [(set (match_dup 3)
1408         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1409    (set (match_dup 4)
1410         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1411    (set (match_dup 5) (float:DF (match_dup 3)))
1412    (set (match_dup 6) (float:DF (match_dup 4)))
1413    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1414    (set (match_dup 8) (fix:DI (match_dup 7)))
1415    (set (match_operand:SI 0 "register_operand" "")
1416         (truncate:SI (match_dup 8)))]
1417   "TARGET_SHMEDIA_FPU"
1418   "
1419 {
1420   operands[3] = gen_reg_rtx (DImode);
1421   operands[4] = gen_reg_rtx (DImode);
1422   operands[5] = gen_reg_rtx (DFmode);
1423   operands[6] = gen_reg_rtx (DFmode);
1424   operands[7] = gen_reg_rtx (DFmode);
1425   operands[8] = gen_reg_rtx (DImode);
1426 }")
1427
1428 (define_insn "udivsi3_i4"
1429   [(set (match_operand:SI 0 "register_operand" "=y")
1430         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1431    (clobber (reg:SI T_REG))
1432    (clobber (reg:SI PR_REG))
1433    (clobber (reg:DF DR0_REG))
1434    (clobber (reg:DF DR2_REG))
1435    (clobber (reg:DF DR4_REG))
1436    (clobber (reg:SI R0_REG))
1437    (clobber (reg:SI R1_REG))
1438    (clobber (reg:SI R4_REG))
1439    (clobber (reg:SI R5_REG))
1440    (use (reg:PSI FPSCR_REG))
1441    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1442   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1443   "jsr  @%1%#"
1444   [(set_attr "type" "sfunc")
1445    (set_attr "fp_mode" "double")
1446    (set_attr "needs_delay_slot" "yes")])
1447
1448 (define_insn "udivsi3_i4_single"
1449   [(set (match_operand:SI 0 "register_operand" "=y")
1450         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1451    (clobber (reg:SI T_REG))
1452    (clobber (reg:SI PR_REG))
1453    (clobber (reg:DF DR0_REG))
1454    (clobber (reg:DF DR2_REG))
1455    (clobber (reg:DF DR4_REG))
1456    (clobber (reg:SI R0_REG))
1457    (clobber (reg:SI R1_REG))
1458    (clobber (reg:SI R4_REG))
1459    (clobber (reg:SI R5_REG))
1460    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1461   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1462   "jsr  @%1%#"
1463   [(set_attr "type" "sfunc")
1464    (set_attr "needs_delay_slot" "yes")])
1465
1466 (define_expand "udivsi3"
1467   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1468    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1469    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1470    (parallel [(set (match_operand:SI 0 "register_operand" "")
1471                    (udiv:SI (reg:SI R4_REG)
1472                             (reg:SI R5_REG)))
1473               (clobber (reg:SI T_REG))
1474               (clobber (reg:SI PR_REG))
1475               (clobber (reg:SI R4_REG))
1476               (use (match_dup 3))])]
1477   ""
1478   "
1479 {
1480   rtx first = 0, last;
1481
1482   operands[3] = gen_reg_rtx (Pmode);
1483   /* Emit the move of the address to a pseudo outside of the libcall.  */
1484   if (TARGET_HARD_SH4 && TARGET_SH3E)
1485     {
1486       emit_move_insn (operands[3],
1487                       gen_rtx_SYMBOL_REF (SImode, \"__udivsi3_i4\"));
1488       if (TARGET_FPU_SINGLE)
1489         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1490       else
1491         last = gen_udivsi3_i4 (operands[0], operands[3]);
1492     }
1493   else if (TARGET_SHMEDIA_FPU)
1494     {
1495       operands[1] = force_reg (SImode, operands[1]);
1496       operands[2] = force_reg (SImode, operands[2]);
1497       last = gen_udivsi3_i4_media (operands[0], operands[1], operands[2]);
1498       first = last;
1499     }
1500   else if (TARGET_SH5)
1501     {
1502       emit_move_insn (operands[3],
1503                       gen_rtx_SYMBOL_REF (Pmode,
1504                                           (TARGET_FPU_ANY
1505                                            ? \"__udivsi3_i4\"
1506                                            : \"__udivsi3\")));
1507
1508       if (TARGET_SHMEDIA)
1509         last = gen_udivsi3_i1_media (operands[0],
1510                                      Pmode == DImode
1511                                      ? operands[3]
1512                                      : gen_rtx_SUBREG (DImode, operands[3],
1513                                                        0));
1514       else if (TARGET_FPU_ANY)
1515         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1516       else
1517         last = gen_udivsi3_i1 (operands[0], operands[3]);
1518     }
1519   else
1520     {
1521       emit_move_insn (operands[3],
1522                       gen_rtx_SYMBOL_REF (SImode, \"__udivsi3\"));
1523       last = gen_udivsi3_i1 (operands[0], operands[3]);
1524     }
1525   if (! first)
1526     {
1527       first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1528       emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1529     }
1530   last = emit_insn (last);
1531   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1532      invariant code motion can move it.  */
1533   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1534   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1535   DONE;
1536 }")
1537
1538 (define_insn "divsi3_i1"
1539   [(set (match_operand:SI 0 "register_operand" "=z")
1540         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1541    (clobber (reg:SI T_REG))
1542    (clobber (reg:SI PR_REG))
1543    (clobber (reg:SI R1_REG))
1544    (clobber (reg:SI R2_REG))
1545    (clobber (reg:SI R3_REG))
1546    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1547   "TARGET_SH1 && ! TARGET_SH4"
1548   "jsr  @%1%#"
1549   [(set_attr "type" "sfunc")
1550    (set_attr "needs_delay_slot" "yes")])
1551
1552 ; Since shmedia-nofpu code could be linked against shcompact code, and
1553 ; the sdivsi3 libcall has the same name, we must consider all registers
1554 ; clobbered that are in the union of the registers clobbered by the
1555 ; shmedia and the shcompact implementation.  Note, if the shcompact
1556 ; implemenation actually used shcompact code, we'd need to clobber
1557 ; also r22, r23 and fr23.
1558 (define_insn "divsi3_i1_media"
1559   [(set (match_operand:SI 0 "register_operand" "=z")
1560         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1561    (clobber (reg:SI T_MEDIA_REG))
1562    (clobber (reg:SI PR_MEDIA_REG))
1563    (clobber (reg:SI R1_REG))
1564    (clobber (reg:SI R2_REG))
1565    (clobber (reg:SI R3_REG))
1566    (clobber (reg:SI R20_REG))
1567    (clobber (reg:SI R21_REG))
1568    (clobber (reg:DI TR0_REG))
1569    (clobber (reg:DI TR1_REG))
1570    (clobber (reg:DI TR2_REG))
1571    (use (match_operand:DI 1 "target_operand" "b"))]
1572   "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1573   "blink        %1, r18"
1574   [(set_attr "type" "sfunc")])
1575
1576 (define_expand "divsi3_i4_media"
1577   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1578    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1579    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1580    (set (match_operand:SI 0 "register_operand" "=r")
1581         (fix:SI (match_dup 5)))]
1582   "TARGET_SHMEDIA_FPU"
1583   "
1584 {
1585   operands[3] = gen_reg_rtx (DFmode);
1586   operands[4] = gen_reg_rtx (DFmode);
1587   operands[5] = gen_reg_rtx (DFmode);
1588 }")
1589
1590 (define_insn "divsi3_i4"
1591   [(set (match_operand:SI 0 "register_operand" "=y")
1592         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1593    (clobber (reg:SI PR_REG))
1594    (clobber (reg:DF DR0_REG))
1595    (clobber (reg:DF DR2_REG))
1596    (use (reg:PSI FPSCR_REG))
1597    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1598   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1599   "jsr  @%1%#"
1600   [(set_attr "type" "sfunc")
1601    (set_attr "fp_mode" "double")
1602    (set_attr "needs_delay_slot" "yes")])
1603
1604 (define_insn "divsi3_i4_single"
1605   [(set (match_operand:SI 0 "register_operand" "=y")
1606         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1607    (clobber (reg:SI PR_REG))
1608    (clobber (reg:DF DR0_REG))
1609    (clobber (reg:DF DR2_REG))
1610    (clobber (reg:SI R2_REG))
1611    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1612   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1613   "jsr  @%1%#"
1614   [(set_attr "type" "sfunc")
1615    (set_attr "needs_delay_slot" "yes")])
1616
1617 (define_expand "divsi3"
1618   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1619    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1620    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1621    (parallel [(set (match_operand:SI 0 "register_operand" "")
1622                    (div:SI (reg:SI R4_REG)
1623                            (reg:SI R5_REG)))
1624               (clobber (reg:SI T_REG))
1625               (clobber (reg:SI PR_REG))
1626               (clobber (reg:SI R1_REG))
1627               (clobber (reg:SI R2_REG))
1628               (clobber (reg:SI R3_REG))
1629               (use (match_dup 3))])]
1630   ""
1631   "
1632 {
1633   rtx first = 0, last;
1634
1635   operands[3] = gen_reg_rtx (Pmode);
1636   /* Emit the move of the address to a pseudo outside of the libcall.  */
1637   if (TARGET_HARD_SH4 && TARGET_SH3E)
1638     {
1639       emit_move_insn (operands[3],
1640                       gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3_i4\"));
1641       if (TARGET_FPU_SINGLE)
1642         last = gen_divsi3_i4_single (operands[0], operands[3]);
1643       else
1644         last = gen_divsi3_i4 (operands[0], operands[3]);
1645     }
1646   else if (TARGET_SHMEDIA_FPU)
1647     {
1648       operands[1] = force_reg (SImode, operands[1]);
1649       operands[2] = force_reg (SImode, operands[2]);
1650       last = gen_divsi3_i4_media (operands[0], operands[1], operands[2]);
1651       first = last;
1652     }
1653   else if (TARGET_SH5)
1654     {
1655       emit_move_insn (operands[3],
1656                       gen_rtx_SYMBOL_REF (Pmode,
1657                                           (TARGET_FPU_ANY
1658                                            ? \"__sdivsi3_i4\"
1659                                            : \"__sdivsi3\")));
1660
1661       if (TARGET_SHMEDIA)
1662         last = gen_divsi3_i1_media (operands[0],
1663                                     Pmode == DImode
1664                                     ? operands[3]
1665                                     : gen_rtx_SUBREG (DImode, operands[3],
1666                                                       0));
1667       else if (TARGET_FPU_ANY)
1668         last = gen_divsi3_i4_single (operands[0], operands[3]);
1669       else
1670         last = gen_divsi3_i1 (operands[0], operands[3]);
1671     }
1672   else
1673     {
1674       emit_move_insn (operands[3], gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3\"));
1675       last = gen_divsi3_i1 (operands[0], operands[3]);
1676     }
1677   if (! first)
1678     {
1679       first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1680       emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1681     }
1682   last = emit_insn (last);
1683   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1684      invariant code motion can move it.  */
1685   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1686   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1687   DONE;
1688 }")
1689 \f
1690 ;; -------------------------------------------------------------------------
1691 ;; Multiplication instructions
1692 ;; -------------------------------------------------------------------------
1693
1694 (define_insn "umulhisi3_i"
1695   [(set (reg:SI MACL_REG)
1696         (mult:SI (zero_extend:SI
1697                   (match_operand:HI 0 "arith_reg_operand" "r"))
1698                  (zero_extend:SI
1699                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
1700   "TARGET_SH1"
1701   "mulu.w       %1,%0"
1702   [(set_attr "type" "smpy")])
1703
1704 (define_insn "mulhisi3_i"
1705   [(set (reg:SI MACL_REG)
1706         (mult:SI (sign_extend:SI
1707                   (match_operand:HI 0 "arith_reg_operand" "r"))
1708                  (sign_extend:SI
1709                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
1710   "TARGET_SH1"
1711   "muls.w       %1,%0"
1712   [(set_attr "type" "smpy")])
1713
1714 (define_expand "mulhisi3"
1715   [(set (reg:SI MACL_REG)
1716         (mult:SI (sign_extend:SI
1717                   (match_operand:HI 1 "arith_reg_operand" ""))
1718                  (sign_extend:SI
1719                   (match_operand:HI 2 "arith_reg_operand" ""))))
1720    (set (match_operand:SI 0 "arith_reg_operand" "")
1721         (reg:SI MACL_REG))]
1722   "TARGET_SH1"
1723   "
1724 {
1725   rtx first, last;
1726
1727   first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1728   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1729   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1730      invariant code motion can move it.  */
1731   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1732   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1733   DONE;
1734 }")
1735
1736 (define_expand "umulhisi3"
1737   [(set (reg:SI MACL_REG)
1738         (mult:SI (zero_extend:SI
1739                   (match_operand:HI 1 "arith_reg_operand" ""))
1740                  (zero_extend:SI
1741                   (match_operand:HI 2 "arith_reg_operand" ""))))
1742    (set (match_operand:SI 0 "arith_reg_operand" "")
1743         (reg:SI MACL_REG))]
1744   "TARGET_SH1"
1745   "
1746 {
1747   rtx first, last;
1748
1749   first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1750   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1751   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1752      invariant code motion can move it.  */
1753   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1754   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1755   DONE;
1756 }")
1757
1758 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1759 ;; a call to a routine which clobbers known registers.
1760
1761 (define_insn ""
1762   [(set (match_operand:SI 1 "register_operand" "=z")
1763         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1764    (clobber (reg:SI MACL_REG))
1765    (clobber (reg:SI T_REG))
1766    (clobber (reg:SI PR_REG))
1767    (clobber (reg:SI R3_REG))
1768    (clobber (reg:SI R2_REG))
1769    (clobber (reg:SI R1_REG))
1770    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1771   "TARGET_SH1"
1772   "jsr  @%0%#"
1773   [(set_attr "type" "sfunc")
1774    (set_attr "needs_delay_slot" "yes")])
1775
1776 (define_expand "mulsi3_call"
1777   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1778    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1779    (parallel[(set (match_operand:SI 0 "register_operand" "")
1780                   (mult:SI (reg:SI R4_REG)
1781                            (reg:SI R5_REG)))
1782              (clobber (reg:SI MACL_REG))
1783              (clobber (reg:SI T_REG))
1784              (clobber (reg:SI PR_REG))
1785              (clobber (reg:SI R3_REG))
1786              (clobber (reg:SI R2_REG))
1787              (clobber (reg:SI R1_REG))
1788              (use (match_operand:SI 3 "register_operand" ""))])]
1789   "TARGET_SH1"
1790   "")
1791
1792 (define_insn "mul_l"
1793   [(set (reg:SI MACL_REG)
1794         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1795                  (match_operand:SI 1 "arith_reg_operand" "r")))]
1796   "TARGET_SH2"
1797   "mul.l        %1,%0"
1798   [(set_attr "type" "dmpy")])
1799
1800 (define_expand "mulsi3"
1801   [(set (reg:SI MACL_REG)
1802         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
1803                   (match_operand:SI 2 "arith_reg_operand" "")))
1804    (set (match_operand:SI 0 "arith_reg_operand" "")
1805         (reg:SI MACL_REG))]
1806   "TARGET_SH1"
1807   "
1808 {
1809   rtx first, last;
1810
1811   if (!TARGET_SH2)
1812     {
1813       /* The address must be set outside the libcall,
1814          since it goes into a pseudo.  */
1815       rtx sym = gen_rtx_SYMBOL_REF (SImode, \"__mulsi3\");
1816       rtx addr = force_reg (SImode, sym);
1817       rtx insns = gen_mulsi3_call (operands[0], operands[1],
1818                                    operands[2], addr);
1819       first = insns;
1820       last = emit_insn (insns);
1821     }
1822   else
1823     {
1824       rtx macl = gen_rtx_REG (SImode, MACL_REG);
1825
1826       first = emit_insn (gen_mul_l (operands[1], operands[2]));
1827       /* consec_sets_giv can only recognize the first insn that sets a
1828          giv as the giv insn.  So we must tag this also with a REG_EQUAL
1829          note.  */
1830       last = emit_insn (gen_movsi_i ((operands[0]), macl));
1831     }
1832   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1833      invariant code motion can move it.  */
1834   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1835   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1836   DONE;
1837 }")
1838
1839 (define_insn "mulsidi3_i"
1840   [(set (reg:SI MACH_REG)
1841         (truncate:SI
1842          (lshiftrt:DI
1843           (mult:DI
1844            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1845            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1846           (const_int 32))))
1847    (set (reg:SI MACL_REG)
1848         (mult:SI (match_dup 0)
1849                  (match_dup 1)))]
1850   "TARGET_SH2"
1851   "dmuls.l      %1,%0"
1852   [(set_attr "type" "dmpy")])
1853
1854 (define_expand "mulsidi3"
1855   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1856         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1857                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1858   "TARGET_SH2 || TARGET_SHMEDIA"
1859   "
1860 {
1861   if (TARGET_SH2)
1862     {
1863        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1864                                         operands[2]));
1865        DONE;
1866     }
1867 }")
1868
1869 (define_insn "mulsidi3_media"
1870   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1871         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1872                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1873   "TARGET_SHMEDIA"
1874   "muls.l       %1, %2, %0"
1875   [(set_attr "type" "dmpy_media")])
1876
1877 (define_insn "mulsidi3_compact"
1878   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1879         (mult:DI
1880          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1881          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1882    (clobber (reg:SI MACH_REG))
1883    (clobber (reg:SI MACL_REG))]
1884   "TARGET_SH2"
1885   "#")
1886
1887 (define_split
1888   [(set (match_operand:DI 0 "arith_reg_operand" "")
1889         (mult:DI
1890          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1891          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1892    (clobber (reg:SI MACH_REG))
1893    (clobber (reg:SI MACL_REG))]
1894   "TARGET_SH2"
1895   [(const_int 0)]
1896   "
1897 {
1898   rtx low_dst = gen_lowpart (SImode, operands[0]);
1899   rtx high_dst = gen_highpart (SImode, operands[0]);
1900
1901   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1902
1903   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1904   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1905   /* We need something to tag the possible REG_EQUAL notes on to.  */
1906   emit_move_insn (operands[0], operands[0]);
1907   DONE;
1908 }")
1909
1910 (define_insn "umulsidi3_i"
1911   [(set (reg:SI MACH_REG)
1912         (truncate:SI
1913          (lshiftrt:DI
1914           (mult:DI
1915            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1916            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1917           (const_int 32))))
1918    (set (reg:SI MACL_REG)
1919         (mult:SI (match_dup 0)
1920                  (match_dup 1)))]
1921   "TARGET_SH2"
1922   "dmulu.l      %1,%0"
1923   [(set_attr "type" "dmpy")])
1924
1925 (define_expand "umulsidi3"
1926   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1927         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1928                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1929   "TARGET_SH2 || TARGET_SHMEDIA"
1930   "
1931 {
1932   if (TARGET_SH2)
1933     {
1934        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1935                                          operands[2]));
1936        DONE;
1937     }
1938 }")
1939
1940 (define_insn "umulsidi3_media"
1941   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1942         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1943                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1944   "TARGET_SHMEDIA"
1945   "mulu.l       %1, %2, %0"
1946   [(set_attr "type" "dmpy_media")])
1947
1948 (define_insn "umulsidi3_compact"
1949   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1950         (mult:DI
1951          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1952          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1953    (clobber (reg:SI MACH_REG))
1954    (clobber (reg:SI MACL_REG))]
1955   "TARGET_SH2"
1956   "#")
1957
1958 (define_split
1959   [(set (match_operand:DI 0 "arith_reg_operand" "")
1960         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1961                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1962    (clobber (reg:SI MACH_REG))
1963    (clobber (reg:SI MACL_REG))]
1964   "TARGET_SH2"
1965   [(const_int 0)]
1966   "
1967 {
1968   rtx low_dst = gen_lowpart (SImode, operands[0]);
1969   rtx high_dst = gen_highpart (SImode, operands[0]);
1970
1971   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1972
1973   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1974   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1975   /* We need something to tag the possible REG_EQUAL notes on to.  */
1976   emit_move_insn (operands[0], operands[0]);
1977   DONE;
1978 }")
1979
1980 (define_insn "smulsi3_highpart_i"
1981   [(set (reg:SI MACH_REG)
1982         (truncate:SI
1983          (lshiftrt:DI
1984           (mult:DI
1985            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1986            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1987           (const_int 32))))
1988    (clobber (reg:SI MACL_REG))]
1989   "TARGET_SH2"
1990   "dmuls.l      %1,%0"
1991   [(set_attr "type" "dmpy")])
1992
1993 (define_expand "smulsi3_highpart"
1994   [(parallel
1995     [(set (reg:SI MACH_REG)
1996           (truncate:SI
1997            (lshiftrt:DI
1998             (mult:DI
1999              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2000              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2001             (const_int 32))))
2002     (clobber (reg:SI MACL_REG))])
2003    (set (match_operand:SI 0 "arith_reg_operand" "")
2004         (reg:SI MACH_REG))]
2005   "TARGET_SH2"
2006   "
2007 {
2008   rtx first, last;
2009
2010   first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
2011   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
2012   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2013      invariant code motion can move it.  */
2014   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2015   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2016   /* expand_binop can't find a suitable code in mul_highpart_optab to
2017      make a REG_EQUAL note from, so make one here.
2018      ??? Alternatively, we could put this at the calling site of expand_binop,
2019      i.e. expand_mult_highpart.  */
2020   REG_NOTES (last)
2021     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2022                          REG_NOTES (last));
2023   DONE;
2024 }")
2025
2026 (define_insn "umulsi3_highpart_i"
2027   [(set (reg:SI MACH_REG)
2028         (truncate:SI
2029          (lshiftrt:DI
2030           (mult:DI
2031            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2032            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2033           (const_int 32))))
2034    (clobber (reg:SI MACL_REG))]
2035   "TARGET_SH2"
2036   "dmulu.l      %1,%0"
2037   [(set_attr "type" "dmpy")])
2038
2039 (define_expand "umulsi3_highpart"
2040   [(parallel
2041     [(set (reg:SI MACH_REG)
2042           (truncate:SI
2043            (lshiftrt:DI
2044             (mult:DI
2045              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2046              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2047             (const_int 32))))
2048     (clobber (reg:SI MACL_REG))])
2049    (set (match_operand:SI 0 "arith_reg_operand" "")
2050         (reg:SI MACH_REG))]
2051   "TARGET_SH2"
2052   "
2053 {
2054   rtx first, last;
2055
2056   first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
2057   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
2058   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2059      invariant code motion can move it.  */
2060   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2061   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2062   DONE;
2063 }")
2064 \f
2065 ;; -------------------------------------------------------------------------
2066 ;; Logical operations
2067 ;; -------------------------------------------------------------------------
2068
2069 (define_insn "*andsi3_compact"
2070   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
2071         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2072                 (match_operand:SI 2 "logical_operand" "r,L")))]
2073   "TARGET_SH1"
2074   "and  %2,%0"
2075   [(set_attr "type" "arith")
2076    (set_attr "insn_class" "ex_group")])
2077
2078 ;; If the constant is 255, then emit a extu.b instruction instead of an
2079 ;; and, since that will give better code.
2080
2081 (define_expand "andsi3"
2082   [(set (match_operand:SI 0 "arith_reg_operand" "")
2083         (and:SI (match_operand:SI 1 "arith_reg_operand" "")
2084                 (match_operand:SI 2 "logical_operand" "")))]
2085   "TARGET_SH1"
2086   "
2087 {
2088   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
2089     {
2090       emit_insn (gen_zero_extendqisi2 (operands[0],
2091                                        gen_lowpart (QImode, operands[1])));
2092       DONE;
2093     }
2094 }")
2095
2096 (define_insn_and_split "anddi3"
2097   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
2098         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
2099                 (match_operand:DI 2 "and_operand" "r,P,n")))]
2100   "TARGET_SHMEDIA"
2101   "@
2102         and     %1, %2, %0
2103         andi    %1, %2, %0
2104         #"
2105   "reload_completed
2106    && ! logical_operand (operands[2], DImode)"
2107   [(const_int 0)]
2108   "
2109 {
2110   if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
2111     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
2112   else
2113     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
2114   DONE;
2115 }"
2116   [(set_attr "type" "arith_media")])
2117
2118 (define_insn "andcdi3"
2119   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2120         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
2121                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
2122   "TARGET_SHMEDIA"
2123   "andc %1,%2,%0"
2124   [(set_attr "type" "arith_media")])
2125
2126 (define_insn "iorsi3"
2127   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
2128         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2129                 (match_operand:SI 2 "logical_operand" "r,L")))]
2130   "TARGET_SH1"
2131   "or   %2,%0"
2132   [(set_attr "type" "arith")
2133    (set_attr "insn_class" "ex_group")])
2134
2135 (define_insn "iordi3"
2136   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2137         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2138                 (match_operand:DI 2 "logical_operand" "r,P")))]
2139   "TARGET_SHMEDIA"
2140   "@
2141         or      %1, %2, %0
2142         ori     %1, %2, %0"
2143   [(set_attr "type" "arith_media")])
2144
2145 (define_insn "xorsi3"
2146   [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
2147         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2148                 (match_operand:SI 2 "logical_operand" "L,r")))]
2149   "TARGET_SH1"
2150   "xor  %2,%0"
2151   [(set_attr "type" "arith")
2152    (set_attr "insn_class" "ex_group")])
2153
2154 (define_insn "xordi3"
2155   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2156         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2157                 (match_operand:DI 2 "shmedia_6bit_operand" "r,O")))]
2158   "TARGET_SHMEDIA"
2159   "@
2160         xor     %1, %2, %0
2161         xori    %1, %2, %0"
2162   [(set_attr "type" "arith_media")])
2163 \f
2164 ;; -------------------------------------------------------------------------
2165 ;; Shifts and rotates
2166 ;; -------------------------------------------------------------------------
2167
2168 (define_expand "rotldi3"
2169   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2170         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2171                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
2172   "TARGET_SHMEDIA"
2173   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2174
2175 (define_insn "rotldi3_mextr"
2176   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2177         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2178                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
2179   "TARGET_SHMEDIA"
2180   "*
2181 {
2182   static char templ[16];
2183
2184   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2185            8 - (int) (INTVAL (operands[2]) >> 3));
2186   return templ;
2187 }"
2188   [(set_attr "type" "arith_media")])
2189
2190 (define_expand "rotrdi3"
2191   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2192         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2193                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
2194   "TARGET_SHMEDIA"
2195   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2196
2197 (define_insn "rotrdi3_mextr"
2198   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2199         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2200                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
2201   "TARGET_SHMEDIA"
2202   "*
2203 {
2204   static char templ[16];
2205
2206   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2207   return templ;
2208 }"
2209   [(set_attr "type" "arith_media")])
2210
2211 (define_insn "rotlsi3_1"
2212   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2213         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2214                    (const_int 1)))
2215    (set (reg:SI T_REG)
2216         (lshiftrt:SI (match_dup 1) (const_int 31)))]
2217   "TARGET_SH1"
2218   "rotl %0"
2219   [(set_attr "type" "arith")
2220    (set_attr "insn_class" "ex_group")])
2221
2222 (define_insn "rotlsi3_31"
2223   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2224         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2225                    (const_int 31)))
2226    (clobber (reg:SI T_REG))]
2227   "TARGET_SH1"
2228   "rotr %0"
2229   [(set_attr "type" "arith")
2230    (set_attr "insn_class" "ex_group")])
2231
2232 (define_insn "rotlsi3_16"
2233   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2234         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2235                    (const_int 16)))]
2236   "TARGET_SH1"
2237   "swap.w       %1,%0"
2238   [(set_attr "type" "arith")
2239   (set_attr "insn_class" "ex_group")])
2240
2241 (define_expand "rotlsi3"
2242   [(set (match_operand:SI 0 "arith_reg_operand" "")
2243         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2244                    (match_operand:SI 2 "immediate_operand" "")))]
2245   "TARGET_SH1"
2246   "
2247 {
2248   static const char rot_tab[] = {
2249     000, 000, 000, 000, 000, 000, 010, 001,
2250     001, 001, 011, 013, 003, 003, 003, 003,
2251     003, 003, 003, 003, 003, 013, 012, 002,
2252     002, 002, 010, 000, 000, 000, 000, 000,
2253   };
2254
2255   int count, choice;
2256
2257   if (GET_CODE (operands[2]) != CONST_INT)
2258     FAIL;
2259   count = INTVAL (operands[2]);
2260   choice = rot_tab[count];
2261   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2262     FAIL;
2263   choice &= 7;
2264   switch (choice)
2265     {
2266     case 0:
2267       emit_move_insn (operands[0], operands[1]);
2268       count -= (count & 16) * 2;
2269       break;
2270     case 3:
2271      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2272      count -= 16;
2273      break;
2274     case 1:
2275     case 2:
2276       {
2277         rtx parts[2];
2278         parts[0] = gen_reg_rtx (SImode);
2279         parts[1] = gen_reg_rtx (SImode);
2280         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2281         parts[choice-1] = operands[1];
2282         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2283         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2284         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2285         count = (count & ~16) - 8;
2286       }
2287     }
2288
2289   for (; count > 0; count--)
2290     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2291   for (; count < 0; count++)
2292     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2293
2294   DONE;
2295 }")
2296
2297 (define_insn "*rotlhi3_8"
2298   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2299         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2300                    (const_int 8)))]
2301   "TARGET_SH1"
2302   "swap.b       %1,%0"
2303   [(set_attr "type" "arith")
2304    (set_attr "insn_class" "ex_group")])
2305
2306 (define_expand "rotlhi3"
2307   [(set (match_operand:HI 0 "arith_reg_operand" "")
2308         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2309                    (match_operand:HI 2 "immediate_operand" "")))]
2310   "TARGET_SH1"
2311   "
2312 {
2313   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2314     FAIL;
2315 }")
2316
2317 ;;
2318 ;; shift left
2319
2320 ;; This pattern is used by init_expmed for computing the costs of shift
2321 ;; insns.
2322
2323 (define_insn_and_split "ashlsi3_std"
2324   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2325         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2326                    (match_operand:SI 2 "nonmemory_operand" "r,M,K,?ri")))
2327    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2328   "TARGET_SH3
2329    || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2330        && CONST_OK_FOR_K (INTVAL (operands[2])))"
2331   "@
2332    shld %2,%0
2333    add  %0,%0
2334    shll%O2      %0
2335    #"
2336   "TARGET_SH3
2337    && reload_completed
2338    && GET_CODE (operands[2]) == CONST_INT
2339    && ! CONST_OK_FOR_K (INTVAL (operands[2]))"
2340   [(set (match_dup 3) (match_dup 2))
2341    (parallel
2342     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2343      (clobber (match_dup 4))])]
2344   "operands[4] = gen_rtx_SCRATCH (SImode);"
2345   [(set_attr "length" "*,*,*,4")
2346    (set_attr "type" "dyn_shift,arith,arith,arith")
2347    (set_attr "insn_class" "ex_group,ex_group,ex_group,ex_group")])
2348
2349 (define_insn "ashlhi3_k"
2350   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2351         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2352                    (match_operand:HI 2 "const_int_operand" "M,K")))]
2353   "TARGET_SH1 && CONST_OK_FOR_K (INTVAL (operands[2]))"
2354   "@
2355         add     %0,%0
2356         shll%O2 %0"
2357   [(set_attr "type" "arith")
2358    (set_attr "insn_class" "ex_group")])
2359
2360 (define_insn "ashlsi3_n"
2361   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2362         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2363                    (match_operand:SI 2 "const_int_operand" "n")))
2364    (clobber (reg:SI T_REG))]
2365   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2366   "#"
2367   [(set (attr "length")
2368         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2369                (const_string "2")
2370                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2371                (const_string "4")
2372                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2373                (const_string "6")]
2374               (const_string "8")))
2375    (set_attr "type" "arith")
2376    (set_attr "insn_class" "ex_group")])
2377
2378 (define_split
2379   [(set (match_operand:SI 0 "arith_reg_operand" "")
2380         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2381                    (match_operand:SI 2 "const_int_operand" "")))
2382    (clobber (reg:SI T_REG))]
2383   "TARGET_SH1 && reload_completed"
2384   [(use (reg:SI R0_REG))]
2385   "
2386 {
2387   gen_shifty_op (ASHIFT, operands);
2388   DONE;
2389 }")
2390
2391 (define_insn "ashlsi3_media"
2392   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2393         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2394                    (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2395   "TARGET_SHMEDIA"
2396   "@
2397         shlld.l %1, %2, %0
2398         shlli.l %1, %2, %0"
2399   [(set_attr "type" "arith_media")])
2400
2401 (define_expand "ashlsi3"
2402   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2403                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2404                               (match_operand:SI 2 "nonmemory_operand" "")))
2405               (clobber (reg:SI T_REG))])]
2406   ""
2407   "
2408 {
2409   if (TARGET_SHMEDIA)
2410     {
2411       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2412       DONE;
2413     }
2414   if (GET_CODE (operands[2]) == CONST_INT
2415       && sh_dynamicalize_shift_p (operands[2]))
2416     operands[2] = force_reg (SImode, operands[2]);
2417   if (TARGET_SH3)
2418     {
2419       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2420       DONE;
2421     }
2422   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2423     FAIL;
2424 }")
2425
2426 (define_insn "ashlhi3"
2427   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2428         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2429                    (match_operand:HI 2 "const_int_operand" "n")))
2430    (clobber (reg:SI T_REG))]
2431   "TARGET_SH1"
2432   "#"
2433   [(set (attr "length")
2434         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2435                (const_string "2")
2436                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2437                (const_string "4")]
2438               (const_string "6")))
2439    (set_attr "type" "arith")])
2440
2441 (define_split
2442   [(set (match_operand:HI 0 "arith_reg_operand" "")
2443         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2444                    (match_operand:HI 2 "const_int_operand" "")))
2445    (clobber (reg:SI T_REG))]
2446   "TARGET_SH1 && reload_completed"
2447   [(use (reg:SI R0_REG))]
2448   "
2449 {
2450   gen_shifty_hi_op (ASHIFT, operands);
2451   DONE;
2452 }")
2453
2454 ;
2455 ; arithmetic shift right
2456 ;
2457
2458 (define_insn "ashrsi3_k"
2459   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2460         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2461                      (match_operand:SI 2 "const_int_operand" "M")))
2462    (clobber (reg:SI T_REG))]
2463   "TARGET_SH1 && INTVAL (operands[2]) == 1"
2464   "shar %0"
2465   [(set_attr "type" "arith")
2466    (set_attr "insn_class" "ex_group")])
2467
2468 ;; We can't do HImode right shifts correctly unless we start out with an
2469 ;; explicit zero / sign extension; doing that would result in worse overall
2470 ;; code, so just let the machine independent code widen the mode.
2471 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2472
2473
2474 ;; ??? This should be a define expand.
2475
2476 (define_insn "ashrsi2_16"
2477   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2478         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2479                      (const_int 16)))]
2480   "TARGET_SH1"
2481   "#"
2482   [(set_attr "length" "4")])
2483
2484 (define_split
2485   [(set (match_operand:SI 0 "arith_reg_operand" "")
2486         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2487                      (const_int 16)))]
2488   "TARGET_SH1"
2489   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2490    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2491   "operands[2] = gen_lowpart (HImode, operands[0]);")
2492
2493 ;; ??? This should be a define expand.
2494
2495 (define_insn "ashrsi2_31"
2496   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2497         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2498                      (const_int 31)))
2499    (clobber (reg:SI T_REG))]
2500   "TARGET_SH1"
2501   "#"
2502   [(set_attr "length" "4")])
2503
2504 (define_split
2505   [(set (match_operand:SI 0 "arith_reg_operand" "")
2506         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2507                      (const_int 31)))
2508    (clobber (reg:SI T_REG))]
2509   "TARGET_SH1"
2510   [(const_int 0)]
2511   "
2512 {
2513   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2514   emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2515   DONE;
2516 }")
2517
2518 (define_insn "ashlsi_c"
2519   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2520         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2521    (set (reg:SI T_REG)
2522         (lt:SI (match_dup 1) (const_int 0)))]
2523   "TARGET_SH1"
2524   "shll %0"
2525   [(set_attr "type" "arith")
2526    (set_attr "insn_class" "ex_group")])
2527
2528 (define_insn "ashrsi3_d"
2529   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2530         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2531                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2532   "TARGET_SH3"
2533   "shad %2,%0"
2534   [(set_attr "type" "dyn_shift")
2535    (set_attr "insn_class" "ex_group")])
2536
2537 (define_insn "ashrsi3_n"
2538   [(set (reg:SI R4_REG)
2539         (ashiftrt:SI (reg:SI R4_REG)
2540                      (match_operand:SI 0 "const_int_operand" "i")))
2541    (clobber (reg:SI T_REG))
2542    (clobber (reg:SI PR_REG))
2543    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2544   "TARGET_SH1"
2545   "jsr  @%1%#"
2546   [(set_attr "type" "sfunc")
2547    (set_attr "needs_delay_slot" "yes")])
2548
2549 (define_insn "ashrsi3_media"
2550   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2551         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2552                      (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2553   "TARGET_SHMEDIA"
2554   "@
2555         shard.l %1, %2, %0
2556         shari.l %1, %2, %0"
2557   [(set_attr "type" "arith_media")])
2558
2559 (define_expand "ashrsi3"
2560   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2561                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2562                                 (match_operand:SI 2 "nonmemory_operand" "")))
2563               (clobber (reg:SI T_REG))])]
2564   ""
2565   "
2566 {
2567   if (TARGET_SHMEDIA)
2568     {
2569       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2570       DONE;
2571     }
2572   if (expand_ashiftrt (operands))
2573     DONE;
2574   else
2575     FAIL;
2576 }")
2577
2578 ;; logical shift right
2579
2580 (define_insn "lshrsi3_d"
2581   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2582         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2583                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2584   "TARGET_SH3"
2585   "shld %2,%0"
2586   [(set_attr "type" "dyn_shift")
2587    (set_attr "insn_class" "ex_group")])
2588
2589 ;;  Only the single bit shift clobbers the T bit.
2590
2591 (define_insn "lshrsi3_m"
2592   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2593         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2594                      (match_operand:SI 2 "const_int_operand" "M")))
2595    (clobber (reg:SI T_REG))]
2596   "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2597   "shlr %0"
2598   [(set_attr "type" "arith")
2599    (set_attr "insn_class" "ex_group")])
2600
2601 (define_insn "lshrsi3_k"
2602   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2603         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2604                      (match_operand:SI 2 "const_int_operand" "K")))]
2605   "TARGET_SH1 && CONST_OK_FOR_K (INTVAL (operands[2]))
2606    && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2607   "shlr%O2      %0"
2608   [(set_attr "type" "arith")
2609    (set_attr "insn_class" "ex_group")])
2610
2611 (define_insn "lshrsi3_n"
2612   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2613         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2614                      (match_operand:SI 2 "const_int_operand" "n")))
2615    (clobber (reg:SI T_REG))]
2616   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2617   "#"
2618   [(set (attr "length")
2619         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2620                (const_string "2")
2621                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2622                (const_string "4")
2623                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2624                (const_string "6")]
2625               (const_string "8")))
2626    (set_attr "type" "arith")])
2627
2628 (define_split
2629   [(set (match_operand:SI 0 "arith_reg_operand" "")
2630         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2631                      (match_operand:SI 2 "const_int_operand" "")))
2632    (clobber (reg:SI T_REG))]
2633   "TARGET_SH1 && reload_completed"
2634   [(use (reg:SI R0_REG))]
2635   "
2636 {
2637   gen_shifty_op (LSHIFTRT, operands);
2638   DONE;
2639 }")
2640
2641 (define_insn "lshrsi3_media"
2642   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2643         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2644                      (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2645   "TARGET_SHMEDIA"
2646   "@
2647         shlrd.l %1, %2, %0
2648         shlri.l %1, %2, %0"
2649   [(set_attr "type" "arith_media")])
2650
2651 (define_expand "lshrsi3"
2652   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2653                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2654                                 (match_operand:SI 2 "nonmemory_operand" "")))
2655               (clobber (reg:SI T_REG))])]
2656   ""
2657   "
2658 {
2659   if (TARGET_SHMEDIA)
2660     {
2661       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2662       DONE;
2663     }
2664   if (GET_CODE (operands[2]) == CONST_INT
2665       && sh_dynamicalize_shift_p (operands[2]))
2666     operands[2] = force_reg (SImode, operands[2]);
2667   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2668     {
2669       rtx count = copy_to_mode_reg (SImode, operands[2]);
2670       emit_insn (gen_negsi2 (count, count));
2671       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2672       DONE;
2673     }
2674   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2675     FAIL;
2676 }")
2677
2678 ;; ??? This should be a define expand.
2679
2680 (define_insn "ashldi3_k"
2681   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2682         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2683                    (const_int 1)))
2684    (clobber (reg:SI T_REG))]
2685   "TARGET_SH1"
2686   "shll %R0\;rotcl      %S0"
2687   [(set_attr "length" "4")
2688    (set_attr "type" "arith")
2689    (set_attr "insn_class" "ex_group")])
2690
2691 (define_insn "ashldi3_media"
2692   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2693         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2694                    (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2695   "TARGET_SHMEDIA"
2696   "@
2697         shlld   %1, %2, %0
2698         shlli   %1, %2, %0"
2699   [(set_attr "type" "arith_media")])
2700
2701 (define_expand "ashldi3"
2702   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2703                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2704                               (match_operand:DI 2 "immediate_operand" "")))
2705               (clobber (reg:SI T_REG))])]
2706   ""
2707   "
2708 {
2709   if (TARGET_SHMEDIA)
2710     {
2711       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2712       DONE;
2713     }
2714   if (GET_CODE (operands[2]) != CONST_INT
2715       || INTVAL (operands[2]) != 1)
2716     FAIL;
2717 }")
2718
2719 ;; ??? This should be a define expand.
2720
2721 (define_insn "lshrdi3_k"
2722   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2723         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2724                      (const_int 1)))
2725    (clobber (reg:SI T_REG))]
2726   "TARGET_SH1"
2727   "shlr %S0\;rotcr      %R0"
2728   [(set_attr "length" "4")
2729    (set_attr "type" "arith")
2730    (set_attr "insn_class" "ex_group")])
2731
2732 (define_insn "lshrdi3_media"
2733   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2734         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2735                      (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2736   "TARGET_SHMEDIA"
2737   "@
2738         shlrd   %1, %2, %0
2739         shlri   %1, %2, %0"
2740   [(set_attr "type" "arith_media")])
2741
2742 (define_expand "lshrdi3"
2743   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2744                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2745                                (match_operand:DI 2 "immediate_operand" "")))
2746              (clobber (reg:SI T_REG))])]
2747   ""
2748   "
2749 {
2750   if (TARGET_SHMEDIA)
2751     {
2752       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2753       DONE;
2754     }
2755   if (GET_CODE (operands[2]) != CONST_INT
2756       || INTVAL (operands[2]) != 1)
2757     FAIL;
2758 }")
2759
2760 ;; ??? This should be a define expand.
2761
2762 (define_insn "ashrdi3_k"
2763   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2764         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2765                      (const_int 1)))
2766    (clobber (reg:SI T_REG))]
2767   "TARGET_SH1"
2768   "shar %S0\;rotcr      %R0"
2769   [(set_attr "length" "4")
2770    (set_attr "type" "arith")
2771    (set_attr "insn_class" "ex_group")])
2772
2773 (define_insn "ashrdi3_media"
2774   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2775         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2776                      (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2777   "TARGET_SHMEDIA"
2778   "@
2779         shard   %1, %2, %0
2780         shari   %1, %2, %0"
2781   [(set_attr "type" "arith_media")])
2782
2783 (define_expand "ashrdi3"
2784   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2785                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2786                                 (match_operand:DI 2 "immediate_operand" "")))
2787               (clobber (reg:SI T_REG))])]
2788   ""
2789   "
2790 {
2791   if (TARGET_SHMEDIA)
2792     {
2793       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2794       DONE;
2795     }
2796   if (GET_CODE (operands[2]) != CONST_INT
2797       || INTVAL (operands[2]) != 1)
2798     FAIL;
2799 }")
2800
2801 ;; combined left/right shift
2802
2803 (define_split
2804   [(set (match_operand:SI 0 "register_operand" "")
2805         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2806                            (match_operand:SI 2 "const_int_operand" ""))
2807                 (match_operand:SI 3 "const_int_operand" "")))]
2808   "TARGET_SH1 && (unsigned)INTVAL (operands[2]) < 32"
2809   [(use (reg:SI R0_REG))]
2810   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2811    DONE;")
2812
2813 (define_split
2814   [(set (match_operand:SI 0 "register_operand" "")
2815         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2816                            (match_operand:SI 2 "const_int_operand" ""))
2817                 (match_operand:SI 3 "const_int_operand" "")))
2818    (clobber (reg:SI T_REG))]
2819   "TARGET_SH1 && (unsigned)INTVAL (operands[2]) < 32"
2820   [(use (reg:SI R0_REG))]
2821   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2822    DONE;")
2823
2824 (define_insn ""
2825   [(set (match_operand:SI 0 "register_operand" "=r")
2826         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2827                            (match_operand:SI 2 "const_int_operand" "n"))
2828                 (match_operand:SI 3 "const_int_operand" "n")))
2829    (clobber (reg:SI T_REG))]
2830   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2831  "#"
2832   [(set (attr "length")
2833         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2834                (const_string "4")
2835                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2836                (const_string "6")
2837                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2838                (const_string "8")
2839                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2840                (const_string "10")
2841                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2842                (const_string "12")
2843                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2844                (const_string "14")
2845                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2846                (const_string "16")]
2847               (const_string "18")))
2848    (set_attr "type" "arith")])
2849
2850 (define_insn ""
2851   [(set (match_operand:SI 0 "register_operand" "=z")
2852         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2853                            (match_operand:SI 2 "const_int_operand" "n"))
2854                 (match_operand:SI 3 "const_int_operand" "n")))
2855    (clobber (reg:SI T_REG))]
2856   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2857  "#"
2858   [(set (attr "length")
2859         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2860                (const_string "4")
2861                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2862                (const_string "6")
2863                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2864                (const_string "8")]
2865               (const_string "10")))
2866    (set_attr "type" "arith")])
2867
2868 ;; shift left / and combination with a scratch register: The combine pass
2869 ;; does not accept the individual instructions, even though they are
2870 ;; cheap.  But it needs a precise description so that it is usable after
2871 ;; reload.
2872 (define_insn "and_shl_scratch"
2873   [(set (match_operand:SI 0 "register_operand" "=r,&r")
2874         (lshiftrt:SI
2875          (ashift:SI
2876           (and:SI
2877            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2878                         (match_operand:SI 2 "const_int_operand" "N,n"))
2879            (match_operand:SI 3 "" "0,r"))
2880           (match_operand:SI 4 "const_int_operand" "n,n"))
2881          (match_operand:SI 5 "const_int_operand" "n,n")))
2882    (clobber (reg:SI T_REG))]
2883   "TARGET_SH1"
2884   "#"
2885   [(set (attr "length")
2886         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2887                (const_string "4")
2888                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2889                (const_string "6")
2890                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2891                (const_string "8")
2892                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2893                (const_string "10")]
2894               (const_string "12")))
2895    (set_attr "type" "arith")])
2896
2897 (define_split
2898   [(set (match_operand:SI 0 "register_operand" "")
2899         (lshiftrt:SI
2900          (ashift:SI
2901           (and:SI
2902            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2903                         (match_operand:SI 2 "const_int_operand" ""))
2904            (match_operand:SI 3 "register_operand" ""))
2905           (match_operand:SI 4 "const_int_operand" ""))
2906          (match_operand:SI 5 "const_int_operand" "")))
2907    (clobber (reg:SI T_REG))]
2908   "TARGET_SH1"
2909   [(use (reg:SI R0_REG))]
2910   "
2911 {
2912   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2913
2914   if (INTVAL (operands[2]))
2915     {
2916       gen_shifty_op (LSHIFTRT, operands);
2917     }
2918   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2919   operands[2] = operands[4];
2920   gen_shifty_op (ASHIFT, operands);
2921   if (INTVAL (operands[5]))
2922     {
2923       operands[2] = operands[5];
2924       gen_shifty_op (LSHIFTRT, operands);
2925     }
2926   DONE;
2927 }")
2928
2929 ;; signed left/right shift combination.
2930 (define_split
2931   [(set (match_operand:SI 0 "register_operand" "")
2932         (sign_extract:SI
2933          (ashift:SI (match_operand:SI 1 "register_operand" "")
2934                     (match_operand:SI 2 "const_int_operand" ""))
2935          (match_operand:SI 3 "const_int_operand" "")
2936          (const_int 0)))
2937    (clobber (reg:SI T_REG))]
2938   "TARGET_SH1"
2939   [(use (reg:SI R0_REG))]
2940   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2941    DONE;")
2942
2943 (define_insn "shl_sext_ext"
2944   [(set (match_operand:SI 0 "register_operand" "=r")
2945         (sign_extract:SI
2946          (ashift:SI (match_operand:SI 1 "register_operand" "0")
2947                     (match_operand:SI 2 "const_int_operand" "n"))
2948          (match_operand:SI 3 "const_int_operand" "n")
2949          (const_int 0)))
2950    (clobber (reg:SI T_REG))]
2951   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2952   "#"
2953   [(set (attr "length")
2954         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2955                (const_string "2")
2956                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2957                (const_string "4")
2958                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2959                (const_string "6")
2960                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2961                (const_string "8")
2962                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2963                (const_string "10")
2964                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2965                (const_string "12")
2966                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2967                (const_string "14")
2968                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2969                (const_string "16")]
2970               (const_string "18")))
2971     (set_attr "type" "arith")])
2972
2973 (define_insn "shl_sext_sub"
2974   [(set (match_operand:SI 0 "register_operand" "=z")
2975         (sign_extract:SI
2976          (ashift:SI (match_operand:SI 1 "register_operand" "0")
2977                     (match_operand:SI 2 "const_int_operand" "n"))
2978          (match_operand:SI 3 "const_int_operand" "n")
2979          (const_int 0)))
2980    (clobber (reg:SI T_REG))]
2981   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2982   "#"
2983   [(set (attr "length")
2984         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2985                (const_string "6")
2986                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2987                (const_string "8")
2988                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2989                (const_string "10")
2990                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2991                (const_string "12")]
2992               (const_string "14")))
2993     (set_attr "type" "arith")])
2994
2995 ;; These patterns are found in expansions of DImode shifts by 16, and
2996 ;; allow the xtrct instruction to be generated from C source.
2997
2998 (define_insn "xtrct_left"
2999   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3000         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
3001                            (const_int 16))
3002                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
3003                              (const_int 16))))]
3004   "TARGET_SH1"
3005   "xtrct        %1,%0"
3006   [(set_attr "type" "arith")
3007    (set_attr "insn_class" "ex_group")])
3008
3009 (define_insn "xtrct_right"
3010   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3011         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3012                              (const_int 16))
3013                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
3014                            (const_int 16))))]
3015   "TARGET_SH1"
3016   "xtrct        %2,%0"
3017   [(set_attr "type" "arith")
3018    (set_attr "insn_class" "ex_group")])
3019
3020 ;; -------------------------------------------------------------------------
3021 ;; Unary arithmetic
3022 ;; -------------------------------------------------------------------------
3023
3024 (define_insn "negc"
3025   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3026         (neg:SI (plus:SI (reg:SI T_REG)
3027                          (match_operand:SI 1 "arith_reg_operand" "r"))))
3028    (set (reg:SI T_REG)
3029         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
3030                (const_int 0)))]
3031   "TARGET_SH1"
3032   "negc %1,%0"
3033   [(set_attr "type" "arith")
3034    (set_attr "insn_class" "ex_group")])
3035
3036 (define_insn "*negdi_media"
3037   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3038         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
3039   "TARGET_SHMEDIA"
3040   "sub  r63, %1, %0"
3041   [(set_attr "type" "arith_media")])
3042
3043 (define_expand "negdi2"
3044   [(set (match_operand:DI 0 "arith_reg_operand" "")
3045         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
3046   ""
3047   "
3048 {
3049   if (TARGET_SH1)
3050     {
3051       int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
3052       int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
3053
3054       rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
3055       rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
3056
3057       rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
3058       rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
3059
3060       emit_insn (gen_clrt ());
3061       emit_insn (gen_negc (low_dst, low_src));
3062       emit_insn (gen_negc (high_dst, high_src));
3063       DONE;
3064     }
3065 }")
3066
3067 (define_insn "negsi2"
3068   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3069         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
3070   "TARGET_SH1"
3071   "neg  %1,%0"
3072   [(set_attr "type" "arith")
3073    (set_attr "insn_class" "ex_group")])
3074
3075 (define_insn "one_cmplsi2"
3076   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3077         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
3078   "TARGET_SH1"
3079   "not  %1,%0"
3080   [(set_attr "type" "arith")
3081    (set_attr "insn_class" "ex_group")])
3082
3083 (define_expand "one_cmpldi2"
3084   [(set (match_operand:DI 0 "arith_reg_operand" "")
3085         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
3086                 (const_int -1)))]
3087   "TARGET_SHMEDIA" "")
3088 \f
3089 ;; -------------------------------------------------------------------------
3090 ;; Zero extension instructions
3091 ;; -------------------------------------------------------------------------
3092
3093 (define_insn "zero_extendsidi2"
3094   [(set (match_operand:DI 0 "register_operand" "=r")
3095         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
3096   "TARGET_SHMEDIA"
3097   "addz.l       %1, r63, %0"
3098   [(set_attr "type" "arith_media")])
3099
3100 (define_insn "zero_extendhidi2"
3101   [(set (match_operand:DI 0 "register_operand" "=r,r")
3102         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3103   "TARGET_SHMEDIA"
3104   "@
3105         #
3106         ld%M1.uw        %m1, %0"
3107   [(set_attr "type" "*,load_media")])
3108
3109 (define_split
3110   [(set (match_operand:DI 0 "register_operand" "")
3111         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3112   "TARGET_SHMEDIA && reload_completed"
3113   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3114    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
3115   "
3116 {
3117   if (GET_CODE (operands[1]) == TRUNCATE)
3118     operands[1] = XEXP (operands[1], 0);
3119 }")
3120
3121 ;; ??? when a truncated input to a zero_extrend is reloaded, reload will
3122 ;; reload the entrire truncate expression.
3123 (define_insn_and_split "*loaddi_trunc"
3124   [(set (match_operand 0 "int_gpr_dest" "=r")
3125         (truncate (match_operand:DI 1 "memory_operand" "m")))]
3126   "TARGET_SHMEDIA && reload_completed"
3127   "#"
3128   "TARGET_SHMEDIA && reload_completed"
3129   [(set (match_dup 0) (match_dup 1))]
3130   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
3131
3132 (define_insn "zero_extendqidi2"
3133   [(set (match_operand:DI 0 "register_operand" "=r,r")
3134         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3135   "TARGET_SHMEDIA"
3136   "@
3137         andi    %1, 255, %0
3138         ld%M1.ub        %m1, %0"
3139   [(set_attr "type" "arith_media,load_media")])
3140
3141 (define_expand "zero_extendhisi2"
3142   [(set (match_operand:SI 0 "arith_reg_operand" "")
3143         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3144   ""
3145   "
3146 {
3147   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3148     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3149 }")
3150
3151 (define_insn "*zero_extendhisi2_compact"
3152   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3153         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
3154   "TARGET_SH1"
3155   "extu.w       %1,%0"
3156   [(set_attr "type" "arith")
3157    (set_attr "insn_class" "ex_group")])
3158
3159 (define_insn "*zero_extendhisi2_media"
3160   [(set (match_operand:SI 0 "register_operand" "=r,r")
3161         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3162   "TARGET_SHMEDIA"
3163   "@
3164         #
3165         ld%M1.uw        %m1, %0"
3166   [(set_attr "type" "arith_media,load_media")])
3167
3168 (define_split
3169   [(set (match_operand:SI 0 "register_operand" "")
3170         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3171   "TARGET_SHMEDIA && reload_completed"
3172   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3173    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3174   "
3175 {
3176   if (GET_CODE (operands[1]) == TRUNCATE)
3177     operands[1] = XEXP (operands[1], 0);
3178 }")
3179
3180 (define_expand "zero_extendqisi2"
3181   [(set (match_operand:SI 0 "arith_reg_operand" "")
3182         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3183   ""
3184   "
3185 {
3186   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3187     operands[1] = copy_to_mode_reg (QImode, operands[1]);
3188 }")
3189
3190 (define_insn "*zero_extendqisi2_compact"
3191   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3192         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
3193   "TARGET_SH1"
3194   "extu.b       %1,%0"
3195   [(set_attr "type" "arith")
3196    (set_attr "insn_class" "ex_group")])
3197
3198 (define_insn "*zero_extendqisi2_media"
3199   [(set (match_operand:SI 0 "register_operand" "=r,r")
3200         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3201   "TARGET_SHMEDIA"
3202   "@
3203         andi    %1, 255, %0
3204         ld%M1.ub        %m1, %0"
3205   [(set_attr "type" "arith_media,load_media")])
3206
3207 (define_insn "zero_extendqihi2"
3208   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3209         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
3210   "TARGET_SH1"
3211   "extu.b       %1,%0"
3212   [(set_attr "type" "arith")
3213    (set_attr "insn_class" "ex_group")])
3214
3215 ;; -------------------------------------------------------------------------
3216 ;; Sign extension instructions
3217 ;; -------------------------------------------------------------------------
3218
3219 ;; ??? This should be a define expand.
3220 ;; ??? Or perhaps it should be dropped?
3221
3222 ;; convert_move generates good code for SH[1-4].
3223 (define_insn "extendsidi2"
3224   [(set (match_operand:DI 0 "register_operand" "=r,r")
3225         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3226   "TARGET_SHMEDIA"
3227   "@
3228         add.l   %1, r63, %0
3229         ld%M1.l %m1, %0"
3230   [(set_attr "type" "arith_media,load_media")])
3231
3232 (define_insn "extendhidi2"
3233   [(set (match_operand:DI 0 "register_operand" "=r,r")
3234         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3235   "TARGET_SHMEDIA"
3236   "@
3237         #
3238         ld%M1.w %m1, %0"
3239   [(set_attr "type" "*,load_media")])
3240
3241 (define_split
3242   [(set (match_operand:DI 0 "register_operand" "")
3243         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3244   "TARGET_SHMEDIA && reload_completed"
3245   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3246    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3247   "
3248 {
3249   if (GET_CODE (operands[1]) == TRUNCATE)
3250     operands[1] = XEXP (operands[1], 0);
3251 }")
3252
3253 (define_insn "extendqidi2"
3254   [(set (match_operand:DI 0 "register_operand" "=r,r")
3255         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3256   "TARGET_SHMEDIA"
3257   "@
3258         #
3259         ld%M1.b %m1, %0"
3260   [(set_attr "type" "*,load_media")])
3261
3262 (define_split
3263   [(set (match_operand:DI 0 "register_operand" "")
3264         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
3265   "TARGET_SHMEDIA && reload_completed"
3266   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3267    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3268   "
3269 {
3270   if (GET_CODE (operands[1]) == TRUNCATE)
3271     operands[1] = XEXP (operands[1], 0);
3272 }")
3273
3274 (define_expand "extendhisi2"
3275   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3276        (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3277   ""
3278   "")
3279
3280 (define_insn "*extendhisi2_compact"
3281   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3282         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3283   "TARGET_SH1"
3284   "@
3285         exts.w  %1,%0
3286         mov.w   %1,%0"
3287   [(set_attr "type" "arith,load")
3288    (set_attr "insn_class" "ex_group,*")])
3289
3290 (define_insn "*extendhisi2_media"
3291   [(set (match_operand:SI 0 "register_operand" "=r,r")
3292         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3293   "TARGET_SHMEDIA"
3294   "@
3295         #
3296         ld%M1.w %m1, %0"
3297   [(set_attr "type" "arith_media,load_media")])
3298
3299 (define_split
3300   [(set (match_operand:SI 0 "register_operand" "")
3301         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3302   "TARGET_SHMEDIA && reload_completed"
3303   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3304    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3305   "
3306 {
3307   if (GET_CODE (operands[1]) == TRUNCATE)
3308     operands[1] = XEXP (operands[1], 0);
3309 }")
3310
3311 (define_expand "extendqisi2"
3312   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3313         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3314   ""
3315   "")
3316
3317 (define_insn "*extendqisi2_compact"
3318   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3319         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3320   "TARGET_SH1"
3321   "@
3322         exts.b  %1,%0
3323         mov.b   %1,%0"
3324   [(set_attr "type" "arith,load")
3325    (set_attr "insn_class" "ex_group,*")])
3326
3327 (define_insn "*extendqisi2_media"
3328   [(set (match_operand:SI 0 "register_operand" "=r,r")
3329         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3330   "TARGET_SHMEDIA"
3331   "@
3332         #
3333         ld%M1.b %m1, %0"
3334   [(set_attr "type" "arith_media,load_media")])
3335
3336 (define_split
3337   [(set (match_operand:SI 0 "register_operand" "")
3338         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
3339   "TARGET_SHMEDIA && reload_completed"
3340   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3341    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3342    "
3343 {
3344   if (GET_CODE (operands[1]) == TRUNCATE)
3345     operands[1] = XEXP (operands[1], 0);
3346 }")
3347
3348 (define_insn "extendqihi2"
3349   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3350         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3351   "TARGET_SH1"
3352   "@
3353         exts.b  %1,%0
3354         mov.b   %1,%0"
3355   [(set_attr "type" "arith,load")
3356    (set_attr "insn_class" "ex_group,*")])
3357
3358 /* It would seem useful to combine the truncXi patterns into the movXi
3359    patterns, but unary operators are ignored when matching constraints,
3360    so we need separate patterns.  */
3361 (define_insn "truncdisi2"
3362   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
3363         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3364   "TARGET_SHMEDIA"
3365   "@
3366         add.l   %1, r63, %0
3367         st%M0.l %m0, %1
3368         fst%M0.s        %m0, %T1
3369         fmov.ls %1, %0
3370         fmov.sl %T1, %0
3371         fmov.s  %T1, %0"
3372   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3373
3374
3375 (define_insn "truncdihi2"
3376   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
3377         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3378   "TARGET_SHMEDIA"
3379   "@
3380         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3381         st%M0.w %m0, %1"
3382   [(set_attr "type"   "arith_media,store_media")
3383    (set_attr "length" "8,4")])
3384
3385 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3386 ; Because we use zero extension, we can't provide signed QImode compares
3387 ; using a simple compare or conditional banch insn.
3388 (define_insn "truncdiqi2"
3389   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3390         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3391   "TARGET_SHMEDIA"
3392   "@
3393         and     %1, 255, %0
3394         st%M0.b %m0, %1"
3395   [(set_attr "type"   "arith_media,store")])
3396
3397 ;; -------------------------------------------------------------------------
3398 ;; Move instructions
3399 ;; -------------------------------------------------------------------------
3400
3401 ;; define push and pop so it is easy for sh.c
3402 ;; We can't use push and pop on SHcompact because the stack must always
3403 ;; be 8-byte aligned.
3404
3405 (define_expand "push"
3406   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3407         (match_operand:SI 0 "register_operand" "r,l,x"))]
3408   "TARGET_SH1 && ! TARGET_SH5"
3409   "")
3410
3411 (define_expand "pop"
3412   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3413         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3414   "TARGET_SH1 && ! TARGET_SH5"
3415   "")
3416
3417 (define_expand "push_e"
3418   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3419                    (match_operand:SF 0 "" ""))
3420               (use (reg:PSI FPSCR_REG))
3421               (clobber (scratch:SI))])]
3422   "TARGET_SH1 && ! TARGET_SH5"
3423   "")
3424
3425 (define_insn "push_fpul"
3426   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3427   "TARGET_SH3E && ! TARGET_SH5"
3428   "sts.l        fpul,@-r15"
3429   [(set_attr "type" "store")
3430    (set_attr "hit_stack" "yes")])
3431
3432 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3433 ;; so use that.
3434 (define_expand "push_4"
3435   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3436                    (match_operand:DF 0 "" ""))
3437               (use (reg:PSI FPSCR_REG))
3438               (clobber (scratch:SI))])]
3439   "TARGET_SH1 && ! TARGET_SH5"
3440   "")
3441
3442 (define_expand "pop_e"
3443   [(parallel [(set (match_operand:SF 0 "" "")
3444               (mem:SF (post_inc:SI (reg:SI SP_REG))))
3445               (use (reg:PSI FPSCR_REG))
3446               (clobber (scratch:SI))])]
3447   "TARGET_SH1 && ! TARGET_SH5"
3448   "")
3449
3450 (define_insn "pop_fpul"
3451   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3452   "TARGET_SH3E && ! TARGET_SH5"
3453   "lds.l        @r15+,fpul"
3454   [(set_attr "type" "load")
3455    (set_attr "hit_stack" "yes")])
3456
3457 (define_expand "pop_4"
3458   [(parallel [(set (match_operand:DF 0 "" "")
3459                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
3460               (use (reg:PSI FPSCR_REG))
3461               (clobber (scratch:SI))])]
3462   "TARGET_SH1 && ! TARGET_SH5"
3463   "")
3464
3465 ;; These two patterns can happen as the result of optimization, when
3466 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3467 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3468
3469 (define_insn "clrt"
3470   [(set (reg:SI T_REG) (const_int 0))]
3471   "TARGET_SH1"
3472   "clrt")
3473
3474 (define_insn "sett"
3475   [(set (reg:SI T_REG) (const_int 1))]
3476   "TARGET_SH1"
3477   "sett")
3478
3479 ;; t/r must come after r/r, lest reload will try to reload stuff like
3480 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3481 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3482 (define_insn "movsi_i"
3483   [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3484         (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3485   "TARGET_SH1
3486    && ! TARGET_SH3E
3487    && (register_operand (operands[0], SImode)
3488        || register_operand (operands[1], SImode))"
3489   "@
3490         mov.l   %1,%0
3491         mov     %1,%0
3492         cmp/pl  %1
3493         mov.l   %1,%0
3494         sts     %1,%0
3495         sts     %1,%0
3496         movt    %0
3497         mov.l   %1,%0
3498         sts.l   %1,%0
3499         sts.l   %1,%0
3500         lds     %1,%0
3501         lds     %1,%0
3502         lds.l   %1,%0
3503         lds.l   %1,%0
3504         fake    %1,%0"
3505   [(set_attr "type" "pcload_si,move,*,load_si,move,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3506    (set_attr "insn_class"  "*,*,mt_group,*,*,*,*,*,*,*,*,*,*,*,*")
3507    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3508
3509 ;; t/r must come after r/r, lest reload will try to reload stuff like
3510 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3511 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3512 ;; will require a reload.
3513 (define_insn "movsi_ie"
3514   [(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")
3515         (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y"))]
3516   "TARGET_SH3E
3517    && (register_operand (operands[0], SImode)
3518        || register_operand (operands[1], SImode))"
3519   "@
3520         mov.l   %1,%0
3521         mov     %1,%0
3522         cmp/pl  %1
3523         mov.l   %1,%0
3524         sts     %1,%0
3525         sts     %1,%0
3526         movt    %0
3527         mov.l   %1,%0
3528         sts.l   %1,%0
3529         sts.l   %1,%0
3530         lds     %1,%0
3531         lds     %1,%0
3532         lds.l   %1,%0
3533         lds.l   %1,%0
3534         lds.l   %1,%0
3535         sts.l   %1,%0
3536         fake    %1,%0
3537         lds     %1,%0
3538         sts     %1,%0
3539         ! move optimized away"
3540   [(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")
3541    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3542
3543 (define_insn "movsi_i_lowpart"
3544   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3545         (match_operand:SI 1 "general_movsrc_operand" "Q,rI,mr,x,l,t,r,i"))]
3546    "TARGET_SH1
3547     && (register_operand (operands[0], SImode)
3548         || register_operand (operands[1], SImode))"
3549   "@
3550         mov.l   %1,%0
3551         mov     %1,%0
3552         mov.l   %1,%0
3553         sts     %1,%0
3554         sts     %1,%0
3555         movt    %0
3556         mov.l   %1,%0
3557         fake    %1,%0"
3558   [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
3559
3560 (define_insn "*movsi_media"
3561   [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
3562         (match_operand:SI 1 "general_movsrc_operand" "r,JS,ns,m,r,m,f,rU,f,f,r,*b,T"))]
3563   "TARGET_SHMEDIA_FPU
3564    && (register_operand (operands[0], SImode)
3565        || register_operand (operands[1], SImode))"
3566   "@
3567         add.l   %1, r63, %0
3568         movi    %1, %0
3569         #
3570         ld%M1.l %m1, %0
3571         st%M0.l %m0, %1
3572         fld%M1.s        %m1, %0
3573         fst%M0.s        %m0, %1
3574         fmov.ls %N1, %0
3575         fmov.sl %1, %0
3576         fmov.s  %1, %0
3577         ptabs   %1, %0
3578         gettr   %1, %0
3579         pt      %1, %0"
3580   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,fload_media,fstore_media,fload_media,fpconv_media,fmove_media,ptabs_media,gettr_media,pt_media")
3581    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3582
3583 (define_insn "*movsi_media_nofpu"
3584   [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,m,*b,r,b")
3585         (match_operand:SI 1 "general_movsrc_operand" "r,JS,ns,m,r,r,*b,T"))]
3586   "TARGET_SHMEDIA
3587    && (register_operand (operands[0], SImode)
3588        || register_operand (operands[1], SImode))"
3589   "@
3590         add.l   %1, r63, %0
3591         movi    %1, %0
3592         #
3593         ld%M1.l %m1, %0
3594         st%M0.l %m0, %1
3595         ptabs   %1, %0
3596         gettr   %1, %0
3597         pt      %1, %0"
3598   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3599    (set_attr "length" "4,4,8,4,4,4,4,12")])
3600
3601 (define_split
3602   [(set (match_operand:SI 0 "arith_reg_operand" "")
3603         (match_operand:SI 1 "immediate_operand" ""))]
3604   "TARGET_SHMEDIA && reload_completed
3605    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3606   [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3607   "
3608 {
3609   operands[2] = shallow_copy_rtx (operands[1]);
3610   PUT_MODE (operands[2], DImode);
3611 }")
3612
3613 (define_split
3614   [(set (match_operand:SI 0 "register_operand" "")
3615         (match_operand:SI 1 "immediate_operand" ""))]
3616   "TARGET_SHMEDIA && reload_completed
3617    && ((GET_CODE (operands[1]) == CONST_INT
3618         && ! CONST_OK_FOR_J (INTVAL (operands[1])))
3619        || GET_CODE (operands[1]) == CONST_DOUBLE)"
3620   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3621
3622 (define_expand "movsi"
3623   [(set (match_operand:SI 0 "general_movdst_operand" "")
3624         (match_operand:SI 1 "general_movsrc_operand" ""))]
3625   ""
3626   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
3627
3628 (define_expand "ic_invalidate_line"
3629   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
3630                                 (match_dup 1)] UNSPEC_ICACHE)
3631               (clobber (scratch:SI))])]
3632   "TARGET_HARD_SH4 || TARGET_SH5"
3633   "
3634 {
3635   if (TARGET_SHMEDIA)
3636     {
3637       emit_insn (gen_ic_invalidate_line_media (operands[0]));
3638       DONE;
3639     }
3640   else if (TARGET_SHCOMPACT)
3641     {
3642       operands[1] = gen_rtx_SYMBOL_REF (Pmode, \"__ic_invalidate\");
3643       operands[1] = force_reg (Pmode, operands[1]);
3644       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3645       DONE;
3646     }
3647   operands[0] = force_reg (Pmode, operands[0]);
3648   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3649                                                                Pmode)));
3650 }")
3651
3652 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
3653 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3654 ;; the requirement *1*00 for associative address writes.  The alignment of
3655 ;; %0 implies that its least significant bit is cleared,
3656 ;; thus we clear the V bit of a matching entry if there is one.
3657 (define_insn "ic_invalidate_line_i"
3658   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
3659                      (match_operand:SI 1 "register_operand" "r")]
3660                      UNSPEC_ICACHE)
3661    (clobber (match_scratch:SI 2 "=&r"))]
3662   "TARGET_HARD_SH4"
3663   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
3664   [(set_attr "length" "8")
3665    (set_attr "insn_class" "cwb")])
3666
3667 ;; ??? could make arg 0 an offsettable memory operand to allow to save
3668 ;; an add in the code that calculates the address.
3669 (define_insn "ic_invalidate_line_media"
3670   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3671                     UNSPEC_ICACHE)]
3672   "TARGET_SHMEDIA"
3673   "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
3674   [(set_attr "length" "16")
3675    (set_attr "type" "invalidate_line_media")])
3676
3677 (define_insn "ic_invalidate_line_compact"
3678   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3679                      (match_operand:SI 1 "register_operand" "r")]
3680                     UNSPEC_ICACHE)
3681    (clobber (reg:SI PR_REG))]
3682   "TARGET_SHCOMPACT"
3683   "jsr @%1%#"
3684   [(set_attr "type" "sfunc")
3685    (set_attr "needs_delay_slot" "yes")])
3686
3687 (define_expand "initialize_trampoline"
3688   [(match_operand:SI 0 "" "")
3689    (match_operand:SI 1 "" "")
3690    (match_operand:SI 2 "" "")]
3691   "TARGET_SHCOMPACT"
3692   "
3693 {
3694   rtx sfun, tramp;
3695
3696   sfun = force_reg (Pmode, gen_rtx_SYMBOL_REF (Pmode, \"__init_trampoline\"));
3697   tramp = gen_rtx_REG (SImode, R0_REG);
3698   emit_move_insn (tramp, operands[0]);
3699   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3700   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3701
3702   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3703   DONE;
3704 }")
3705
3706 (define_insn "initialize_trampoline_compact"
3707   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3708                      (match_operand:SI 1 "register_operand" "r")
3709                      (reg:SI R2_REG) (reg:SI R3_REG)]
3710                     UNSPEC_INIT_TRAMP)
3711
3712    (clobber (reg:SI PR_REG))]
3713   "TARGET_SHCOMPACT"
3714   "jsr @%1%#"
3715   [(set_attr "type" "sfunc")
3716    (set_attr "needs_delay_slot" "yes")])
3717
3718 (define_insn "movqi_i"
3719   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3720         (match_operand:QI 1 "general_movsrc_operand"  "ri,m,r,t,l,r"))]
3721   "TARGET_SH1
3722    && (arith_reg_operand (operands[0], QImode)
3723        || arith_reg_operand (operands[1], QImode))"
3724   "@
3725         mov     %1,%0
3726         mov.b   %1,%0
3727         mov.b   %1,%0
3728         movt    %0
3729         sts     %1,%0
3730         lds     %1,%0"
3731  [(set_attr "type" "move,load,store,move,move,move")])
3732
3733 (define_insn "*movqi_media"
3734   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
3735         (match_operand:QI 1 "general_movsrc_operand" "r,JS,m,r"))]
3736   "TARGET_SHMEDIA
3737    && (arith_reg_operand (operands[0], QImode)
3738        || arith_reg_operand (operands[1], QImode))"
3739   "@
3740         add.l   %1, r63, %0
3741         movi    %1, %0
3742         ld%M1.ub        %m1, %0
3743         st%M0.b %m0, %1"
3744   [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
3745
3746 (define_expand "movqi"
3747   [(set (match_operand:QI 0 "general_operand" "")
3748         (match_operand:QI 1 "general_operand"  ""))]
3749   ""
3750   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
3751
3752 (define_expand "reload_inqi"
3753   [(set (match_operand:SI 2 "" "=&r")
3754         (match_operand:QI 1 "inqhi_operand" ""))
3755    (set (match_operand:QI 0 "arith_reg_operand" "=r")
3756         (truncate:HI (match_dup 3)))]
3757   "TARGET_SHMEDIA"
3758   "
3759 {
3760   rtx inner = XEXP (operands[1], 0);
3761   int regno = REGNO (inner);
3762
3763   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3764   operands[1] = gen_rtx_REG (SImode, regno);
3765   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3766 }")
3767
3768 (define_insn "movhi_i"
3769   [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
3770         (match_operand:HI 1 "general_movsrc_operand" "Q,rI,m,t,r,l,r,i"))]
3771   "TARGET_SH1
3772    && (arith_reg_operand (operands[0], HImode)
3773        || arith_reg_operand (operands[1], HImode))"
3774   "@
3775         mov.w   %1,%0
3776         mov     %1,%0
3777         mov.w   %1,%0
3778         movt    %0
3779         mov.w   %1,%0
3780         sts     %1,%0
3781         lds     %1,%0
3782         fake    %1,%0"
3783   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
3784
3785 (define_insn "*movhi_media"
3786   [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
3787         (match_operand:HI 1 "general_movsrc_operand" "r,JS,n,m,r"))]
3788   "TARGET_SHMEDIA
3789    && (arith_reg_operand (operands[0], HImode)
3790        || arith_reg_operand (operands[1], HImode))"
3791   "@
3792         add.l   %1, r63, %0
3793         movi    %1, %0
3794         #
3795         ld%M1.w %m1, %0
3796         st%M0.w %m0, %1"
3797   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
3798
3799 (define_split
3800   [(set (match_operand:HI 0 "register_operand" "")
3801         (match_operand:HI 1 "immediate_operand" ""))]
3802   "TARGET_SHMEDIA && reload_completed
3803    && ! CONST_OK_FOR_J (INTVAL (operands[1]))"
3804   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3805
3806 (define_expand "movhi"
3807   [(set (match_operand:HI 0 "general_movdst_operand" "")
3808         (match_operand:HI 1 "general_movsrc_operand"  ""))]
3809   ""
3810   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3811
3812 (define_expand "reload_inhi"
3813   [(set (match_operand:SI 2 "" "=&r")
3814         (match_operand:HI 1 "inqhi_operand" ""))
3815    (set (match_operand:HI 0 "arith_reg_operand" "=r")
3816         (truncate:HI (match_dup 3)))]
3817   "TARGET_SHMEDIA"
3818   "
3819 {
3820   rtx inner = XEXP (operands[1], 0);
3821   int regno = REGNO (inner);
3822
3823   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3824   operands[1] = gen_rtx_REG (SImode, regno);
3825   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3826 }")
3827
3828 ;; ??? This should be a define expand.
3829
3830 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3831 ;; compiled with -m2 -ml -O3 -funroll-loops
3832 (define_insn ""
3833   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3834         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I,i,x,r"))]
3835   "TARGET_SH1
3836    && (arith_reg_operand (operands[0], DImode)
3837        || arith_reg_operand (operands[1], DImode))"
3838   "* return output_movedouble (insn, operands, DImode);"
3839   [(set_attr "length" "4")
3840    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
3841
3842 ;; If the output is a register and the input is memory or a register, we have
3843 ;; to be careful and see which word needs to be loaded first.
3844
3845 (define_split
3846   [(set (match_operand:DI 0 "general_movdst_operand" "")
3847         (match_operand:DI 1 "general_movsrc_operand" ""))]
3848   "TARGET_SH1 && reload_completed"
3849   [(set (match_dup 2) (match_dup 3))
3850    (set (match_dup 4) (match_dup 5))]
3851   "
3852 {
3853   int regno;
3854
3855   if ((GET_CODE (operands[0]) == MEM
3856        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3857       || (GET_CODE (operands[1]) == MEM
3858           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3859     FAIL;
3860
3861   if (GET_CODE (operands[0]) == REG)
3862     regno = REGNO (operands[0]);
3863   else if (GET_CODE (operands[0]) == SUBREG)
3864     regno = subreg_regno (operands[0]);
3865   else if (GET_CODE (operands[0]) == MEM)
3866     regno = -1;
3867   else
3868     abort ();
3869
3870   if (regno == -1
3871       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
3872     {
3873       operands[2] = operand_subword (operands[0], 0, 0, DImode);
3874       operands[3] = operand_subword (operands[1], 0, 0, DImode);
3875       operands[4] = operand_subword (operands[0], 1, 0, DImode);
3876       operands[5] = operand_subword (operands[1], 1, 0, DImode);
3877     }
3878   else
3879     {
3880       operands[2] = operand_subword (operands[0], 1, 0, DImode);
3881       operands[3] = operand_subword (operands[1], 1, 0, DImode);
3882       operands[4] = operand_subword (operands[0], 0, 0, DImode);
3883       operands[5] = operand_subword (operands[1], 0, 0, DImode);
3884     }
3885
3886   if (operands[2] == 0 || operands[3] == 0
3887       || operands[4] == 0 || operands[5] == 0)
3888     FAIL;
3889 }")
3890
3891 (define_insn "*movdi_media"
3892   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
3893         (match_operand:DI 1 "general_movsrc_operand" "r,JS,iF,m,rl,m,f,rU,f,f,r,*b,T"))]
3894   "TARGET_SHMEDIA_FPU
3895    && (register_operand (operands[0], DImode)
3896        || register_operand (operands[1], DImode))"
3897   "@
3898         add     %1, r63, %0
3899         movi    %1, %0
3900         #
3901         ld%M1.q %m1, %0
3902         st%M0.q %m0, %1
3903         fld%M1.d        %m1, %0
3904         fst%M0.d        %m0, %1
3905         fmov.qd %N1, %0
3906         fmov.dq %1, %0
3907         fmov.d  %1, %0
3908         ptabs   %1, %0
3909         gettr   %1, %0
3910         pt      %1, %0"
3911   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,fload_media,fstore_media,fload_media,dfpconv_media,fmove_media,ptabs_media,gettr_media,pt_media")
3912    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3913
3914 (define_insn "*movdi_media_nofpu"
3915   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
3916         (match_operand:DI 1 "general_movsrc_operand" "r,JS,iF,m,rl,r,*b,T"))]
3917   "TARGET_SHMEDIA
3918    && (register_operand (operands[0], DImode)
3919        || register_operand (operands[1], DImode))"
3920   "@
3921         add     %1, r63, %0
3922         movi    %1, %0
3923         #
3924         ld%M1.q %m1, %0
3925         st%M0.q %m0, %1
3926         ptabs   %1, %0
3927         gettr   %1, %0
3928         pt      %1, %0"
3929   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3930    (set_attr "length" "4,4,16,4,4,4,4,*")])
3931
3932 (define_split
3933   [(set (match_operand:DI 0 "arith_reg_operand" "")
3934         (match_operand:DI 1 "immediate_operand" ""))]
3935   "TARGET_SHMEDIA && reload_completed
3936    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3937   [(set (match_dup 0) (match_dup 1))]
3938   "
3939 {
3940   rtx insn;
3941
3942   if (TARGET_SHMEDIA64)
3943     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3944   else
3945     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3946
3947   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3948                                         REG_NOTES (insn));
3949
3950   DONE;
3951 }")
3952
3953 (define_expand "movdi_const"
3954   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3955         (const:DI (sign_extend:DI
3956                    (truncate:HI
3957                     (ashiftrt:DI
3958                      (match_operand:DI 1 "immediate_operand" "s")
3959                      (const_int 48))))))
3960    (set (match_dup 0)
3961         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3962                 (zero_extend:DI
3963                  (truncate:HI
3964                   (const:DI
3965                    (sign_extend:DI
3966                     (truncate:HI
3967                      (ashiftrt:SI
3968                       (match_dup 1)
3969                       (const_int 32)))))))))
3970    (set (match_dup 0)
3971         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3972                 (zero_extend:DI
3973                  (truncate:HI
3974                   (const:DI
3975                    (sign_extend:DI
3976                     (truncate:HI
3977                      (ashiftrt:SI
3978                       (match_dup 1)
3979                       (const_int 16)))))))))
3980    (set (match_dup 0)
3981         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3982                 (zero_extend:DI
3983                  (truncate:HI
3984                   (const:DI
3985                    (sign_extend:DI
3986                     (truncate:HI
3987                      (match_dup 1))))))))]
3988   "TARGET_SHMEDIA64 && reload_completed
3989    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3990   "
3991 {
3992   if (GET_CODE (operands[1]) == LABEL_REF
3993       && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
3994     LABEL_NUSES (XEXP (operands[1], 0)) += 4;
3995   else if (GOTOFF_P (operands[1])
3996            && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == LABEL_REF
3997            && (GET_CODE (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0))
3998                == CODE_LABEL))
3999     LABEL_NUSES (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0)) += 4;
4000 }")
4001
4002 (define_expand "movdi_const_32bit"
4003   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
4004         (const:DI (sign_extend:DI
4005                    (truncate:HI
4006                     (ashiftrt:DI
4007                      (match_operand:DI 1 "immediate_operand" "s")
4008                      (const_int 16))))))
4009    (set (match_dup 0)
4010         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
4011                 (zero_extend:DI
4012                  (truncate:HI
4013                   (const:DI
4014                    (sign_extend:DI
4015                     (truncate:HI
4016                      (match_dup 1))))))))]
4017   "TARGET_SHMEDIA32 && reload_completed
4018    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
4019   "
4020 {
4021   if (GET_CODE (operands[1]) == LABEL_REF
4022       && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
4023     LABEL_NUSES (XEXP (operands[1], 0)) += 2;
4024   else if (GOTOFF_P (operands[1])
4025            && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == LABEL_REF
4026            && (GET_CODE (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0))
4027                == CODE_LABEL))
4028     LABEL_NUSES (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0)) += 2;
4029 }")
4030
4031 (define_expand "movdi_const_16bit"
4032   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
4033         (const:DI (sign_extend:DI
4034                    (truncate:HI
4035                     (match_operand:DI 1 "immediate_operand" "s")))))]
4036   "TARGET_SHMEDIA && flag_pic && reload_completed
4037    && GET_CODE (operands[1]) == SYMBOL_REF"
4038   "")
4039
4040 (define_split
4041   [(set (match_operand:DI 0 "arith_reg_operand" "")
4042         (match_operand:DI 1 "immediate_operand" ""))]
4043   "TARGET_SHMEDIA && reload_completed
4044    && GET_CODE (operands[1]) == CONST_INT
4045    && ! CONST_OK_FOR_J (INTVAL (operands[1]))"
4046   [(set (match_dup 0) (match_dup 2))
4047    (match_dup 1)]
4048   "
4049 {
4050   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
4051   unsigned HOST_WIDE_INT low = val;
4052   unsigned HOST_WIDE_INT high = val;
4053   unsigned HOST_WIDE_INT sign;
4054   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
4055
4056   /* Sign-extend the 16 least-significant bits.  */
4057   low &= 0xffff;
4058   low ^= 0x8000;
4059   low -= 0x8000;
4060
4061   /* Arithmetic shift right the word by 16 bits.  */
4062   high >>= 16;
4063   sign = 1;
4064   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4065   high ^= sign;
4066   high -= sign;
4067   do
4068     {
4069       /* If we can't generate the constant with a two-insn movi / shori
4070          sequence, try some other strategies.  */
4071       if (! CONST_OK_FOR_J (high))
4072         {
4073           /* Try constant load / left shift.  We know VAL != 0.  */
4074           val2 = val ^ (val-1);
4075           if (val2 > 0x1ffff)
4076             {
4077               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
4078
4079               if (CONST_OK_FOR_J (val >> trailing_zeroes)
4080                   || (! CONST_OK_FOR_J (high >> 16)
4081                       && CONST_OK_FOR_J (val >> (trailing_zeroes + 16))))
4082                 {
4083                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
4084                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
4085                                                    GEN_INT (trailing_zeroes));
4086                   break;
4087                 }
4088             }
4089           /* Try constant load / right shift.  */
4090           val2 = (val >> 15) + 1;
4091           if (val2 == (val2 & -val2))
4092             {
4093               int shift = 49 - exact_log2 (val2);
4094
4095               val2 = trunc_int_for_mode (val << shift, DImode);
4096               if (CONST_OK_FOR_J (val2))
4097                 {
4098                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
4099                                                    GEN_INT (shift));
4100                   break;
4101                 }
4102             }
4103           /* Try mperm.w .  */
4104           val2 = val & 0xffff;
4105           if ((val >> 16 & 0xffff) == val2
4106               && (val >> 32 & 0xffff) == val2
4107               && (val >> 48 & 0xffff) == val2)
4108             {
4109               val2 = (HOST_WIDE_INT) val >> 48;
4110               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
4111               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
4112               break;
4113             }
4114           /* Try movi / mshflo.l  */
4115           val2 = (HOST_WIDE_INT) val >> 32;
4116           if (val2 == trunc_int_for_mode (val, SImode))
4117             {
4118               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4119                                              operands[0]);
4120               break;
4121             }
4122           /* Try movi / mshflo.l w/ r63.  */
4123           val2 = val + ((HOST_WIDE_INT) -1 << 32);
4124           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_J (val2))
4125             {
4126               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4127                                              GEN_INT (0));
4128               break;
4129             }
4130         }
4131       val2 = high;
4132       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
4133     }
4134   while (0);
4135   operands[2] = GEN_INT (val2);
4136 }")
4137
4138 (define_split
4139   [(set (match_operand:DI 0 "arith_reg_operand" "")
4140         (match_operand:DI 1 "immediate_operand" ""))]
4141   "TARGET_SHMEDIA && reload_completed
4142    && GET_CODE (operands[1]) == CONST_DOUBLE"
4143   [(set (match_dup 0) (match_dup 2))
4144   (set (match_dup 0)
4145        (ior:DI (ashift:DI (match_dup 0) (const_int 16))
4146                (zero_extend:DI (truncate:HI (match_dup 1)))))]
4147   "
4148 {
4149   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4150   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
4151   unsigned HOST_WIDE_INT val = low;
4152   unsigned HOST_WIDE_INT sign;
4153
4154   /* Sign-extend the 16 least-significant bits.  */
4155   val &= 0xffff;
4156   val ^= 0x8000;
4157   val -= 0x8000;
4158   operands[1] = GEN_INT (val);
4159
4160   /* Arithmetic shift right the double-word by 16 bits.  */
4161   low >>= 16;
4162   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
4163   high >>= 16;
4164   sign = 1;
4165   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4166   high ^= sign;
4167   high -= sign;
4168
4169   /* This will only be true if high is a sign-extension of low, i.e.,
4170      it must be either 0 or (unsigned)-1, and be zero iff the
4171      most-significant bit of low is set.  */
4172   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
4173     operands[2] = GEN_INT (low);
4174   else
4175     operands[2] = immed_double_const (low, high, DImode);
4176 }")
4177
4178 (define_insn "shori_media"
4179   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
4180         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
4181                            (const_int 16))
4182                 (zero_extend:DI
4183                  (truncate:HI
4184                   (match_operand:DI 2 "immediate_operand" "JS,nF")))))]
4185   "TARGET_SHMEDIA"
4186   "@
4187         shori   %u2, %0
4188         #"
4189   [(set_attr "type" "arith_media,*")])
4190
4191 (define_expand "movdi"
4192   [(set (match_operand:DI 0 "general_movdst_operand" "")
4193         (match_operand:DI 1 "general_movsrc_operand" ""))]
4194   ""
4195   "{ if (prepare_move_operands (operands, DImode)) DONE; }")
4196
4197 (define_insn "movdf_media"
4198   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4199         (match_operand:DF 1 "general_movsrc_operand" "f,rU,f,r,F,m,f,m,r"))]
4200   "TARGET_SHMEDIA_FPU
4201    && (register_operand (operands[0], DFmode)
4202        || register_operand (operands[1], DFmode))"
4203   "@
4204         fmov.d  %1, %0
4205         fmov.qd %N1, %0
4206         fmov.dq %1, %0
4207         add     %1, r63, %0
4208         #
4209         fld%M1.d        %m1, %0
4210         fst%M0.d        %m0, %1
4211         ld%M1.q %m1, %0
4212         st%M0.q %m0, %1"
4213   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4214
4215 (define_insn "movdf_media_nofpu"
4216   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4217         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,r"))]
4218   "TARGET_SHMEDIA
4219    && (register_operand (operands[0], DFmode)
4220        || register_operand (operands[1], DFmode))"
4221   "@
4222         add     %1, r63, %0
4223         #
4224         ld%M1.q %m1, %0
4225         st%M0.q %m0, %1"
4226   [(set_attr "type" "arith_media,*,load_media,store_media")])
4227
4228 (define_split
4229   [(set (match_operand:DF 0 "arith_reg_operand" "")
4230         (match_operand:DF 1 "immediate_operand" ""))]
4231   "TARGET_SHMEDIA && reload_completed"
4232   [(set (match_dup 3) (match_dup 2))]
4233   "
4234 {
4235   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
4236   long values[2];
4237   REAL_VALUE_TYPE value;
4238
4239   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4240   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
4241
4242   if (HOST_BITS_PER_WIDE_INT >= 64)
4243     operands[2] = immed_double_const ((unsigned long) values[endian]
4244                                       | ((HOST_WIDE_INT) values[1 - endian]
4245                                          << 32), 0, DImode);
4246   else if (HOST_BITS_PER_WIDE_INT == 32)
4247     operands[2] = immed_double_const (values[endian], values[1 - endian],
4248                                       DImode);
4249   else
4250     abort ();
4251
4252   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4253 }")
4254
4255 ;; ??? This should be a define expand.
4256
4257 (define_insn "movdf_k"
4258   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4259         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
4260   "TARGET_SH1
4261    && (! TARGET_SH4 || reload_completed
4262        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
4263        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4264        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4265    && (arith_reg_operand (operands[0], DFmode)
4266        || arith_reg_operand (operands[1], DFmode))"
4267   "* return output_movedouble (insn, operands, DFmode);"
4268   [(set_attr "length" "4")
4269    (set_attr "type" "move,pcload,load,store")])
4270
4271 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
4272 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
4273 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
4274 ;; the d/m/c/X alternative, which is split later into single-precision
4275 ;; instructions.  And when not optimizing, no splits are done before fixing
4276 ;; up pcloads, so we need usable length information for that.
4277 (define_insn "movdf_i4"
4278   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
4279         (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
4280    (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
4281    (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
4282   "TARGET_SH4
4283    && (arith_reg_operand (operands[0], DFmode)
4284        || arith_reg_operand (operands[1], DFmode))"
4285   "@
4286         fmov    %1,%0
4287         #
4288         #
4289         fmov.d  %1,%0
4290         fmov.d  %1,%0
4291         #
4292         #
4293         #
4294         #
4295         #"
4296   [(set_attr_alternative "length"
4297      [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
4298       (const_int 4)
4299       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4300       (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4301       (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4302       (const_int 4)
4303       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
4304       ;; We can't use 4-byte push/pop on SHcompact, so we have to
4305       ;; increment or decrement r15 explicitly.
4306       (if_then_else
4307        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4308        (const_int 10) (const_int 8))
4309       (if_then_else
4310        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4311        (const_int 10) (const_int 8))])
4312    (set_attr "type" "fmove,move,pcload,load,store,pcload,load,store,load,load")
4313    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4314                                            (const_string "double")
4315                                            (const_string "none")))])
4316
4317 ;; Moving DFmode between fp/general registers through memory
4318 ;; (the top of the stack) is faster than moving through fpul even for
4319 ;; little endian.  Because the type of an instruction is important for its
4320 ;; scheduling,  it is beneficial to split these operations, rather than
4321 ;; emitting them in one single chunk, even if this will expose a stack
4322 ;; use that will prevent scheduling of other stack accesses beyond this
4323 ;; instruction.
4324 (define_split
4325   [(set (match_operand:DF 0 "register_operand" "")
4326         (match_operand:DF 1 "register_operand" ""))
4327    (use (match_operand:PSI 2 "fpscr_operand" ""))
4328    (clobber (match_scratch:SI 3 "=X"))]
4329   "TARGET_SH4 && reload_completed
4330    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
4331   [(const_int 0)]
4332   "
4333 {
4334   rtx insn, tos;
4335
4336   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
4337     {
4338       emit_move_insn (stack_pointer_rtx,
4339                       plus_constant (stack_pointer_rtx, -8));
4340       tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4341     }
4342   else
4343     tos = gen_rtx (MEM, DFmode, gen_rtx (PRE_DEC, Pmode, stack_pointer_rtx));
4344   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
4345   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
4346     REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4347   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4348     tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4349   else
4350     tos = gen_rtx (MEM, DFmode, gen_rtx (POST_INC, Pmode, stack_pointer_rtx));
4351   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
4352   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4353     emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
4354   else
4355     REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4356   DONE;
4357 }")
4358
4359 ;; local-alloc sometimes allocates scratch registers even when not required,
4360 ;; so we must be prepared to handle these.
4361
4362 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
4363 (define_split
4364   [(set (match_operand:DF 0 "general_movdst_operand" "")
4365         (match_operand:DF 1 "general_movsrc_operand"  ""))
4366    (use (match_operand:PSI 2 "fpscr_operand" ""))
4367    (clobber (match_scratch:SI 3 ""))]
4368   "TARGET_SH4
4369    && reload_completed
4370    && true_regnum (operands[0]) < 16
4371    && true_regnum (operands[1]) < 16"
4372   [(set (match_dup 0) (match_dup 1))]
4373   "
4374 {
4375   /* If this was a reg <-> mem operation with base + index reg addressing,
4376      we have to handle this in a special way.  */
4377   rtx mem = operands[0];
4378   int store_p = 1;
4379   if (! memory_operand (mem, DFmode))
4380     {
4381       mem = operands[1];
4382       store_p = 0;
4383     }
4384   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
4385     mem = SUBREG_REG (mem);
4386   if (GET_CODE (mem) == MEM)
4387     {
4388       rtx addr = XEXP (mem, 0);
4389       if (GET_CODE (addr) == PLUS
4390           && GET_CODE (XEXP (addr, 0)) == REG
4391           && GET_CODE (XEXP (addr, 1)) == REG)
4392         {
4393           int offset;
4394           rtx reg0 = gen_rtx (REG, Pmode, 0);
4395           rtx regop = operands[store_p], word0 ,word1;
4396
4397           if (GET_CODE (regop) == SUBREG)
4398             alter_subreg (&regop);
4399           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4400             offset = 2;
4401           else
4402             offset = 4;
4403           mem = copy_rtx (mem);
4404           PUT_MODE (mem, SImode);
4405           word0 = gen_rtx (SUBREG, SImode, regop, 0);
4406           alter_subreg (&word0);
4407           word1 = gen_rtx (SUBREG, SImode, regop, 4);
4408           alter_subreg (&word1);
4409           if (store_p || ! refers_to_regno_p (REGNO (word0),
4410                                               REGNO (word0) + 1, addr, 0))
4411             {
4412               emit_insn (store_p
4413                          ? gen_movsi_ie (mem, word0)
4414                          : gen_movsi_ie (word0, mem));
4415               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4416               mem = copy_rtx (mem);
4417               emit_insn (store_p
4418                          ? gen_movsi_ie (mem, word1)
4419                          : gen_movsi_ie (word1, mem));
4420               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4421             }
4422           else
4423             {
4424               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4425               emit_insn (gen_movsi_ie (word1, mem));
4426               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4427               mem = copy_rtx (mem);
4428               emit_insn (gen_movsi_ie (word0, mem));
4429             }
4430           DONE;
4431         }
4432     }
4433 }")
4434
4435 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4436 (define_split
4437   [(set (match_operand:DF 0 "register_operand" "")
4438         (match_operand:DF 1 "memory_operand"  ""))
4439    (use (match_operand:PSI 2 "fpscr_operand" ""))
4440    (clobber (reg:SI R0_REG))]
4441   "TARGET_SH4 && reload_completed"
4442   [(parallel [(set (match_dup 0) (match_dup 1))
4443               (use (match_dup 2))
4444               (clobber (scratch:SI))])]
4445   "")
4446
4447 (define_expand "reload_indf"
4448   [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4449                    (match_operand:DF 1 "immediate_operand" "FQ"))
4450               (use (reg:PSI FPSCR_REG))
4451               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4452   "TARGET_SH1"
4453   "")
4454
4455 (define_expand "reload_outdf"
4456   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4457                    (match_operand:DF 1 "register_operand" "af,r"))
4458               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
4459   "TARGET_SH1"
4460   "")
4461
4462 ;; Simplify no-op moves.
4463 (define_split
4464   [(set (match_operand:SF 0 "register_operand" "")
4465         (match_operand:SF 1 "register_operand" ""))
4466    (use (match_operand:PSI 2 "fpscr_operand" ""))
4467    (clobber (match_scratch:SI 3 "X"))]
4468   "TARGET_SH3E && reload_completed
4469    && true_regnum (operands[0]) == true_regnum (operands[1])"
4470   [(set (match_dup 0) (match_dup 0))]
4471   "")
4472
4473 ;; fmovd substitute post-reload splits
4474 (define_split
4475   [(set (match_operand:DF 0 "register_operand" "")
4476         (match_operand:DF 1 "register_operand" ""))
4477    (use (match_operand:PSI 2 "fpscr_operand" ""))
4478    (clobber (match_scratch:SI 3 "X"))]
4479   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4480    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4481    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4482   [(const_int 0)]
4483   "
4484 {
4485   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4486   emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst),
4487                            gen_rtx (REG, SFmode, src), operands[2]));
4488   emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst + 1),
4489                            gen_rtx (REG, SFmode, src + 1), operands[2]));
4490   DONE;
4491 }")
4492
4493 (define_split
4494   [(set (match_operand:DF 0 "register_operand" "")
4495         (mem:DF (match_operand:SI 1 "register_operand" "")))
4496    (use (match_operand:PSI 2 "fpscr_operand" ""))
4497    (clobber (match_scratch:SI 3 ""))]
4498   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4499    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4500    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4501   [(const_int 0)]
4502   "
4503 {
4504   int regno = true_regnum (operands[0]);
4505   rtx insn;
4506   rtx mem2 = gen_rtx (MEM, SFmode, gen_rtx (POST_INC, Pmode, operands[1]));
4507
4508   insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4509                                            regno + !! TARGET_LITTLE_ENDIAN),
4510                                   mem2, operands[2]));
4511   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[1], NULL_RTX);
4512   insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4513                                            regno + ! TARGET_LITTLE_ENDIAN),
4514                                   gen_rtx (MEM, SFmode, operands[1]),
4515                                   operands[2]));
4516   DONE;
4517 }")
4518
4519 (define_split
4520   [(set (match_operand:DF 0 "register_operand" "")
4521         (match_operand:DF 1 "memory_operand" ""))
4522    (use (match_operand:PSI 2 "fpscr_operand" ""))
4523    (clobber (match_scratch:SI 3 ""))]
4524   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4525    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
4526   [(const_int 0)]
4527   "
4528 {
4529   int regno = true_regnum (operands[0]);
4530   rtx addr, insn, adjust = NULL_RTX;
4531   rtx mem2 = copy_rtx (operands[1]);
4532   rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4533   rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4534
4535   PUT_MODE (mem2, SFmode);
4536   operands[1] = copy_rtx (mem2);
4537   addr = XEXP (mem2, 0);
4538   if (GET_CODE (addr) != POST_INC)
4539     {
4540       /* If we have to modify the stack pointer, the value that we have
4541          read with post-increment might be modified by an interrupt,
4542          so write it back.  */
4543       if (REGNO (addr) == STACK_POINTER_REGNUM)
4544         adjust = gen_push_e (reg0);
4545       else
4546         adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4547       XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4548     }
4549   addr = XEXP (addr, 0);
4550   insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4551   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4552   insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4553   if (adjust)
4554     emit_insn (adjust);
4555   else
4556     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4557   DONE;
4558 }")
4559
4560 (define_split
4561   [(set (match_operand:DF 0 "memory_operand" "")
4562         (match_operand:DF 1 "register_operand" ""))
4563    (use (match_operand:PSI 2 "fpscr_operand" ""))
4564    (clobber (match_scratch:SI 3 ""))]
4565   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4566    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4567   [(const_int 0)]
4568   "
4569 {
4570   int regno = true_regnum (operands[1]);
4571   rtx insn, addr, adjust = NULL_RTX;
4572
4573   operands[0] = copy_rtx (operands[0]);
4574   PUT_MODE (operands[0], SFmode);
4575   insn = emit_insn (gen_movsf_ie (operands[0],
4576                                   gen_rtx (REG, SFmode,
4577                                            regno + ! TARGET_LITTLE_ENDIAN),
4578                                   operands[2]));
4579   operands[0] = copy_rtx (operands[0]);
4580   addr = XEXP (operands[0], 0);
4581   if (GET_CODE (addr) != PRE_DEC)
4582     {
4583       adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4584       emit_insn_before (adjust, insn);
4585       XEXP (operands[0], 0) = addr = gen_rtx (PRE_DEC, SImode, addr);
4586     }
4587   addr = XEXP (addr, 0);
4588   if (! adjust)
4589     REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4590   insn = emit_insn (gen_movsf_ie (operands[0],
4591                                   gen_rtx (REG, SFmode,
4592                                            regno + !! TARGET_LITTLE_ENDIAN),
4593                                   operands[2]));
4594   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4595   DONE;
4596 }")
4597
4598 ;; If the output is a register and the input is memory or a register, we have
4599 ;; to be careful and see which word needs to be loaded first.
4600
4601 (define_split
4602   [(set (match_operand:DF 0 "general_movdst_operand" "")
4603         (match_operand:DF 1 "general_movsrc_operand" ""))]
4604   "TARGET_SH1 && reload_completed"
4605   [(set (match_dup 2) (match_dup 3))
4606    (set (match_dup 4) (match_dup 5))]
4607   "
4608 {
4609   int regno;
4610
4611   if ((GET_CODE (operands[0]) == MEM
4612        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4613       || (GET_CODE (operands[1]) == MEM
4614           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4615     FAIL;
4616
4617   if (GET_CODE (operands[0]) == REG)
4618     regno = REGNO (operands[0]);
4619   else if (GET_CODE (operands[0]) == SUBREG)
4620     regno = subreg_regno (operands[0]);
4621   else if (GET_CODE (operands[0]) == MEM)
4622     regno = -1;
4623   else
4624     abort ();
4625
4626   if (regno == -1
4627       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
4628     {
4629       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4630       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4631       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4632       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4633     }
4634   else
4635     {
4636       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4637       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4638       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4639       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4640     }
4641
4642   if (operands[2] == 0 || operands[3] == 0
4643       || operands[4] == 0 || operands[5] == 0)
4644     FAIL;
4645 }")
4646
4647 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4648 ;; used only once, let combine add in the index again.
4649
4650 (define_split
4651   [(set (match_operand:SI 0 "register_operand" "")
4652         (match_operand:SI 1 "" ""))
4653    (clobber (match_operand 2 "register_operand" ""))]
4654   "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4655   [(use (reg:SI R0_REG))]
4656   "
4657 {
4658   rtx addr, reg, const_int;
4659
4660   if (GET_CODE (operands[1]) != MEM)
4661     FAIL;
4662   addr = XEXP (operands[1], 0);
4663   if (GET_CODE (addr) != PLUS)
4664     FAIL;
4665   reg = XEXP (addr, 0);
4666   const_int = XEXP (addr, 1);
4667   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4668          && GET_CODE (const_int) == CONST_INT))
4669     FAIL;
4670   emit_move_insn (operands[2], const_int);
4671   emit_move_insn (operands[0],
4672                   change_address (operands[1], VOIDmode,
4673                                   gen_rtx_PLUS (SImode, reg, operands[2])));
4674   DONE;
4675 }")
4676
4677 (define_split
4678   [(set (match_operand:SI 1 "" "")
4679         (match_operand:SI 0 "register_operand" ""))
4680    (clobber (match_operand 2 "register_operand" ""))]
4681   "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4682   [(use (reg:SI R0_REG))]
4683   "
4684 {
4685   rtx addr, reg, const_int;
4686
4687   if (GET_CODE (operands[1]) != MEM)
4688     FAIL;
4689   addr = XEXP (operands[1], 0);
4690   if (GET_CODE (addr) != PLUS)
4691     FAIL;
4692   reg = XEXP (addr, 0);
4693   const_int = XEXP (addr, 1);
4694   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4695          && GET_CODE (const_int) == CONST_INT))
4696     FAIL;
4697   emit_move_insn (operands[2], const_int);
4698   emit_move_insn (change_address (operands[1], VOIDmode,
4699                                   gen_rtx_PLUS (SImode, reg, operands[2])),
4700                   operands[0]);
4701   DONE;
4702 }")
4703
4704 (define_expand "movdf"
4705   [(set (match_operand:DF 0 "general_movdst_operand" "")
4706         (match_operand:DF 1 "general_movsrc_operand" ""))]
4707   ""
4708   "
4709 {
4710   if (prepare_move_operands (operands, DFmode)) DONE;
4711   if (TARGET_SHMEDIA)
4712     {
4713       if (TARGET_SHMEDIA_FPU)
4714         emit_insn (gen_movdf_media (operands[0], operands[1]));
4715       else
4716         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4717       DONE;
4718     }
4719   if (TARGET_SH4)
4720     {
4721       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4722       DONE;
4723     }
4724 }")
4725
4726 ;;This is incompatible with the way gcc uses subregs.
4727 ;;(define_insn "movv2sf_i"
4728 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4729 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4730 ;;  "TARGET_SHMEDIA_FPU
4731 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
4732 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
4733 ;;  "@
4734 ;;      #
4735 ;;      fld%M1.p        %m1, %0
4736 ;;      fst%M0.p        %m0, %1"
4737 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
4738
4739 (define_insn_and_split "movv2sf_i"
4740   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
4741         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfU?"))]
4742   "TARGET_SHMEDIA_FPU"
4743   "#"
4744   "TARGET_SHMEDIA_FPU && reload_completed"
4745   [(set (match_dup 0) (match_dup 1))]
4746   "
4747 {
4748   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
4749   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
4750 }")
4751
4752 (define_expand "movv2sf"
4753   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
4754         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
4755   "TARGET_SHMEDIA_FPU"
4756   "
4757 {
4758   if (prepare_move_operands (operands, V2SFmode))
4759     DONE;
4760 }")
4761
4762 (define_expand "addv2sf3"
4763   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4764    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4765    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4766   "TARGET_SHMEDIA_FPU"
4767   "
4768 {
4769   sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
4770   DONE;
4771 }")
4772
4773 (define_expand "subv2sf3"
4774   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4775    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4776    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4777   "TARGET_SHMEDIA_FPU"
4778   "
4779 {
4780   sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
4781   DONE;
4782 }")
4783
4784 (define_expand "mulv2sf3"
4785   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4786    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4787    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4788   "TARGET_SHMEDIA_FPU"
4789   "
4790 {
4791   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
4792   DONE;
4793 }")
4794
4795 (define_expand "divv2sf3"
4796   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4797    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4798    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4799   "TARGET_SHMEDIA_FPU"
4800   "
4801 {
4802   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
4803   DONE;
4804 }")
4805
4806 (define_insn_and_split "*movv4sf_i"
4807   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4808         (match_operand:V4SF 1 "general_operand" "fU,m,f"))]
4809   "TARGET_SHMEDIA_FPU"
4810   "#"
4811   "&& reload_completed"
4812   [(const_int 0)]
4813   "
4814 {
4815   int i;
4816
4817   for (i = 0; i < 4/2; i++)
4818     {
4819       rtx x, y;
4820
4821       if (GET_CODE (operands[0]) == MEM)
4822         x = gen_rtx_MEM (V2SFmode,
4823                          plus_constant (XEXP (operands[0], 0),
4824                                         i * GET_MODE_SIZE (V2SFmode)));
4825       else
4826         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
4827
4828       if (GET_CODE (operands[1]) == MEM)
4829         y = gen_rtx_MEM (V2SFmode,
4830                          plus_constant (XEXP (operands[1], 0),
4831                                         i * GET_MODE_SIZE (V2SFmode)));
4832       else
4833         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
4834
4835       emit_insn (gen_movv2sf_i (x, y));
4836     }
4837
4838   DONE;
4839 }"
4840   [(set_attr "length" "8")])
4841
4842 (define_expand "movv4sf"
4843   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
4844         (match_operand:V4SF 1 "general_operand" ""))]
4845   "TARGET_SHMEDIA_FPU"
4846   "
4847 {
4848   if (prepare_move_operands (operands, V4SFmode))
4849     DONE;
4850 }")
4851
4852 (define_insn_and_split "*movv16sf_i"
4853   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4854         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4855   "TARGET_SHMEDIA_FPU"
4856   "#"
4857   "&& reload_completed"
4858   [(const_int 0)]
4859   "
4860 {
4861   int i;
4862
4863   for (i = 0; i < 16/2; i++)
4864     {
4865       rtx x,y;
4866
4867       if (GET_CODE (operands[0]) == MEM)
4868         x = gen_rtx_MEM (V2SFmode,
4869                          plus_constant (XEXP (operands[0], 0),
4870                                         i * GET_MODE_SIZE (V2SFmode)));
4871       else
4872         {
4873           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 2);
4874           alter_subreg (&x);
4875         }
4876
4877       if (GET_CODE (operands[1]) == MEM)
4878         y = gen_rtx_MEM (V2SFmode,
4879                          plus_constant (XEXP (operands[1], 0),
4880                                         i * GET_MODE_SIZE (V2SFmode)));
4881       else
4882         {
4883           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 2);
4884           alter_subreg (&y);
4885         }
4886
4887       emit_insn (gen_movv2sf_i (x, y));
4888     }
4889
4890   DONE;
4891 }"
4892   [(set_attr "length" "32")])
4893
4894 (define_expand "movv16sf"
4895   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4896         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4897   "TARGET_SHMEDIA_FPU"
4898   "
4899 {
4900   if (prepare_move_operands (operands, V16SFmode))
4901     DONE;
4902 }")
4903
4904 (define_insn "movsf_media"
4905   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4906         (match_operand:SF 1 "general_movsrc_operand" "f,rU,f,r,F,m,f,m,r"))]
4907   "TARGET_SHMEDIA_FPU
4908    && (register_operand (operands[0], SFmode)
4909        || register_operand (operands[1], SFmode))"
4910   "@
4911         fmov.s  %1, %0
4912         fmov.ls %N1, %0
4913         fmov.sl %1, %0
4914         add.l   %1, r63, %0
4915         #
4916         fld%M1.s        %m1, %0
4917         fst%M0.s        %m0, %1
4918         ld%M1.l %m1, %0
4919         st%M0.l %m0, %1"
4920   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4921
4922 (define_insn "movsf_media_nofpu"
4923   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
4924         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,r"))]
4925   "TARGET_SHMEDIA
4926    && (register_operand (operands[0], SFmode)
4927        || register_operand (operands[1], SFmode))"
4928   "@
4929         add.l   %1, r63, %0
4930         #
4931         ld%M1.l %m1, %0
4932         st%M0.l %m0, %1"
4933   [(set_attr "type" "arith_media,*,load_media,store_media")])
4934
4935 (define_split
4936   [(set (match_operand:SF 0 "arith_reg_operand" "")
4937         (match_operand:SF 1 "immediate_operand" ""))]
4938   "TARGET_SHMEDIA && reload_completed
4939    && ! FP_REGISTER_P (true_regnum (operands[0]))"
4940   [(set (match_dup 3) (match_dup 2))]
4941   "
4942 {
4943   long values;
4944   REAL_VALUE_TYPE value;
4945
4946   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4947   REAL_VALUE_TO_TARGET_SINGLE (value, values);
4948   operands[2] = GEN_INT (values);
4949
4950   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4951 }")
4952
4953 (define_insn "movsf_i"
4954   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
4955         (match_operand:SF 1 "general_movsrc_operand"  "r,I,FQ,mr,r,r,l"))]
4956   "TARGET_SH1
4957    && (! TARGET_SH3E
4958        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4959        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4960        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4961    && (arith_reg_operand (operands[0], SFmode)
4962        || arith_reg_operand (operands[1], SFmode))"
4963   "@
4964         mov     %1,%0
4965         mov     %1,%0
4966         mov.l   %1,%0
4967         mov.l   %1,%0
4968         mov.l   %1,%0
4969         lds     %1,%0
4970         sts     %1,%0"
4971   [(set_attr "type" "move,move,pcload,load,store,move,move")])
4972
4973 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4974 ;; update_flow_info would not know where to put REG_EQUAL notes
4975 ;; when the destination changes mode.
4976 (define_insn "movsf_ie"
4977   [(set (match_operand:SF 0 "general_movdst_operand"
4978          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
4979         (match_operand:SF 1 "general_movsrc_operand"
4980           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4981    (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"))
4982    (clobber (match_scratch:SI 3 "=X,X,X,X,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
4983
4984   "TARGET_SH3E
4985    && (arith_reg_operand (operands[0], SFmode)
4986        || arith_reg_operand (operands[1], SFmode)
4987        || arith_reg_operand (operands[3], SImode)
4988        || (fpul_operand (operands[0], SFmode)
4989            && memory_operand (operands[1], SFmode)
4990            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4991        || (fpul_operand (operands[1], SFmode)
4992            && memory_operand (operands[0], SFmode)
4993            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
4994   "@
4995         fmov    %1,%0
4996         mov     %1,%0
4997         fldi0   %0
4998         fldi1   %0
4999         #
5000         fmov.s  %1,%0
5001         fmov.s  %1,%0
5002         mov.l   %1,%0
5003         mov.l   %1,%0
5004         mov.l   %1,%0
5005         fsts    fpul,%0
5006         flds    %1,fpul
5007         lds.l   %1,%0
5008         #
5009         sts     %1,%0
5010         lds     %1,%0
5011         sts.l   %1,%0
5012         lds.l   %1,%0
5013         ! move optimized away"
5014   [(set_attr "type" "fmove,move,fmove,fmove,pcload,load,store,pcload,load,store,fmove,fmove,load,*,gp_fpul,gp_fpul,store,load,nil")
5015    (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,4,2,2,2,2,0")
5016    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5017                                            (const_string "single")
5018                                            (const_string "none")))])
5019
5020 (define_split
5021   [(set (match_operand:SF 0 "register_operand" "")
5022         (match_operand:SF 1 "register_operand" ""))
5023    (use (match_operand:PSI 2 "fpscr_operand" ""))
5024    (clobber (reg:SI FPUL_REG))]
5025   "TARGET_SH1"
5026   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
5027               (use (match_dup 2))
5028               (clobber (scratch:SI))])
5029    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
5030               (use (match_dup 2))
5031               (clobber (scratch:SI))])]
5032   "")
5033
5034 (define_expand "movsf"
5035   [(set (match_operand:SF 0 "general_movdst_operand" "")
5036         (match_operand:SF 1 "general_movsrc_operand" ""))]
5037   ""
5038   "
5039 {
5040   if (prepare_move_operands (operands, SFmode))
5041     DONE;
5042   if (TARGET_SHMEDIA)
5043     {
5044       if (TARGET_SHMEDIA_FPU)
5045         emit_insn (gen_movsf_media (operands[0], operands[1]));
5046       else
5047         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
5048       DONE;
5049     }
5050   if (TARGET_SH3E)
5051     {
5052       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
5053       DONE;
5054     }
5055 }")
5056
5057 (define_insn "mov_nop"
5058   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
5059   "TARGET_SH3E"
5060   ""
5061   [(set_attr "length" "0")
5062    (set_attr "type" "nil")])
5063
5064 (define_expand "reload_insf"
5065   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
5066                    (match_operand:SF 1 "immediate_operand" "FQ"))
5067               (use (reg:PSI FPSCR_REG))
5068               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5069   "TARGET_SH1"
5070   "")
5071
5072 (define_expand "reload_insi"
5073   [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
5074                    (match_operand:SF 1 "immediate_operand" "FQ"))
5075               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5076   "TARGET_SH1"
5077   "")
5078
5079 (define_insn "*movsi_y"
5080   [(set (match_operand:SI 0 "register_operand" "=y,y")
5081         (match_operand:SI 1 "immediate_operand" "Qi,I"))
5082    (clobber (match_scratch:SI 2 "=&z,r"))]
5083   "TARGET_SH3E
5084    && (reload_in_progress || reload_completed)"
5085   "#"
5086   [(set_attr "length" "4")
5087    (set_attr "type" "pcload,move")])
5088
5089 (define_split
5090   [(set (match_operand:SI 0 "register_operand" "")
5091         (match_operand:SI 1 "immediate_operand" ""))
5092    (clobber (match_operand:SI 2 "register_operand" ""))]
5093   "TARGET_SH1"
5094   [(set (match_dup 2) (match_dup 1))
5095    (set (match_dup 0) (match_dup 2))]
5096   "")
5097
5098 (define_split
5099   [(set (match_operand:SI 0 "register_operand" "")
5100         (match_operand:SI 1 "memory_operand" ""))
5101    (clobber (reg:SI R0_REG))]
5102   "TARGET_SH1"
5103   [(set (match_dup 0) (match_dup 1))]
5104   "")
5105 \f
5106 ;; ------------------------------------------------------------------------
5107 ;; Define the real conditional branch instructions.
5108 ;; ------------------------------------------------------------------------
5109
5110 (define_insn "branch_true"
5111   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
5112                            (label_ref (match_operand 0 "" ""))
5113                            (pc)))]
5114   "TARGET_SH1"
5115   "* return output_branch (1, insn, operands);"
5116   [(set_attr "type" "cbranch")])
5117
5118 (define_insn "branch_false"
5119   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
5120                            (label_ref (match_operand 0 "" ""))
5121                            (pc)))]
5122   "TARGET_SH1"
5123   "* return output_branch (0, insn, operands);"
5124   [(set_attr "type" "cbranch")])
5125
5126 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
5127 ;; which destination is too far away.
5128 ;; The const_int_operand is distinct for each branch target; it avoids
5129 ;; unwanted matches with redundant_insn.
5130 (define_insn "block_branch_redirect"
5131   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
5132   "TARGET_SH1"
5133   ""
5134   [(set_attr "length" "0")])
5135
5136 ;; This one has the additional purpose to record a possible scratch register
5137 ;; for the following branch.
5138 (define_insn "indirect_jump_scratch"
5139   [(set (match_operand:SI 0 "register_operand" "=r")
5140         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))]
5141   "TARGET_SH1"
5142   ""
5143   [(set_attr "length" "0")])
5144 \f
5145 ;; Conditional branch insns
5146
5147 (define_expand "beq_media"
5148   [(set (pc)
5149         (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
5150                           (match_operand:DI 2 "arith_operand" "r,O"))
5151                       (label_ref:DI (match_operand 0 "" ""))
5152                       (pc)))]
5153   "TARGET_SHMEDIA"
5154   "")
5155
5156 (define_insn "*beq_media_i"
5157   [(set (pc)
5158         (if_then_else (match_operator 3 "equality_comparison_operator"
5159                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
5160                          (match_operand:DI 2 "arith_operand" "r,O")])
5161                       (match_operand:DI 0 "target_operand" "b,b")
5162                       (pc)))]
5163   "TARGET_SHMEDIA"
5164   "@
5165         b%o3%'  %1, %2, %0
5166         b%o3i%' %1, %2, %0"
5167   [(set_attr "type" "cbranch_media")])
5168
5169 (define_expand "bne_media"
5170   [(set (pc)
5171         (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
5172                           (match_operand:DI 2 "arith_operand" "r,O"))
5173                       (label_ref:DI (match_operand 0 "" ""))
5174                       (pc)))]
5175   "TARGET_SHMEDIA"
5176   "")
5177
5178 (define_expand "bgt_media"
5179   [(set (pc)
5180         (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5181                           (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5182                       (label_ref:DI (match_operand 0 "" ""))
5183                       (pc)))]
5184   "TARGET_SHMEDIA"
5185   "")
5186
5187 (define_expand "bge_media"
5188   [(set (pc)
5189         (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5190                           (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5191                       (label_ref:DI (match_operand 0 "" ""))
5192                       (pc)))]
5193   "TARGET_SHMEDIA"
5194   "")
5195
5196 (define_expand "bgtu_media"
5197   [(set (pc)
5198         (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5199                            (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5200                       (label_ref:DI (match_operand 0 "" ""))
5201                       (pc)))]
5202   "TARGET_SHMEDIA"
5203   "")
5204
5205 (define_expand "bgeu_media"
5206   [(set (pc)
5207         (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5208                            (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5209                       (label_ref:DI (match_operand 0 "" ""))
5210                       (pc)))]
5211   "TARGET_SHMEDIA"
5212   "")
5213
5214 (define_insn "*bgt_media_i"
5215   [(set (pc)
5216         (if_then_else (match_operator 3 "greater_comparison_operator"
5217                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5218                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5219                       (match_operand:DI 0 "target_operand" "b")
5220                       (pc)))]
5221   "TARGET_SHMEDIA"
5222   "b%o3%'       %N1, %N2, %0"
5223   [(set_attr "type" "cbranch_media")])
5224
5225 ;; These are only needed to make invert_jump() happy.
5226 (define_insn "*blt_media_i"
5227   [(set (pc)
5228         (if_then_else (match_operator 3 "less_comparison_operator"
5229                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5230                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5231                       (match_operand:DI 0 "target_operand" "b")
5232                       (pc)))]
5233   "TARGET_SHMEDIA"
5234   "b%o3%'       %N2, %N1, %0"
5235   [(set_attr "type" "cbranch_media")])
5236
5237 (define_expand "beq"
5238   [(set (pc)
5239         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5240                       (label_ref (match_operand 0 "" ""))
5241                       (pc)))]
5242   ""
5243   "
5244 {
5245   if (TARGET_SHMEDIA)
5246     {
5247       if (GET_MODE (sh_compare_op0) != DImode)
5248         {
5249           rtx tmp = gen_reg_rtx (DImode);
5250
5251           emit_insn (gen_seq (tmp));
5252           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5253           DONE;
5254         }
5255
5256       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5257       emit_jump_insn (gen_beq_media (operands[0],
5258                                      sh_compare_op0, sh_compare_op1));
5259       DONE;
5260     }
5261
5262   from_compare (operands, EQ);
5263 }")
5264
5265 (define_expand "bne"
5266   [(set (pc)
5267         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5268                       (label_ref (match_operand 0 "" ""))
5269                       (pc)))]
5270   ""
5271   "
5272 {
5273   if (TARGET_SHMEDIA)
5274     {
5275       if (GET_MODE (sh_compare_op0) != DImode)
5276         {
5277           rtx tmp = gen_reg_rtx (DImode);
5278
5279           emit_insn (gen_seq (tmp));
5280           emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
5281           DONE;
5282         }
5283
5284       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5285       emit_jump_insn (gen_bne_media (operands[0],
5286                                      sh_compare_op0, sh_compare_op1));
5287       DONE;
5288     }
5289
5290   from_compare (operands, EQ);
5291 }")
5292
5293 (define_expand "bgt"
5294   [(set (pc)
5295         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5296                       (label_ref (match_operand 0 "" ""))
5297                       (pc)))]
5298   ""
5299   "
5300 {
5301   if (TARGET_SHMEDIA)
5302     {
5303       if (GET_MODE (sh_compare_op0) != DImode)
5304         {
5305           rtx tmp = gen_reg_rtx (DImode);
5306
5307           emit_insn (gen_sgt (tmp));
5308           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5309           DONE;
5310         }
5311
5312       if (sh_compare_op0 != const0_rtx)
5313         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5314       if (sh_compare_op1 != const0_rtx)
5315         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5316       emit_jump_insn (gen_bgt_media (operands[0],
5317                                      sh_compare_op0, sh_compare_op1));
5318       DONE;
5319     }
5320
5321   from_compare (operands, GT);
5322 }")
5323
5324 (define_expand "blt"
5325   [(set (pc)
5326         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5327                       (label_ref (match_operand 0 "" ""))
5328                       (pc)))]
5329   ""
5330   "
5331 {
5332   if (TARGET_SHMEDIA)
5333     {
5334       if (GET_MODE (sh_compare_op0) != DImode)
5335         {
5336           rtx tmp = gen_reg_rtx (DImode);
5337
5338           emit_insn (gen_slt (tmp));
5339           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5340           DONE;
5341         }
5342
5343       if (sh_compare_op0 != const0_rtx)
5344         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5345       if (sh_compare_op1 != const0_rtx)
5346         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5347       emit_jump_insn (gen_bgt_media (operands[0],
5348                                      sh_compare_op1, sh_compare_op0));
5349       DONE;
5350     }
5351
5352   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5353     {
5354       rtx tmp = sh_compare_op0;
5355       sh_compare_op0 = sh_compare_op1;
5356       sh_compare_op1 = tmp;
5357       emit_insn (gen_bgt (operands[0]));
5358       DONE;
5359     }
5360   from_compare (operands, GE);
5361 }")
5362
5363 (define_expand "ble"
5364   [(set (pc)
5365         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5366                       (label_ref (match_operand 0 "" ""))
5367                       (pc)))]
5368   ""
5369   "
5370 {
5371   if (TARGET_SHMEDIA)
5372     {
5373       if (GET_MODE (sh_compare_op0) != DImode)
5374         {
5375           rtx tmp = gen_reg_rtx (DImode);
5376
5377           emit_insn (gen_sle (tmp));
5378           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5379           DONE;
5380         }
5381
5382       if (sh_compare_op0 != const0_rtx)
5383         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5384       if (sh_compare_op1 != const0_rtx)
5385         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5386       emit_jump_insn (gen_bge_media (operands[0],
5387                                      sh_compare_op1, sh_compare_op0));
5388       DONE;
5389     }
5390
5391   if (TARGET_SH3E
5392       && TARGET_IEEE
5393       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5394     {
5395       rtx tmp = sh_compare_op0;
5396       sh_compare_op0 = sh_compare_op1;
5397       sh_compare_op1 = tmp;
5398       emit_insn (gen_bge (operands[0]));
5399       DONE;
5400     }
5401   from_compare (operands, GT);
5402 }")
5403
5404 (define_expand "bge"
5405   [(set (pc)
5406         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5407                       (label_ref (match_operand 0 "" ""))
5408                       (pc)))]
5409   ""
5410   "
5411 {
5412   if (TARGET_SHMEDIA)
5413     {
5414       if (GET_MODE (sh_compare_op0) != DImode)
5415         {
5416           rtx tmp = gen_reg_rtx (DImode);
5417
5418           emit_insn (gen_sge (tmp));
5419           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5420           DONE;
5421         }
5422
5423       if (sh_compare_op0 != const0_rtx)
5424         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5425       if (sh_compare_op1 != const0_rtx)
5426         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5427       emit_jump_insn (gen_bge_media (operands[0],
5428                                      sh_compare_op0, sh_compare_op1));
5429       DONE;
5430     }
5431
5432   if (TARGET_SH3E
5433       && ! TARGET_IEEE
5434       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5435     {
5436       rtx tmp = sh_compare_op0;
5437       sh_compare_op0 = sh_compare_op1;
5438       sh_compare_op1 = tmp;
5439       emit_insn (gen_ble (operands[0]));
5440       DONE;
5441     }
5442   from_compare (operands, GE);
5443 }")
5444
5445 (define_expand "bgtu"
5446   [(set (pc)
5447         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5448                       (label_ref (match_operand 0 "" ""))
5449                       (pc)))]
5450   ""
5451   "
5452 {
5453   if (TARGET_SHMEDIA)
5454     {
5455       if (sh_compare_op0 != const0_rtx)
5456         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5457       if (sh_compare_op1 != const0_rtx)
5458         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5459       emit_jump_insn (gen_bgtu_media (operands[0],
5460                                       sh_compare_op0, sh_compare_op1));
5461       DONE;
5462     }
5463
5464   from_compare (operands, GTU);
5465 }")
5466
5467 (define_expand "bltu"
5468   [(set (pc)
5469         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5470                       (label_ref (match_operand 0 "" ""))
5471                       (pc)))]
5472   ""
5473   "
5474 {
5475   if (TARGET_SHMEDIA)
5476     {
5477       if (sh_compare_op0 != const0_rtx)
5478         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5479       if (sh_compare_op1 != const0_rtx)
5480         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5481       emit_jump_insn (gen_bgtu_media (operands[0],
5482                                       sh_compare_op1, sh_compare_op0));
5483       DONE;
5484     }
5485
5486   from_compare (operands, GEU);
5487 }")
5488
5489 (define_expand "bgeu"
5490   [(set (pc)
5491         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5492                       (label_ref (match_operand 0 "" ""))
5493                       (pc)))]
5494   ""
5495   "
5496 {
5497   if (TARGET_SHMEDIA)
5498     {
5499       if (sh_compare_op0 != const0_rtx)
5500         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5501       if (sh_compare_op1 != const0_rtx)
5502         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5503       emit_jump_insn (gen_bgeu_media (operands[0],
5504                                       sh_compare_op0, sh_compare_op1));
5505       DONE;
5506     }
5507
5508   from_compare (operands, GEU);
5509 }")
5510
5511 (define_expand "bleu"
5512   [(set (pc)
5513         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5514                       (label_ref (match_operand 0 "" ""))
5515                       (pc)))]
5516   ""
5517   "
5518 {
5519   if (TARGET_SHMEDIA)
5520     {
5521       if (sh_compare_op0 != const0_rtx)
5522         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5523       if (sh_compare_op1 != const0_rtx)
5524         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5525       emit_jump_insn (gen_bgeu_media (operands[0],
5526                                       sh_compare_op1, sh_compare_op0));
5527       DONE;
5528     }
5529
5530   from_compare (operands, GTU);
5531 }")
5532
5533 (define_expand "bunordered"
5534   [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5535    (set (pc)
5536         (if_then_else (ne (match_dup 1) (const_int 0))
5537                       (label_ref:DI (match_operand 0 "" ""))
5538                       (pc)))]
5539   "TARGET_SHMEDIA"
5540   "
5541 {
5542   operands[1] = gen_reg_rtx (DImode);
5543   operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5544   operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5545 }")
5546 \f
5547 ;; ------------------------------------------------------------------------
5548 ;; Jump and linkage insns
5549 ;; ------------------------------------------------------------------------
5550
5551 (define_insn "jump_compact"
5552   [(set (pc)
5553         (label_ref (match_operand 0 "" "")))]
5554   "TARGET_SH1"
5555   "*
5556 {
5557   /* The length is 16 if the delay slot is unfilled.  */
5558   if (get_attr_length(insn) > 4)
5559     return output_far_jump(insn, operands[0]);
5560   else
5561     return   \"bra      %l0%#\";
5562 }"
5563   [(set_attr "type" "jump")
5564    (set_attr "needs_delay_slot" "yes")])
5565
5566 (define_insn "jump_media"
5567   [(set (pc)
5568         (match_operand:DI 0 "target_operand" "b"))]
5569   "TARGET_SHMEDIA"
5570   "blink        %0, r63"
5571   [(set_attr "type" "jump_media")])
5572
5573 (define_expand "jump"
5574   [(set (pc)
5575         (label_ref (match_operand 0 "" "")))]
5576   ""
5577   "
5578 {
5579   if (TARGET_SH1)
5580     emit_jump_insn (gen_jump_compact (operands[0]));
5581   else if (TARGET_SHMEDIA)
5582     {
5583       if (reload_in_progress || reload_completed)
5584         FAIL;
5585       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5586                                                          operands[0])));
5587     }
5588   DONE;
5589 }")
5590
5591 (define_insn "force_mode_for_call"
5592   [(use (reg:PSI FPSCR_REG))]
5593   "TARGET_SHCOMPACT"
5594   ""
5595   [(set_attr "length" "0")
5596    (set (attr "fp_mode")
5597         (if_then_else (eq_attr "fpu_single" "yes")
5598                       (const_string "single") (const_string "double")))])
5599
5600 (define_insn "calli"
5601   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5602          (match_operand 1 "" ""))
5603    (use (reg:PSI FPSCR_REG))
5604    (clobber (reg:SI PR_REG))]
5605   "TARGET_SH1"
5606   "jsr  @%0%#"
5607   [(set_attr "type" "call")
5608    (set (attr "fp_mode")
5609         (if_then_else (eq_attr "fpu_single" "yes")
5610                       (const_string "single") (const_string "double")))
5611    (set_attr "needs_delay_slot" "yes")])
5612
5613 ;; This is a pc-rel call, using bsrf, for use with PIC.
5614
5615 (define_insn "calli_pcrel"
5616   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5617          (match_operand 1 "" ""))
5618    (use (reg:PSI FPSCR_REG))
5619    (use (reg:SI PIC_REG))
5620    (use (match_operand 2 "" ""))
5621    (clobber (reg:SI PR_REG))]
5622   "TARGET_SH2"
5623   "bsrf %0\\n%O2:%#"
5624   [(set_attr "type" "call")
5625    (set (attr "fp_mode")
5626         (if_then_else (eq_attr "fpu_single" "yes")
5627                       (const_string "single") (const_string "double")))
5628    (set_attr "needs_delay_slot" "yes")])
5629
5630 (define_insn_and_split "call_pcrel"
5631   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5632          (match_operand 1 "" ""))
5633    (use (reg:PSI FPSCR_REG))
5634    (use (reg:SI PIC_REG))
5635    (clobber (reg:SI PR_REG))
5636    (clobber (match_scratch:SI 2 "=r"))]
5637   "TARGET_SH2"
5638   "#"
5639   "reload_completed"
5640   [(const_int 0)]
5641   "
5642 {
5643   rtx lab = PATTERN (gen_call_site ());
5644
5645   if (SYMBOL_REF_FLAG (operands[0]))
5646     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5647   else
5648     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5649   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5650   DONE;
5651 }"
5652   [(set_attr "type" "call")
5653    (set (attr "fp_mode")
5654         (if_then_else (eq_attr "fpu_single" "yes")
5655                       (const_string "single") (const_string "double")))
5656    (set_attr "needs_delay_slot" "yes")])
5657
5658 (define_insn "call_compact"
5659   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5660          (match_operand 1 "" ""))
5661    (match_operand 2 "immediate_operand" "n")
5662    (use (reg:SI R0_REG))
5663    (use (reg:SI R1_REG))
5664    (use (reg:PSI FPSCR_REG))
5665    (clobber (reg:SI PR_REG))]
5666   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5667   "jsr  @%0%#"
5668   [(set_attr "type" "call")
5669    (set (attr "fp_mode")
5670         (if_then_else (eq_attr "fpu_single" "yes")
5671                       (const_string "single") (const_string "double")))
5672    (set_attr "needs_delay_slot" "yes")])
5673
5674 (define_insn "call_compact_rettramp"
5675   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5676          (match_operand 1 "" ""))
5677    (match_operand 2 "immediate_operand" "n")
5678    (use (reg:SI R0_REG))
5679    (use (reg:SI R1_REG))
5680    (use (reg:PSI FPSCR_REG))
5681    (clobber (reg:SI R10_REG))
5682    (clobber (reg:SI PR_REG))]
5683   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5684   "jsr  @%0%#"
5685   [(set_attr "type" "call")
5686    (set (attr "fp_mode")
5687         (if_then_else (eq_attr "fpu_single" "yes")
5688                       (const_string "single") (const_string "double")))
5689    (set_attr "needs_delay_slot" "yes")])
5690
5691 (define_insn "call_media"
5692   [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5693          (match_operand 1 "" ""))
5694    (clobber (reg:DI PR_MEDIA_REG))]
5695   "TARGET_SHMEDIA"
5696   "blink        %0, r18"
5697   [(set_attr "type" "jump_media")])
5698
5699 (define_insn "call_valuei"
5700   [(set (match_operand 0 "" "=rf")
5701         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5702               (match_operand 2 "" "")))
5703    (use (reg:PSI FPSCR_REG))
5704    (clobber (reg:SI PR_REG))]
5705   "TARGET_SH1"
5706   "jsr  @%1%#"
5707   [(set_attr "type" "call")
5708    (set (attr "fp_mode")
5709         (if_then_else (eq_attr "fpu_single" "yes")
5710                       (const_string "single") (const_string "double")))
5711    (set_attr "needs_delay_slot" "yes")])
5712
5713 (define_insn "call_valuei_pcrel"
5714   [(set (match_operand 0 "" "=rf")
5715         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5716               (match_operand 2 "" "")))
5717    (use (reg:PSI FPSCR_REG))
5718    (use (reg:SI PIC_REG))
5719    (use (match_operand 3 "" ""))
5720    (clobber (reg:SI PR_REG))]
5721   "TARGET_SH2"
5722   "bsrf %1\\n%O3:%#"
5723   [(set_attr "type" "call")
5724    (set (attr "fp_mode")
5725         (if_then_else (eq_attr "fpu_single" "yes")
5726                       (const_string "single") (const_string "double")))
5727    (set_attr "needs_delay_slot" "yes")])
5728
5729 (define_insn_and_split "call_value_pcrel"
5730   [(set (match_operand 0 "" "=rf")
5731         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5732               (match_operand 2 "" "")))
5733    (use (reg:PSI FPSCR_REG))
5734    (use (reg:SI PIC_REG))
5735    (clobber (reg:SI PR_REG))
5736    (clobber (match_scratch:SI 3 "=r"))]
5737   "TARGET_SH2"
5738   "#"
5739   "reload_completed"
5740   [(const_int 0)]
5741   "
5742 {
5743   rtx lab = PATTERN (gen_call_site ());
5744
5745   if (SYMBOL_REF_FLAG (operands[1]))
5746     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5747   else
5748     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5749   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5750                                          operands[2], lab));
5751   DONE;
5752 }"
5753   [(set_attr "type" "call")
5754    (set (attr "fp_mode")
5755         (if_then_else (eq_attr "fpu_single" "yes")
5756                       (const_string "single") (const_string "double")))
5757    (set_attr "needs_delay_slot" "yes")])
5758
5759 (define_insn "call_value_compact"
5760   [(set (match_operand 0 "" "=rf")
5761         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5762               (match_operand 2 "" "")))
5763    (match_operand 3 "immediate_operand" "n")
5764    (use (reg:SI R0_REG))
5765    (use (reg:SI R1_REG))
5766    (use (reg:PSI FPSCR_REG))
5767    (clobber (reg:SI PR_REG))]
5768   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5769   "jsr  @%1%#"
5770   [(set_attr "type" "call")
5771    (set (attr "fp_mode")
5772         (if_then_else (eq_attr "fpu_single" "yes")
5773                       (const_string "single") (const_string "double")))
5774    (set_attr "needs_delay_slot" "yes")])
5775
5776 (define_insn "call_value_compact_rettramp"
5777   [(set (match_operand 0 "" "=rf")
5778         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5779               (match_operand 2 "" "")))
5780    (match_operand 3 "immediate_operand" "n")
5781    (use (reg:SI R0_REG))
5782    (use (reg:SI R1_REG))
5783    (use (reg:PSI FPSCR_REG))
5784    (clobber (reg:SI R10_REG))
5785    (clobber (reg:SI PR_REG))]
5786   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5787   "jsr  @%1%#"
5788   [(set_attr "type" "call")
5789    (set (attr "fp_mode")
5790         (if_then_else (eq_attr "fpu_single" "yes")
5791                       (const_string "single") (const_string "double")))
5792    (set_attr "needs_delay_slot" "yes")])
5793
5794 (define_insn "call_value_media"
5795   [(set (match_operand 0 "" "=rf")
5796         (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5797               (match_operand 2 "" "")))
5798    (clobber (reg:DI PR_MEDIA_REG))]
5799   "TARGET_SHMEDIA"
5800   "blink        %1, r18"
5801   [(set_attr "type" "jump_media")])
5802
5803 (define_expand "call"
5804   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5805                             (match_operand 1 "" ""))
5806               (match_operand 2 "" "")
5807               (use (reg:PSI FPSCR_REG))
5808               (clobber (reg:SI PR_REG))])]
5809   ""
5810   "
5811 {
5812   if (TARGET_SHMEDIA)
5813     {
5814       operands[0] = XEXP (operands[0], 0);
5815       if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5816         {
5817           if (! SYMBOL_REF_FLAG (operands[0]))
5818             {
5819               rtx reg = gen_reg_rtx (Pmode);
5820
5821               emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5822               operands[0] = reg;
5823             }
5824           else
5825             {
5826               operands[0] = gen_sym2PIC (operands[0]);
5827               PUT_MODE (operands[0], Pmode);
5828             }
5829         }
5830       if (GET_MODE (operands[0]) == SImode)
5831         {
5832           if (GET_CODE (operands[0]) == REG)
5833             operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5834           else if (GET_CODE (operands[0]) == SUBREG)
5835             {
5836               operands[0] = SUBREG_REG (operands[0]);
5837               if (GET_MODE (operands[0]) != DImode)
5838                 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5839             }
5840           else
5841             {
5842               operands[0] = shallow_copy_rtx (operands[0]);
5843               PUT_MODE (operands[0], DImode);
5844             }
5845         }
5846       if (! target_reg_operand (operands[0], DImode))
5847         operands[0] = copy_to_mode_reg (DImode, operands[0]);
5848       emit_call_insn (gen_call_media (operands[0], operands[1]));
5849       DONE;
5850     }
5851   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5852     {
5853       rtx cookie_rtx = operands[2];
5854       long cookie = INTVAL (cookie_rtx);
5855       rtx func = XEXP (operands[0], 0);
5856       rtx r0, r1;
5857
5858       if (flag_pic)
5859         {
5860           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5861             {
5862               rtx reg = gen_reg_rtx (Pmode);
5863
5864               emit_insn (gen_symGOTPLT2reg (reg, func));
5865               func = reg;
5866             }
5867           else
5868             func = legitimize_pic_address (func, Pmode, 0);
5869         }
5870
5871       r0 = gen_rtx_REG (SImode, R0_REG);
5872       r1 = gen_rtx_REG (SImode, R1_REG);
5873
5874       /* Since such a call function may use all call-clobbered
5875          registers, we force a mode switch earlier, so that we don't
5876          run out of registers when adjusting fpscr for the call.  */
5877       emit_insn (gen_force_mode_for_call ());
5878
5879       operands[0] = gen_rtx_SYMBOL_REF (SImode,
5880                                         \"__GCC_shcompact_call_trampoline\");
5881       if (flag_pic)
5882         {
5883           rtx reg = gen_reg_rtx (Pmode);
5884
5885           emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5886           operands[0] = reg;
5887         }
5888       operands[0] = force_reg (SImode, operands[0]);
5889
5890       emit_move_insn (r0, func);
5891       emit_move_insn (r1, cookie_rtx);
5892
5893       if (cookie & CALL_COOKIE_RET_TRAMP (1))
5894         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5895                                                    operands[2]));
5896       else
5897         emit_call_insn (gen_call_compact (operands[0], operands[1],
5898                                           operands[2]));
5899
5900       DONE;
5901     }
5902   else if (TARGET_SHCOMPACT && flag_pic
5903            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5904            && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
5905     {
5906       rtx reg = gen_reg_rtx (Pmode);
5907
5908       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5909       XEXP (operands[0], 0) = reg;
5910     }
5911   if (flag_pic && TARGET_SH2
5912       && GET_CODE (operands[0]) == MEM
5913       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5914     {
5915       emit_call_insn (gen_call_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_calli (operands[0], operands[1]));
5922   DONE;
5923 }")
5924
5925 (define_insn "call_pop_compact"
5926   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5927          (match_operand 1 "" ""))
5928    (match_operand 2 "immediate_operand" "n")
5929    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5930                                  (match_operand 3 "immediate_operand" "n")))
5931    (use (reg:SI R0_REG))
5932    (use (reg:SI R1_REG))
5933    (use (reg:PSI FPSCR_REG))
5934    (clobber (reg:SI PR_REG))]
5935   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5936   "jsr  @%0%#"
5937   [(set_attr "type" "call")
5938    (set (attr "fp_mode")
5939         (if_then_else (eq_attr "fpu_single" "yes")
5940                       (const_string "single") (const_string "double")))
5941    (set_attr "needs_delay_slot" "yes")])
5942
5943 (define_insn "call_pop_compact_rettramp"
5944   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5945          (match_operand 1 "" ""))
5946    (match_operand 2 "immediate_operand" "n")
5947    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5948                                  (match_operand 3 "immediate_operand" "n")))
5949    (use (reg:SI R0_REG))
5950    (use (reg:SI R1_REG))
5951    (use (reg:PSI FPSCR_REG))
5952    (clobber (reg:SI R10_REG))
5953    (clobber (reg:SI PR_REG))]
5954   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5955   "jsr  @%0%#"
5956   [(set_attr "type" "call")
5957    (set (attr "fp_mode")
5958         (if_then_else (eq_attr "fpu_single" "yes")
5959                       (const_string "single") (const_string "double")))
5960    (set_attr "needs_delay_slot" "yes")])
5961
5962 (define_expand "call_pop"
5963   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5964                     (match_operand 1 "" ""))
5965              (match_operand 2 "" "")
5966              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5967                                            (match_operand 3 "" "")))])]
5968   "TARGET_SHCOMPACT"
5969   "
5970 {
5971   if (operands[2] && INTVAL (operands[2]))
5972     {
5973       rtx cookie_rtx = operands[2];
5974       long cookie = INTVAL (cookie_rtx);
5975       rtx func = XEXP (operands[0], 0);
5976       rtx r0, r1;
5977
5978       if (flag_pic)
5979         {
5980           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5981             {
5982               rtx reg = gen_reg_rtx (Pmode);
5983
5984               emit_insn (gen_symGOTPLT2reg (reg, func));
5985               func = reg;
5986             }
5987           else
5988             func = legitimize_pic_address (func, Pmode, 0);
5989         }
5990
5991       r0 = gen_rtx_REG (SImode, R0_REG);
5992       r1 = gen_rtx_REG (SImode, R1_REG);
5993
5994       /* Since such a call function may use all call-clobbered
5995          registers, we force a mode switch earlier, so that we don't
5996          run out of registers when adjusting fpscr for the call.  */
5997       emit_insn (gen_force_mode_for_call ());
5998
5999       operands[0] = gen_rtx_SYMBOL_REF (SImode,
6000                                         \"__GCC_shcompact_call_trampoline\");
6001       if (flag_pic)
6002         {
6003           rtx reg = gen_reg_rtx (Pmode);
6004
6005           emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
6006           operands[0] = reg;
6007         }
6008       operands[0] = force_reg (SImode, operands[0]);
6009
6010       emit_move_insn (r0, func);
6011       emit_move_insn (r1, cookie_rtx);
6012
6013       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6014         emit_call_insn (gen_call_pop_compact_rettramp
6015                         (operands[0], operands[1], operands[2], operands[3]));
6016       else
6017         emit_call_insn (gen_call_pop_compact
6018                         (operands[0], operands[1], operands[2], operands[3]));
6019
6020       DONE;
6021     }
6022
6023   abort ();
6024 }")
6025
6026 (define_expand "call_value"
6027   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6028                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6029                                  (match_operand 2 "" "")))
6030               (match_operand 3 "" "")
6031               (use (reg:PSI FPSCR_REG))
6032               (clobber (reg:SI PR_REG))])]
6033   ""
6034   "
6035 {
6036   if (TARGET_SHMEDIA)
6037     {
6038       operands[1] = XEXP (operands[1], 0);
6039       if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
6040         {
6041           if (! SYMBOL_REF_FLAG (operands[1]))
6042             {
6043               rtx reg = gen_reg_rtx (Pmode);
6044
6045               emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6046               operands[1] = reg;
6047             }
6048           else
6049             {
6050               operands[1] = gen_sym2PIC (operands[1]);
6051               PUT_MODE (operands[1], Pmode);
6052             }
6053         }
6054       if (GET_MODE (operands[1]) == SImode)
6055         {
6056           if (GET_CODE (operands[1]) == REG)
6057             operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6058           else if (GET_CODE (operands[1]) == SUBREG)
6059             {
6060               operands[1] = SUBREG_REG (operands[1]);
6061               if (GET_MODE (operands[1]) != DImode)
6062                 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6063             }
6064           else
6065             {
6066               operands[1] = shallow_copy_rtx (operands[1]);
6067               PUT_MODE (operands[1], DImode);
6068             }
6069         }
6070       if (! target_reg_operand (operands[1], DImode))
6071         operands[1] = copy_to_mode_reg (DImode, operands[1]);
6072       emit_call_insn (gen_call_value_media (operands[0], operands[1],
6073                                             operands[2]));
6074       DONE;
6075     }
6076   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6077     {
6078       rtx cookie_rtx = operands[3];
6079       long cookie = INTVAL (cookie_rtx);
6080       rtx func = XEXP (operands[1], 0);
6081       rtx r0, r1;
6082
6083       if (flag_pic)
6084         {
6085           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
6086             {
6087               rtx reg = gen_reg_rtx (Pmode);
6088
6089               emit_insn (gen_symGOTPLT2reg (reg, func));
6090               func = reg;
6091             }
6092           else
6093             func = legitimize_pic_address (func, Pmode, 0);
6094         }
6095
6096       r0 = gen_rtx_REG (SImode, R0_REG);
6097       r1 = gen_rtx_REG (SImode, R1_REG);
6098
6099       /* Since such a call function may use all call-clobbered
6100          registers, we force a mode switch earlier, so that we don't
6101          run out of registers when adjusting fpscr for the call.  */
6102       emit_insn (gen_force_mode_for_call ());
6103
6104       operands[1] = gen_rtx_SYMBOL_REF (SImode,
6105                                         \"__GCC_shcompact_call_trampoline\");
6106       if (flag_pic)
6107         {
6108           rtx reg = gen_reg_rtx (Pmode);
6109
6110           emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6111           operands[1] = reg;
6112         }
6113       operands[1] = force_reg (SImode, operands[1]);
6114
6115       emit_move_insn (r0, func);
6116       emit_move_insn (r1, cookie_rtx);
6117
6118       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6119         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
6120                                                          operands[1],
6121                                                          operands[2],
6122                                                          operands[3]));
6123       else
6124         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
6125                                                 operands[2], operands[3]));
6126
6127       DONE;
6128     }
6129   else if (TARGET_SHCOMPACT && flag_pic
6130            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6131            && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
6132     {
6133       rtx reg = gen_reg_rtx (Pmode);
6134
6135       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6136       XEXP (operands[1], 0) = reg;
6137     }
6138   if (flag_pic && TARGET_SH2
6139       && GET_CODE (operands[1]) == MEM
6140       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6141     {
6142       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6143                                             operands[2]));
6144       DONE;
6145     }
6146   else
6147     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
6148
6149   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6150   DONE;
6151 }")
6152
6153 (define_insn "sibcalli"
6154   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
6155          (match_operand 1 "" ""))
6156    (use (reg:PSI FPSCR_REG))
6157    (return)]
6158   "TARGET_SH1"
6159   "jmp  @%0%#"
6160   [(set_attr "needs_delay_slot" "yes")
6161    (set (attr "fp_mode")
6162         (if_then_else (eq_attr "fpu_single" "yes")
6163                       (const_string "single") (const_string "double")))
6164    (set_attr "type" "jump_ind")])
6165
6166 (define_insn "sibcalli_pcrel"
6167   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
6168          (match_operand 1 "" ""))
6169    (use (match_operand 2 "" ""))
6170    (use (reg:PSI FPSCR_REG))
6171    (return)]
6172   "TARGET_SH2"
6173   "braf %0\\n%O2:%#"
6174   [(set_attr "needs_delay_slot" "yes")
6175    (set (attr "fp_mode")
6176         (if_then_else (eq_attr "fpu_single" "yes")
6177                       (const_string "single") (const_string "double")))
6178    (set_attr "type" "jump_ind")])
6179
6180 (define_insn_and_split "sibcall_pcrel"
6181   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6182          (match_operand 1 "" ""))
6183    (use (reg:PSI FPSCR_REG))
6184    (clobber (match_scratch:SI 2 "=k"))
6185    (return)]
6186   "TARGET_SH2"
6187   "#"
6188   "reload_completed"
6189   [(const_int 0)]
6190   "
6191 {
6192   rtx lab = PATTERN (gen_call_site ());
6193   rtx call_insn;
6194
6195   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6196   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6197                                                   lab));
6198   SIBLING_CALL_P (call_insn) = 1;
6199   DONE;
6200 }"
6201   [(set_attr "needs_delay_slot" "yes")
6202    (set (attr "fp_mode")
6203         (if_then_else (eq_attr "fpu_single" "yes")
6204                       (const_string "single") (const_string "double")))
6205    (set_attr "type" "jump_ind")])
6206
6207 (define_insn "sibcall_compact"
6208   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6209          (match_operand 1 "" ""))
6210    (return)
6211    (use (match_operand:SI 2 "register_operand" "z,x"))
6212    (use (reg:SI R1_REG))
6213    (use (reg:PSI FPSCR_REG))
6214    ;; We want to make sure the `x' above will only match MACH_REG
6215    ;; because sibcall_epilogue may clobber MACL_REG.
6216    (clobber (reg:SI MACL_REG))]
6217   "TARGET_SHCOMPACT"
6218   "@
6219         jmp     @%0%#
6220         jmp     @%0\\n  sts     %2, r0"
6221   [(set_attr "needs_delay_slot" "yes,no")
6222    (set_attr "length" "2,4")
6223    (set (attr "fp_mode") (const_string "single"))
6224    (set_attr "type" "jump_ind")])
6225
6226 (define_insn "sibcall_media"
6227   [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6228          (match_operand 1 "" ""))
6229    (return)]
6230   "TARGET_SHMEDIA"
6231   "blink        %0, r63"
6232   [(set_attr "type" "jump_media")])
6233
6234 (define_expand "sibcall"
6235   [(parallel
6236     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6237            (match_operand 1 "" ""))
6238      (match_operand 2 "" "")
6239      (use (reg:PSI FPSCR_REG))
6240      (return)])]
6241   ""
6242   "
6243 {
6244   if (TARGET_SHMEDIA)
6245     {
6246       operands[0] = XEXP (operands[0], 0);
6247       if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6248         {
6249           if (! SYMBOL_REF_FLAG (operands[0]))
6250             {
6251               rtx reg = gen_reg_rtx (Pmode);
6252
6253               /* We must not use GOTPLT for sibcalls, because PIC_REG
6254                  must be restored before the PLT code gets to run.  */
6255               emit_insn (gen_symGOT2reg (reg, operands[0]));
6256               operands[0] = reg;
6257             }
6258           else
6259             {
6260               operands[0] = gen_sym2PIC (operands[0]);
6261               PUT_MODE (operands[0], Pmode);
6262             }
6263         }
6264       if (GET_MODE (operands[0]) == SImode)
6265         {
6266           if (GET_CODE (operands[0]) == REG)
6267             operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6268           else if (GET_CODE (operands[0]) == SUBREG)
6269             {
6270               operands[0] = SUBREG_REG (operands[0]);
6271               if (GET_MODE (operands[0]) != DImode)
6272                 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6273             }
6274           else
6275             {
6276               operands[0] = shallow_copy_rtx (operands[0]);
6277               PUT_MODE (operands[0], DImode);
6278             }
6279         }
6280       if (! target_reg_operand (operands[0], DImode))
6281         operands[0] = copy_to_mode_reg (DImode, operands[0]);
6282       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6283       DONE;
6284     }
6285   else if (TARGET_SHCOMPACT && operands[2]
6286            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6287     {
6288       rtx cookie_rtx = operands[2];
6289       long cookie = INTVAL (cookie_rtx);
6290       rtx func = XEXP (operands[0], 0);
6291       rtx mach, r1;
6292
6293       if (flag_pic)
6294         {
6295           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
6296             {
6297               rtx reg = gen_reg_rtx (Pmode);
6298
6299               emit_insn (gen_symGOT2reg (reg, func));
6300               func = reg;
6301             }
6302           else
6303             func = legitimize_pic_address (func, Pmode, 0);
6304         }
6305
6306       /* FIXME: if we could tell whether all argument registers are
6307          already taken, we could decide whether to force the use of
6308          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
6309          simple way to tell.  We could use the CALL_COOKIE, but we
6310          can't currently tell a register used for regular argument
6311          passing from one that is unused.  If we leave it up to reload
6312          to decide which register to use, it seems to always choose
6313          R0_REG, which leaves no available registers in SIBCALL_REGS
6314          to hold the address of the trampoline.  */
6315       mach = gen_rtx_REG (SImode, MACH_REG);
6316       r1 = gen_rtx_REG (SImode, R1_REG);
6317
6318       /* Since such a call function may use all call-clobbered
6319          registers, we force a mode switch earlier, so that we don't
6320          run out of registers when adjusting fpscr for the call.  */
6321       emit_insn (gen_force_mode_for_call ());
6322
6323       operands[0] = gen_rtx_SYMBOL_REF (SImode,
6324                                         \"__GCC_shcompact_call_trampoline\");
6325       if (flag_pic)
6326         {
6327           rtx reg = gen_reg_rtx (Pmode);
6328
6329           emit_insn (gen_symGOT2reg (reg, operands[0]));
6330           operands[0] = reg;
6331         }
6332       operands[0] = force_reg (SImode, operands[0]);
6333
6334       /* We don't need a return trampoline, since the callee will
6335          return directly to the upper caller.  */
6336       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6337         {
6338           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6339           cookie_rtx = GEN_INT (cookie);
6340         }
6341
6342       emit_move_insn (mach, func);
6343       emit_move_insn (r1, cookie_rtx);
6344
6345       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6346       DONE;
6347     }
6348   else if (TARGET_SHCOMPACT && flag_pic
6349            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6350            && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
6351     {
6352       rtx reg = gen_reg_rtx (Pmode);
6353
6354       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6355       XEXP (operands[0], 0) = reg;
6356     }
6357   if (flag_pic && TARGET_SH2
6358       && GET_CODE (operands[0]) == MEM
6359       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6360       /* The PLT needs the PIC register, but the epilogue would have
6361          to restore it, so we can only use PC-relative PIC calls for
6362          static functions.  */
6363       && SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
6364     {
6365       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6366       DONE;
6367     }
6368   else
6369     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
6370
6371   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6372   DONE;
6373 }")
6374
6375 (define_expand "sibcall_value"
6376   [(set (match_operand 0 "" "")
6377         (call (match_operand 1 "" "")
6378               (match_operand 2 "" "")))
6379    (match_operand 3 "" "")]
6380   ""
6381   "
6382 {
6383   emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
6384   DONE;
6385 }")
6386
6387 (define_insn "call_value_pop_compact"
6388   [(set (match_operand 0 "" "=rf")
6389         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6390               (match_operand 2 "" "")))
6391    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6392                                  (match_operand 4 "immediate_operand" "n")))
6393    (match_operand 3 "immediate_operand" "n")
6394    (use (reg:SI R0_REG))
6395    (use (reg:SI R1_REG))
6396    (use (reg:PSI FPSCR_REG))
6397    (clobber (reg:SI PR_REG))]
6398   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6399   "jsr  @%1%#"
6400   [(set_attr "type" "call")
6401    (set (attr "fp_mode")
6402         (if_then_else (eq_attr "fpu_single" "yes")
6403                       (const_string "single") (const_string "double")))
6404    (set_attr "needs_delay_slot" "yes")])
6405
6406 (define_insn "call_value_pop_compact_rettramp"
6407   [(set (match_operand 0 "" "=rf")
6408         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6409               (match_operand 2 "" "")))
6410    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6411                                  (match_operand 4 "immediate_operand" "n")))
6412    (match_operand 3 "immediate_operand" "n")
6413    (use (reg:SI R0_REG))
6414    (use (reg:SI R1_REG))
6415    (use (reg:PSI FPSCR_REG))
6416    (clobber (reg:SI R10_REG))
6417    (clobber (reg:SI PR_REG))]
6418   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6419   "jsr  @%1%#"
6420   [(set_attr "type" "call")
6421    (set (attr "fp_mode")
6422         (if_then_else (eq_attr "fpu_single" "yes")
6423                       (const_string "single") (const_string "double")))
6424    (set_attr "needs_delay_slot" "yes")])
6425
6426 (define_expand "call_value_pop"
6427   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6428                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6429                                  (match_operand 2 "" "")))
6430               (match_operand 3 "" "")
6431               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6432                                             (match_operand 4 "" "")))])]
6433   "TARGET_SHCOMPACT"
6434   "
6435 {
6436   if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6437     {
6438       rtx cookie_rtx = operands[3];
6439       long cookie = INTVAL (cookie_rtx);
6440       rtx func = XEXP (operands[1], 0);
6441       rtx r0, r1;
6442
6443       if (flag_pic)
6444         {
6445           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
6446             {
6447               rtx reg = gen_reg_rtx (Pmode);
6448
6449               emit_insn (gen_symGOTPLT2reg (reg, func));
6450               func = reg;
6451             }
6452           else
6453             func = legitimize_pic_address (func, Pmode, 0);
6454         }
6455
6456       r0 = gen_rtx_REG (SImode, R0_REG);
6457       r1 = gen_rtx_REG (SImode, R1_REG);
6458
6459       /* Since such a call function may use all call-clobbered
6460          registers, we force a mode switch earlier, so that we don't
6461          run out of registers when adjusting fpscr for the call.  */
6462       emit_insn (gen_force_mode_for_call ());
6463
6464       operands[1] = gen_rtx_SYMBOL_REF (SImode,
6465                                         \"__GCC_shcompact_call_trampoline\");
6466       if (flag_pic)
6467         {
6468           rtx reg = gen_reg_rtx (Pmode);
6469
6470           emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6471           operands[1] = reg;
6472         }
6473       operands[1] = force_reg (SImode, operands[1]);
6474
6475       emit_move_insn (r0, func);
6476       emit_move_insn (r1, cookie_rtx);
6477
6478       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6479         emit_call_insn (gen_call_value_pop_compact_rettramp
6480                         (operands[0], operands[1], operands[2],
6481                          operands[3], operands[4]));
6482       else
6483         emit_call_insn (gen_call_value_pop_compact
6484                         (operands[0], operands[1], operands[2],
6485                          operands[3], operands[4]));
6486
6487       DONE;
6488     }
6489
6490   abort ();
6491 }")
6492
6493 (define_expand "sibcall_epilogue"
6494   [(return)]
6495   ""
6496   "
6497 {
6498   sh_expand_epilogue ();
6499   if (TARGET_SHCOMPACT)
6500     {
6501       rtx insn, set;
6502
6503       /* If epilogue clobbers r0, preserve it in macl.  */
6504       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6505         if ((set = single_set (insn))
6506             && GET_CODE (SET_DEST (set)) == REG
6507             && REGNO (SET_DEST (set)) == R0_REG)
6508           {
6509             rtx r0 = gen_rtx_REG (SImode, R0_REG);
6510             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6511             rtx i;
6512
6513             /* We can't tell at this point whether the sibcall is a
6514                sibcall_compact and, if it is, whether it uses r0 or
6515                mach as operand 2, so let the instructions that
6516                preserve r0 be optimized away if r0 turns out to be
6517                dead.  */
6518             i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6519             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6520                                                REG_NOTES (i));
6521             i = emit_move_insn (r0, tmp);
6522             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6523                                                REG_NOTES (i));
6524             break;
6525           }
6526     }
6527   DONE;
6528 }")
6529
6530 (define_insn "indirect_jump_compact"
6531   [(set (pc)
6532         (match_operand:SI 0 "arith_reg_operand" "r"))]
6533   "TARGET_SH1"
6534   "jmp  @%0%#"
6535   [(set_attr "needs_delay_slot" "yes")
6536    (set_attr "type" "jump_ind")])
6537
6538 (define_expand "indirect_jump"
6539   [(set (pc)
6540         (match_operand 0 "register_operand" ""))]
6541   ""
6542   "
6543 {
6544   if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6545     operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6546 }")
6547
6548 ;; The use of operand 1 / 2 helps us distinguish case table jumps
6549 ;; which can be present in structured code from indirect jumps which can not
6550 ;; be present in structured code.  This allows -fprofile-arcs to work.
6551
6552 ;; For SH1 processors.
6553 (define_insn "casesi_jump_1"
6554   [(set (pc)
6555         (match_operand:SI 0 "register_operand" "r"))
6556    (use (label_ref (match_operand 1 "" "")))]
6557   "TARGET_SH1"
6558   "jmp  @%0%#"
6559   [(set_attr "needs_delay_slot" "yes")
6560    (set_attr "type" "jump_ind")])
6561
6562 ;; For all later processors.
6563 (define_insn "casesi_jump_2"
6564   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
6565                       (label_ref (match_operand 1 "" ""))))
6566    (use (label_ref (match_operand 2 "" "")))]
6567   "TARGET_SH2
6568    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
6569   "braf %0%#"
6570   [(set_attr "needs_delay_slot" "yes")
6571    (set_attr "type" "jump_ind")])
6572
6573 (define_insn "casesi_jump_media"
6574   [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6575    (use (label_ref (match_operand 1 "" "")))]
6576   "TARGET_SHMEDIA"
6577   "blink        %0, r63"
6578   [(set_attr "type" "jump_media")])
6579
6580 ;; Call subroutine returning any type.
6581 ;; ??? This probably doesn't work.
6582
6583 (define_expand "untyped_call"
6584   [(parallel [(call (match_operand 0 "" "")
6585                     (const_int 0))
6586               (match_operand 1 "" "")
6587               (match_operand 2 "" "")])]
6588   "TARGET_SH3E || TARGET_SHMEDIA"
6589   "
6590 {
6591   int i;
6592
6593   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
6594
6595   for (i = 0; i < XVECLEN (operands[2], 0); i++)
6596     {
6597       rtx set = XVECEXP (operands[2], 0, i);
6598       emit_move_insn (SET_DEST (set), SET_SRC (set));
6599     }
6600
6601   /* The optimizer does not know that the call sets the function value
6602      registers we stored in the result block.  We avoid problems by
6603      claiming that all hard registers are used and clobbered at this
6604      point.  */
6605   emit_insn (gen_blockage ());
6606
6607   DONE;
6608 }")
6609 \f
6610 ;; ------------------------------------------------------------------------
6611 ;; Misc insns
6612 ;; ------------------------------------------------------------------------
6613
6614 (define_insn "dect"
6615   [(set (reg:SI T_REG)
6616         (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6617    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
6618   "TARGET_SH2"
6619   "dt   %0"
6620   [(set_attr "type" "arith")])
6621
6622 (define_insn "nop"
6623   [(const_int 0)]
6624   ""
6625   "nop")
6626
6627 ;; Load address of a label. This is only generated by the casesi expand,
6628 ;; and by machine_dependent_reorg (fixing up fp moves).
6629 ;; This must use unspec, because this only works for labels that are
6630 ;; within range,
6631
6632 (define_insn "mova"
6633   [(set (reg:SI R0_REG)
6634         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
6635   "TARGET_SH1"
6636   "mova %O0,r0"
6637   [(set_attr "in_delay_slot" "no")
6638    (set_attr "type" "arith")])
6639
6640 ;; machine_dependent_reorg() will make this a `mova'.
6641 (define_insn "mova_const"
6642   [(set (reg:SI R0_REG)
6643         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
6644   "TARGET_SH1"
6645   "#"
6646   [(set_attr "in_delay_slot" "no")
6647    (set_attr "type" "arith")])
6648
6649 (define_expand "GOTaddr2picreg"
6650   [(set (reg:SI R0_REG)
6651         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6652                    UNSPEC_MOVA))
6653    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
6654    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6655   "" "
6656 {
6657   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
6658   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
6659
6660   if (TARGET_SH5)
6661     operands[1] = gen_datalabel_ref (operands[1]);
6662
6663   if (TARGET_SHMEDIA)
6664     {
6665       rtx tr = gen_rtx_REG (DImode, TR0_REG);
6666       rtx dipic = operands[0];
6667       rtx lab = PATTERN (gen_call_site ());
6668       rtx insn, equiv;
6669
6670       equiv = operands[1];
6671       operands[1] = gen_rtx_MINUS (DImode,
6672                                    operands[1],
6673                                    gen_rtx_CONST
6674                                    (DImode,
6675                                     gen_rtx_MINUS (DImode,
6676                                                    gen_rtx_CONST (DImode,
6677                                                                   lab),
6678                                                    pc_rtx)));
6679       operands[1] = gen_sym2PIC (operands[1]);
6680       PUT_MODE (operands[1], DImode);
6681
6682       if (GET_MODE (dipic) != DImode)
6683         dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6684
6685       if (TARGET_SHMEDIA64)
6686         emit_insn (gen_movdi_const (dipic, operands[1]));
6687       else
6688         emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6689
6690       emit_insn (gen_ptrel (tr, dipic, lab));
6691
6692       if (GET_MODE (operands[0]) != GET_MODE (tr))
6693         tr = gen_rtx_SUBREG (GET_MODE (operands[0]), tr, 0);
6694
6695       insn = emit_move_insn (operands[0], tr);
6696
6697       REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6698                                             REG_NOTES (insn));
6699
6700       DONE;
6701     }
6702 }
6703 ")
6704
6705 ;; When generating PIC, we must match label_refs especially, because
6706 ;; they do not satisfy LEGITIMATE_PIC_OPERAND_P(), and we don't want
6707 ;; them to do, because they can't be loaded directly into
6708 ;; non-branch-target registers.
6709 (define_insn "*pt"
6710   [(set (match_operand:DI 0 "target_reg_operand" "=b")
6711         (match_operand:DI 1 "" "T"))]
6712   "TARGET_SHMEDIA && flag_pic
6713    && EXTRA_CONSTRAINT_T (operands[1])"
6714   "pt   %1, %0"
6715   [(set_attr "type" "pt_media")
6716    (set_attr "length" "*")])
6717
6718 (define_insn "*ptb"
6719   [(set (match_operand:DI 0 "target_reg_operand" "=b")
6720         (const:DI (unspec:DI [(match_operand:DI 1 "" "T")]
6721                              UNSPEC_DATALABEL)))]
6722   "TARGET_SHMEDIA && flag_pic
6723    && EXTRA_CONSTRAINT_T (operands[1])"
6724   "ptb/u        datalabel %1, %0"
6725   [(set_attr "type" "pt_media")
6726    (set_attr "length" "*")])
6727
6728 (define_insn "ptrel"
6729   [(set (match_operand:DI 0 "target_reg_operand" "=b")
6730         (plus:DI (match_operand:DI 1 "register_operand" "r")
6731               (pc)))
6732    (match_operand:DI 2 "" "")]
6733   "TARGET_SHMEDIA"
6734   "%O2: ptrel/u %1, %0"
6735   [(set_attr "type" "ptabs_media")])
6736
6737 (define_expand "builtin_setjmp_receiver"
6738   [(match_operand 0 "" "")]
6739   "flag_pic"
6740   "
6741 {
6742   emit_insn (gen_GOTaddr2picreg ());
6743   DONE;
6744 }")
6745
6746 (define_expand "call_site"
6747   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
6748   "TARGET_SH1"
6749   "
6750 {
6751   static HOST_WIDE_INT i = 0;
6752   operands[0] = GEN_INT (i);
6753   i++;
6754 }")
6755
6756 (define_expand "sym_label2reg"
6757   [(set (match_operand:SI 0 "" "")
6758         (const:SI (minus:SI
6759                    (const:SI
6760                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6761                    (const:SI
6762                     (plus:SI
6763                      (match_operand:SI 2 "" "")
6764                      (const_int 2))))))]
6765   "TARGET_SH1" "")
6766
6767 (define_expand "symGOT_load"
6768   [(set (match_dup 2) (match_operand 1 "" ""))
6769    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6770    (set (match_operand 0 "" "") (mem (match_dup 3)))]
6771   ""
6772   "
6773 {
6774   rtx insn;
6775
6776   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6777   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6778
6779   if (TARGET_SHMEDIA)
6780     {
6781       rtx reg = operands[2];
6782
6783       if (GET_MODE (reg) != DImode)
6784         reg = gen_rtx_SUBREG (DImode, reg, 0);
6785
6786       if (flag_pic > 1)
6787         emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6788       else
6789         emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6790     }
6791   else
6792     emit_move_insn (operands[2], operands[1]);
6793
6794   emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6795                                              operands[2],
6796                                              gen_rtx_REG (Pmode, PIC_REG)));
6797
6798   insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6799
6800   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6801                                                                   0), 0, 0),
6802                                         REG_NOTES (insn));
6803
6804   DONE;
6805 }")
6806
6807 (define_expand "sym2GOT"
6808   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6809   ""
6810   "")
6811
6812 (define_expand "symGOT2reg"
6813   [(match_operand 0 "" "") (match_operand 1 "" "")]
6814   ""
6815   "
6816 {
6817   rtx gotsym, insn;
6818
6819   gotsym = gen_sym2GOT (operands[1]);
6820   PUT_MODE (gotsym, Pmode);
6821   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6822
6823   RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
6824
6825   DONE;
6826 }")
6827
6828 (define_expand "sym2GOTPLT"
6829   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6830   ""
6831   "")
6832
6833 (define_expand "symGOTPLT2reg"
6834   [(match_operand 0 "" "") (match_operand 1 "" "")]
6835   ""
6836   "
6837 {
6838   emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6839   DONE;
6840 }")
6841
6842 (define_expand "sym2GOTOFF"
6843   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6844   ""
6845   "")
6846
6847 (define_expand "symGOTOFF2reg"
6848   [(match_operand 0 "" "") (match_operand 1 "" "")]
6849   ""
6850   "
6851 {
6852   rtx gotoffsym, insn;
6853   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6854
6855   gotoffsym = gen_sym2GOTOFF (operands[1]);
6856   PUT_MODE (gotoffsym, Pmode);
6857   emit_move_insn (t, gotoffsym);
6858   insn = emit_move_insn (operands[0],
6859                          gen_rtx_PLUS (Pmode, t,
6860                                        gen_rtx_REG (Pmode, PIC_REG)));
6861
6862   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6863                                         REG_NOTES (insn));
6864
6865   DONE;
6866 }")
6867
6868 (define_expand "symPLT_label2reg"
6869   [(set (match_operand:SI 0 "" "")
6870         (const:SI (minus:SI
6871                    (const:SI
6872                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6873                    (const:SI
6874                     (minus:SI
6875                      (const:SI (plus:SI
6876                                 (match_operand:SI 2 "" "")
6877                                 (const_int 2)))
6878                      (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6879    ;; Even though the PIC register is not really used by the call
6880    ;; sequence in which this is expanded, the PLT code assumes the PIC
6881    ;; register is set, so we must not skip its initialization.  Since
6882    ;; we only use this expand as part of calling sequences, and never
6883    ;; to take the address of a function, this is the best point to
6884    ;; insert the (use).  Using the PLT to take the address of a
6885    ;; function would be wrong, not only because the PLT entry could
6886    ;; then be called from a function that doesn't initialize the PIC
6887    ;; register to the proper GOT, but also because pointers to the
6888    ;; same function might not compare equal, should they be set by
6889    ;; different shared libraries.
6890    (use (reg:SI PIC_REG))]
6891   "TARGET_SH1"
6892   "")
6893
6894 (define_expand "sym2PIC"
6895   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6896   ""
6897   "")
6898
6899 ;; case instruction for switch statements.
6900
6901 ;; Operand 0 is index
6902 ;; operand 1 is the minimum bound
6903 ;; operand 2 is the maximum bound - minimum bound + 1
6904 ;; operand 3 is CODE_LABEL for the table;
6905 ;; operand 4 is the CODE_LABEL to go to if index out of range.
6906
6907 (define_expand "casesi"
6908   [(match_operand:SI 0 "arith_reg_operand" "")
6909    (match_operand:SI 1 "arith_reg_operand" "")
6910    (match_operand:SI 2 "arith_reg_operand" "")
6911    (match_operand 3 "" "") (match_operand 4 "" "")]
6912   ""
6913   "
6914 {
6915   rtx reg = gen_reg_rtx (SImode);
6916   rtx reg2 = gen_reg_rtx (SImode);
6917   if (TARGET_SHMEDIA)
6918     {
6919       rtx reg = gen_reg_rtx (DImode);
6920       rtx reg2 = gen_reg_rtx (DImode);
6921       rtx reg3 = gen_reg_rtx (DImode);
6922       rtx reg4 = gen_reg_rtx (DImode);
6923       rtx reg5 = gen_reg_rtx (DImode);
6924
6925       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
6926       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
6927       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
6928
6929       emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
6930       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
6931       emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
6932       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
6933       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
6934                                                (DImode, operands[3])));
6935       emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
6936       emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
6937       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
6938       emit_barrier ();
6939       DONE;
6940     }
6941   operands[1] = copy_to_mode_reg (SImode, operands[1]);
6942   operands[2] = copy_to_mode_reg (SImode, operands[2]);
6943   /* If optimizing, casesi_worker depends on the mode of the instruction
6944      before label it 'uses' - operands[3].  */
6945   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
6946                            reg));
6947   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
6948   if (TARGET_SH2)
6949     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
6950   else
6951     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
6952   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
6953      operands[3], but to lab.  We will fix this up in
6954      machine_dependent_reorg.  */
6955   emit_barrier ();
6956   DONE;
6957 }")
6958
6959 (define_expand "casesi_0"
6960   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
6961    (set (match_dup 4) (minus:SI (match_dup 4)
6962                                 (match_operand:SI 1 "arith_operand" "")))
6963    (set (reg:SI T_REG)
6964         (gtu:SI (match_dup 4)
6965                 (match_operand:SI 2 "arith_reg_operand" "")))
6966    (set (pc)
6967         (if_then_else (ne (reg:SI T_REG)
6968                           (const_int 0))
6969                       (label_ref (match_operand 3 "" ""))
6970                       (pc)))]
6971   "TARGET_SH1"
6972   "")
6973
6974 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
6975 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
6976 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
6977
6978 (define_insn "casesi_worker_0"
6979   [(set (match_operand:SI 0 "register_operand" "=r,r")
6980         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
6981                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6982    (clobber (match_scratch:SI 3 "=X,1"))
6983    (clobber (match_scratch:SI 4 "=&z,z"))]
6984   "TARGET_SH1"
6985   "#")
6986
6987 (define_split
6988   [(set (match_operand:SI 0 "register_operand" "")
6989         (unspec:SI [(match_operand:SI 1 "register_operand" "")
6990                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6991    (clobber (match_scratch:SI 3 ""))
6992    (clobber (match_scratch:SI 4 ""))]
6993   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
6994   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
6995    (parallel [(set (match_dup 0)
6996               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
6997                           (label_ref (match_dup 2))] UNSPEC_CASESI))
6998               (clobber (match_dup 3))])
6999    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
7000   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7001
7002 (define_split
7003   [(set (match_operand:SI 0 "register_operand" "")
7004         (unspec:SI [(match_operand:SI 1 "register_operand" "")
7005                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7006    (clobber (match_scratch:SI 3 ""))
7007    (clobber (match_scratch:SI 4 ""))]
7008   "TARGET_SH2 && reload_completed"
7009   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7010    (parallel [(set (match_dup 0)
7011               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7012                           (label_ref (match_dup 2))] UNSPEC_CASESI))
7013               (clobber (match_dup 3))])]
7014   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7015
7016 (define_insn "*casesi_worker"
7017   [(set (match_operand:SI 0 "register_operand" "=r,r")
7018         (unspec:SI [(reg:SI R0_REG)
7019                     (match_operand:SI 1 "register_operand" "0,r")
7020                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7021    (clobber (match_scratch:SI 3 "=X,1"))]
7022   "TARGET_SH1"
7023   "*
7024 {
7025   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7026
7027   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7028     abort ();
7029
7030   switch (GET_MODE (diff_vec))
7031     {
7032     case SImode:
7033       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
7034     case HImode:
7035       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
7036     case QImode:
7037       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7038         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
7039       return \"mov.b    @(r0,%1),%0\";
7040     default:
7041       abort ();
7042     }
7043 }"
7044   [(set_attr "length" "4")])
7045
7046 (define_insn "casesi_shift_media"
7047   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7048         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
7049                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
7050                     UNSPEC_CASESI)))]
7051   "TARGET_SHMEDIA"
7052   "*
7053 {
7054   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7055
7056   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7057     abort ();
7058
7059   switch (GET_MODE (diff_vec))
7060     {
7061     case SImode:
7062       return \"shlli    %1, 2, %0\";
7063     case HImode:
7064       return \"shlli    %1, 1, %0\";
7065     case QImode:
7066       if (rtx_equal_p (operands[0], operands[1]))
7067         return \"\";
7068       return \"add      %1, r63, %0\";
7069     default:
7070       abort ();
7071     }
7072 }"
7073   [(set_attr "type" "arith_media")])
7074
7075 (define_insn "casesi_load_media"
7076   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7077         (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
7078                          (match_operand 2 "arith_reg_operand" "r")
7079                          (label_ref:DI (match_operand 3 "" ""))] 2)))]
7080   "TARGET_SHMEDIA"
7081   "*
7082 {
7083   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
7084
7085   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7086     abort ();
7087
7088   switch (GET_MODE (diff_vec))
7089     {
7090     case SImode:
7091       return \"ldx.l    %1, %2, %0\";
7092     case HImode:
7093 #if 0
7094       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7095         return \"ldx.uw %1, %2, %0\";
7096 #endif
7097       return \"ldx.w    %1, %2, %0\";
7098     case QImode:
7099       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7100         return \"ldx.ub %1, %2, %0\";
7101       return \"ldx.b    %1, %2, %0\";
7102     default:
7103       abort ();
7104     }
7105 }"
7106   [(set_attr "type" "load_media")])
7107
7108 (define_expand "return"
7109   [(return)]
7110   "reload_completed && ! sh_need_epilogue ()"
7111   "
7112 {
7113   if (TARGET_SHMEDIA)
7114     {
7115       emit_jump_insn (gen_return_media ());
7116       DONE;
7117     }
7118
7119   if (TARGET_SHCOMPACT
7120       && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
7121     {
7122       emit_jump_insn (gen_shcompact_return_tramp ());
7123       DONE;
7124     }
7125 }")
7126
7127 (define_insn "*return_i"
7128   [(return)]
7129   "TARGET_SH1 && ! (TARGET_SHCOMPACT
7130                     && (current_function_args_info.call_cookie
7131                         & CALL_COOKIE_RET_TRAMP (1)))
7132    && reload_completed"
7133   "%@   %#"
7134   [(set_attr "type" "return")
7135    (set_attr "needs_delay_slot" "yes")])
7136
7137 (define_expand "shcompact_return_tramp"
7138   [(return)]
7139   "TARGET_SHCOMPACT
7140    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7141   "
7142 {
7143   rtx reg = gen_rtx_REG (Pmode, R0_REG);
7144   rtx sym = gen_rtx_SYMBOL_REF (Pmode,
7145                                 \"__GCC_shcompact_return_trampoline\");
7146
7147   if (flag_pic)
7148     emit_insn (gen_symGOTPLT2reg (reg, sym));
7149   else
7150     emit_move_insn (reg, sym);
7151
7152   emit_jump_insn (gen_shcompact_return_tramp_i ());
7153   DONE;
7154 }")
7155
7156 (define_insn "shcompact_return_tramp_i"
7157   [(parallel [(return) (use (reg:SI R0_REG))])]
7158   "TARGET_SHCOMPACT
7159    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7160   "jmp  @r0%#"
7161   [(set_attr "type" "jump_ind")
7162    (set_attr "needs_delay_slot" "yes")])
7163
7164 (define_insn "return_media_i"
7165   [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7166   "TARGET_SHMEDIA && reload_completed"
7167   "blink        %0, r63"
7168   [(set_attr "type" "jump_media")])
7169
7170 (define_expand "return_media"
7171   [(return)]
7172   "TARGET_SHMEDIA && reload_completed"
7173   "
7174 {
7175   int tr_regno = sh_media_register_for_return ();
7176   rtx tr;
7177
7178   if (tr_regno < 0)
7179     {
7180       rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7181
7182       tr_regno = TR0_REG;
7183       tr = gen_rtx_REG (DImode, tr_regno);
7184       emit_move_insn (tr, r18);
7185     }
7186   else
7187     tr = gen_rtx_REG (DImode, tr_regno);
7188
7189   emit_jump_insn (gen_return_media_i (tr));
7190   DONE;
7191 }")
7192
7193 (define_insn "shcompact_preserve_incoming_args"
7194   [(set (match_operand:SI 0 "register_operand" "+r")
7195         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
7196   "TARGET_SHCOMPACT"
7197   ""
7198   [(set_attr "length" "0")])
7199
7200 (define_insn "shcompact_incoming_args"
7201   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7202    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7203    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7204    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7205    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7206    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7207    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7208    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
7209    (set (mem:BLK (reg:SI MACL_REG))
7210         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
7211    (use (reg:SI R0_REG))
7212    (clobber (reg:SI R0_REG))
7213    (clobber (reg:SI MACL_REG))
7214    (clobber (reg:SI MACH_REG))
7215    (clobber (reg:SI PR_REG))]
7216   "TARGET_SHCOMPACT"
7217   "jsr  @r0%#"
7218   [(set_attr "needs_delay_slot" "yes")])
7219
7220 (define_insn "shmedia_save_restore_regs_compact"
7221   [(set (reg:SI SP_REG)
7222         (plus:SI (reg:SI SP_REG)
7223                  (match_operand:SI 0 "immediate_operand" "i")))
7224    (use (reg:SI R0_REG))
7225    (clobber (reg:SI PR_REG))]
7226   "TARGET_SHCOMPACT
7227    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7228        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7229   "jsr @r0%#"
7230   [(set_attr "needs_delay_slot" "yes")])
7231
7232 (define_expand "prologue"
7233   [(const_int 0)]
7234   ""
7235   "sh_expand_prologue (); DONE;")
7236
7237 (define_expand "epilogue"
7238   [(return)]
7239   ""
7240   "
7241 {
7242   sh_expand_epilogue ();
7243   emit_jump_insn (gen_return ());
7244   DONE;
7245 }")
7246
7247 (define_insn "blockage"
7248   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7249   ""
7250   ""
7251   [(set_attr "length" "0")])
7252 \f
7253 ;; ------------------------------------------------------------------------
7254 ;; Scc instructions
7255 ;; ------------------------------------------------------------------------
7256
7257 (define_insn "movt"
7258   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7259         (eq:SI (reg:SI T_REG) (const_int 1)))]
7260   "TARGET_SH1"
7261   "movt %0"
7262   [(set_attr "type" "arith")])
7263
7264 (define_expand "seq"
7265   [(set (match_operand:SI 0 "arith_reg_operand" "")
7266         (match_dup 1))]
7267   ""
7268   "
7269 {
7270   if (TARGET_SHMEDIA)
7271     {
7272       if (GET_MODE (operands[0]) != DImode)
7273         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7274       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7275       if (sh_compare_op1 != const0_rtx)
7276         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7277                                     ? GET_MODE (sh_compare_op0)
7278                                     : GET_MODE (sh_compare_op1),
7279                                     sh_compare_op1);
7280
7281       switch (GET_MODE (sh_compare_op0))
7282         {
7283         case DImode:
7284           emit_insn (gen_cmpeqdi_media (operands[0],
7285                                         sh_compare_op0, sh_compare_op1));
7286           break;
7287
7288         case SFmode:
7289           if (! TARGET_SHMEDIA_FPU)
7290             FAIL;
7291           emit_insn (gen_cmpeqsf_media (operands[0],
7292                                         sh_compare_op0, sh_compare_op1));
7293           break;
7294
7295         case DFmode:
7296           if (! TARGET_SHMEDIA_FPU)
7297             FAIL;
7298           emit_insn (gen_cmpeqdf_media (operands[0],
7299                                         sh_compare_op0, sh_compare_op1));
7300           break;
7301
7302         default:
7303           FAIL;
7304         }
7305       DONE;
7306     }
7307   operands[1] = prepare_scc_operands (EQ);
7308 }")
7309
7310 (define_expand "slt"
7311   [(set (match_operand:SI 0 "arith_reg_operand" "")
7312         (match_dup 1))]
7313   ""
7314   "
7315 {
7316   if (TARGET_SHMEDIA)
7317     {
7318       if (GET_MODE (operands[0]) != DImode)
7319         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7320       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7321       if (sh_compare_op1 != const0_rtx)
7322         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7323                                     ? GET_MODE (sh_compare_op0)
7324                                     : GET_MODE (sh_compare_op1),
7325                                     sh_compare_op1);
7326
7327       switch (GET_MODE (sh_compare_op0))
7328         {
7329         case DImode:
7330           emit_insn (gen_cmpgtdi_media (operands[0],
7331                                         sh_compare_op1, sh_compare_op0));
7332           break;
7333
7334         case SFmode:
7335           if (! TARGET_SHMEDIA_FPU)
7336             FAIL;
7337           emit_insn (gen_cmpgtsf_media (operands[0],
7338                                         sh_compare_op1, sh_compare_op0));
7339           break;
7340
7341         case DFmode:
7342           if (! TARGET_SHMEDIA_FPU)
7343             FAIL;
7344           emit_insn (gen_cmpgtdf_media (operands[0],
7345                                         sh_compare_op1, sh_compare_op0));
7346           break;
7347
7348         default:
7349           FAIL;
7350         }
7351       DONE;
7352     }
7353   operands[1] = prepare_scc_operands (LT);
7354 }")
7355
7356 (define_expand "sle"
7357   [(match_operand:SI 0 "arith_reg_operand" "")]
7358   ""
7359   "
7360 {
7361   rtx tmp = sh_compare_op0;
7362
7363   if (TARGET_SHMEDIA)
7364     {
7365       if (GET_MODE (operands[0]) != DImode)
7366         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7367       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7368       if (sh_compare_op1 != const0_rtx)
7369         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7370                                     ? GET_MODE (sh_compare_op0)
7371                                     : GET_MODE (sh_compare_op1),
7372                                     sh_compare_op1);
7373
7374       switch (GET_MODE (sh_compare_op0))
7375         {
7376         case DImode:
7377           {
7378             tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7379
7380             emit_insn (gen_cmpgtdi_media (tmp,
7381                                           sh_compare_op0, sh_compare_op1));
7382             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7383             break;
7384           }
7385
7386         case SFmode:
7387           if (! TARGET_SHMEDIA_FPU)
7388             FAIL;
7389           emit_insn (gen_cmpgesf_media (operands[0],
7390                                         sh_compare_op1, sh_compare_op0));
7391           break;
7392
7393         case DFmode:
7394           if (! TARGET_SHMEDIA_FPU)
7395             FAIL;
7396           emit_insn (gen_cmpgedf_media (operands[0],
7397                                         sh_compare_op1, sh_compare_op0));
7398           break;
7399
7400         default:
7401           FAIL;
7402         }
7403       DONE;
7404     }
7405
7406   sh_compare_op0 = sh_compare_op1;
7407   sh_compare_op1 = tmp;
7408   emit_insn (gen_sge (operands[0]));
7409   DONE;
7410 }")
7411
7412 (define_expand "sgt"
7413   [(set (match_operand:SI 0 "arith_reg_operand" "")
7414         (match_dup 1))]
7415   ""
7416   "
7417 {
7418   if (TARGET_SHMEDIA)
7419     {
7420       if (GET_MODE (operands[0]) != DImode)
7421         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7422       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7423       if (sh_compare_op1 != const0_rtx)
7424         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7425                                     ? GET_MODE (sh_compare_op0)
7426                                     : GET_MODE (sh_compare_op1),
7427                                     sh_compare_op1);
7428
7429       switch (GET_MODE (sh_compare_op0))
7430         {
7431         case DImode:
7432           emit_insn (gen_cmpgtdi_media (operands[0],
7433                                         sh_compare_op0, sh_compare_op1));
7434           break;
7435
7436         case SFmode:
7437           if (! TARGET_SHMEDIA_FPU)
7438             FAIL;
7439           emit_insn (gen_cmpgtsf_media (operands[0],
7440                                         sh_compare_op0, sh_compare_op1));
7441           break;
7442
7443         case DFmode:
7444           if (! TARGET_SHMEDIA_FPU)
7445             FAIL;
7446           emit_insn (gen_cmpgtdf_media (operands[0],
7447                                         sh_compare_op0, sh_compare_op1));
7448           break;
7449
7450         default:
7451           FAIL;
7452         }
7453       DONE;
7454     }
7455   operands[1] = prepare_scc_operands (GT);
7456 }")
7457
7458 (define_expand "sge"
7459   [(set (match_operand:SI 0 "arith_reg_operand" "")
7460         (match_dup 1))]
7461   ""
7462   "
7463 {
7464   if (TARGET_SHMEDIA)
7465     {
7466       if (GET_MODE (operands[0]) != DImode)
7467         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7468       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7469       if (sh_compare_op1 != const0_rtx)
7470         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7471                                     ? GET_MODE (sh_compare_op0)
7472                                     : GET_MODE (sh_compare_op1),
7473                                     sh_compare_op1);
7474
7475       switch (GET_MODE (sh_compare_op0))
7476         {
7477         case DImode:
7478           {
7479             rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7480
7481             emit_insn (gen_cmpgtdi_media (tmp,
7482                                           sh_compare_op1, sh_compare_op0));
7483             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7484             break;
7485           }
7486
7487         case SFmode:
7488           if (! TARGET_SHMEDIA_FPU)
7489             FAIL;
7490           emit_insn (gen_cmpgesf_media (operands[0],
7491                                         sh_compare_op0, sh_compare_op1));
7492           break;
7493
7494         case DFmode:
7495           if (! TARGET_SHMEDIA_FPU)
7496             FAIL;
7497           emit_insn (gen_cmpgedf_media (operands[0],
7498                                         sh_compare_op0, sh_compare_op1));
7499           break;
7500
7501         default:
7502           FAIL;
7503         }
7504       DONE;
7505     }
7506
7507   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7508     {
7509       if (TARGET_IEEE)
7510         {
7511           rtx lab = gen_label_rtx ();
7512           prepare_scc_operands (EQ);
7513           emit_jump_insn (gen_branch_true (lab));
7514           prepare_scc_operands (GT);
7515           emit_label (lab);
7516           emit_insn (gen_movt (operands[0]));
7517         }
7518       else
7519         emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
7520       DONE;
7521     }
7522   operands[1] = prepare_scc_operands (GE);
7523 }")
7524
7525 (define_expand "sgtu"
7526   [(set (match_operand:SI 0 "arith_reg_operand" "")
7527         (match_dup 1))]
7528   ""
7529   "
7530 {
7531   if (TARGET_SHMEDIA)
7532     {
7533       if (GET_MODE (operands[0]) != DImode)
7534         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7535       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7536       if (sh_compare_op1 != const0_rtx)
7537         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7538                                     ? GET_MODE (sh_compare_op0)
7539                                     : GET_MODE (sh_compare_op1),
7540                                     sh_compare_op1);
7541
7542       emit_insn (gen_cmpgtudi_media (operands[0],
7543                                      sh_compare_op0, sh_compare_op1));
7544       DONE;
7545     }
7546   operands[1] = prepare_scc_operands (GTU);
7547 }")
7548
7549 (define_expand "sltu"
7550   [(set (match_operand:SI 0 "arith_reg_operand" "")
7551         (match_dup 1))]
7552   ""
7553   "
7554 {
7555   if (TARGET_SHMEDIA)
7556     {
7557       if (GET_MODE (operands[0]) != DImode)
7558         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7559       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7560       if (sh_compare_op1 != const0_rtx)
7561         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7562                                     ? GET_MODE (sh_compare_op0)
7563                                     : GET_MODE (sh_compare_op1),
7564                                     sh_compare_op1);
7565
7566       emit_insn (gen_cmpgtudi_media (operands[0],
7567                                      sh_compare_op1, sh_compare_op0));
7568       DONE;
7569     }
7570   operands[1] = prepare_scc_operands (LTU);
7571 }")
7572
7573 (define_expand "sleu"
7574   [(set (match_operand:SI 0 "arith_reg_operand" "")
7575         (match_dup 1))]
7576   ""
7577   "
7578 {
7579   if (TARGET_SHMEDIA)
7580     {
7581       rtx tmp;
7582
7583       if (GET_MODE (operands[0]) != DImode)
7584         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7585       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7586       if (sh_compare_op1 != const0_rtx)
7587         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7588                                     ? GET_MODE (sh_compare_op0)
7589                                     : GET_MODE (sh_compare_op1),
7590                                     sh_compare_op1);
7591
7592       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7593
7594       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7595       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7596
7597       DONE;
7598     }
7599   operands[1] = prepare_scc_operands (LEU);
7600 }")
7601
7602 (define_expand "sgeu"
7603   [(set (match_operand:SI 0 "arith_reg_operand" "")
7604         (match_dup 1))]
7605   ""
7606   "
7607 {
7608   if (TARGET_SHMEDIA)
7609     {
7610       rtx tmp;
7611
7612       if (GET_MODE (operands[0]) != DImode)
7613         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7614       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7615       if (sh_compare_op1 != const0_rtx)
7616         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7617                                     ? GET_MODE (sh_compare_op0)
7618                                     : GET_MODE (sh_compare_op1),
7619                                     sh_compare_op1);
7620
7621       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7622
7623       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7624       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7625
7626       DONE;
7627     }
7628
7629   operands[1] = prepare_scc_operands (GEU);
7630 }")
7631
7632 ;; sne moves the complement of the T reg to DEST like this:
7633 ;;      cmp/eq ...
7634 ;;      mov    #-1,temp
7635 ;;      negc   temp,dest
7636 ;;   This is better than xoring compare result with 1 because it does
7637 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
7638 ;;   loop.
7639
7640 (define_expand "sne"
7641   [(set (match_dup 2) (const_int -1))
7642    (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7643                    (neg:SI (plus:SI (match_dup 1)
7644                                     (match_dup 2))))
7645               (set (reg:SI T_REG)
7646                    (ne:SI (ior:SI (match_dup 1) (match_dup 2))
7647                           (const_int 0)))])]
7648   ""
7649   "
7650 {
7651   if (TARGET_SHMEDIA)
7652     {
7653       rtx tmp;
7654
7655       if (GET_MODE (operands[0]) != DImode)
7656         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7657
7658       if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7659         FAIL;
7660
7661       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7662       if (sh_compare_op1 != const0_rtx)
7663         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7664                                     ? GET_MODE (sh_compare_op0)
7665                                     : GET_MODE (sh_compare_op1),
7666                                     sh_compare_op1);
7667
7668       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7669
7670       emit_insn (gen_seq (tmp));
7671       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7672
7673       DONE;
7674     }
7675
7676    operands[1] = prepare_scc_operands (EQ);
7677    operands[2] = gen_reg_rtx (SImode);
7678 }")
7679
7680 (define_expand "sunordered"
7681   [(set (match_operand:DI 0 "arith_reg_operand" "")
7682         (unordered:DI (match_dup 1) (match_dup 2)))]
7683   "TARGET_SHMEDIA_FPU"
7684   "
7685 {
7686   operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7687   operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7688 }")
7689
7690 ;; Use the same trick for FP sle / sge
7691 (define_expand "movnegt"
7692   [(set (match_dup 2) (const_int -1))
7693    (parallel [(set (match_operand 0 "" "")
7694                    (neg:SI (plus:SI (match_dup 1)
7695                                     (match_dup 2))))
7696               (set (reg:SI T_REG)
7697                    (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
7698                           (const_int 0)))])]
7699   "TARGET_SH1"
7700   "operands[2] = gen_reg_rtx (SImode);")
7701
7702 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
7703 ;; This prevents a regression that occurred when we switched from xor to
7704 ;; mov/neg for sne.
7705
7706 (define_split
7707   [(set (match_operand:SI 0 "arith_reg_operand" "")
7708         (plus:SI (reg:SI T_REG)
7709                  (const_int -1)))]
7710   "TARGET_SH1"
7711   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
7712    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7713   "")
7714
7715 ;; -------------------------------------------------------------------------
7716 ;; Instructions to cope with inline literal tables
7717 ;; -------------------------------------------------------------------------
7718
7719 ; 2 byte integer in line
7720
7721 (define_insn "consttable_2"
7722  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7723                     (match_operand 1 "" "")]
7724                    UNSPECV_CONST2)]
7725  ""
7726  "*
7727 {
7728   if (operands[1] != const0_rtx)
7729     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
7730   return \"\";
7731 }"
7732  [(set_attr "length" "2")
7733  (set_attr "in_delay_slot" "no")])
7734
7735 ; 4 byte integer in line
7736
7737 (define_insn "consttable_4"
7738  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7739                     (match_operand 1 "" "")]
7740                    UNSPECV_CONST4)]
7741  ""
7742  "*
7743 {
7744   if (operands[1] != const0_rtx)
7745     assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
7746   return \"\";
7747 }"
7748  [(set_attr "length" "4")
7749   (set_attr "in_delay_slot" "no")])
7750
7751 ; 8 byte integer in line
7752
7753 (define_insn "consttable_8"
7754  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7755                     (match_operand 1 "" "")]
7756                    UNSPECV_CONST8)]
7757  ""
7758  "*
7759 {
7760   if (operands[1] != const0_rtx)
7761     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
7762   return \"\";
7763 }"
7764  [(set_attr "length" "8")
7765   (set_attr "in_delay_slot" "no")])
7766
7767 ; 4 byte floating point
7768
7769 (define_insn "consttable_sf"
7770  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7771                     (match_operand 1 "" "")]
7772                    UNSPECV_CONST4)]
7773  ""
7774  "*
7775 {
7776   if (operands[1] != const0_rtx)
7777     {
7778       REAL_VALUE_TYPE d;
7779       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7780       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
7781     }
7782   return \"\";
7783 }"
7784  [(set_attr "length" "4")
7785   (set_attr "in_delay_slot" "no")])
7786
7787 ; 8 byte floating point
7788
7789 (define_insn "consttable_df"
7790  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
7791                     (match_operand 1 "" "")]
7792                    UNSPECV_CONST8)]
7793  ""
7794  "*
7795 {
7796   if (operands[1] != const0_rtx)
7797     {
7798       REAL_VALUE_TYPE d;
7799       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7800       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
7801     }
7802   return \"\";
7803 }"
7804  [(set_attr "length" "8")
7805   (set_attr "in_delay_slot" "no")])
7806
7807 ;; Alignment is needed for some constant tables; it may also be added for
7808 ;; Instructions at the start of loops, or after unconditional branches.
7809 ;; ??? We would get more accurate lengths if we did instruction
7810 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
7811 ;; here is too conservative.
7812
7813 ; align to a two byte boundary
7814
7815 (define_expand "align_2"
7816  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
7817  ""
7818  "")
7819
7820 ; align to a four byte boundary
7821 ;; align_4 and align_log are instructions for the starts of loops, or
7822 ;; after unconditional branches, which may take up extra room.
7823
7824 (define_expand "align_4"
7825  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
7826  ""
7827  "")
7828
7829 ; align to a cache line boundary
7830
7831 (define_insn "align_log"
7832  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
7833  ""
7834  ""
7835  [(set_attr "length" "0")
7836   (set_attr "in_delay_slot" "no")])
7837
7838 ; emitted at the end of the literal table, used to emit the
7839 ; 32bit branch labels if needed.
7840
7841 (define_insn "consttable_end"
7842   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
7843   ""
7844   "* return output_jump_label_table ();"
7845   [(set_attr "in_delay_slot" "no")])
7846
7847 ; emitted at the end of the window in the literal table.
7848
7849 (define_insn "consttable_window_end"
7850   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
7851   ""
7852   ""
7853   [(set_attr "length" "0")
7854    (set_attr "in_delay_slot" "no")])
7855
7856 ;; -------------------------------------------------------------------------
7857 ;; Misc
7858 ;; -------------------------------------------------------------------------
7859
7860 ;; String/block move insn.
7861
7862 (define_expand "movstrsi"
7863   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
7864                    (mem:BLK (match_operand:BLK 1 "" "")))
7865               (use (match_operand:SI 2 "nonmemory_operand" ""))
7866               (use (match_operand:SI 3 "immediate_operand" ""))
7867               (clobber (reg:SI PR_REG))
7868               (clobber (reg:SI R4_REG))
7869               (clobber (reg:SI R5_REG))
7870               (clobber (reg:SI R0_REG))])]
7871   "TARGET_SH1 && ! TARGET_SH5"
7872   "
7873 {
7874   if(expand_block_move (operands))
7875      DONE;
7876   else FAIL;
7877 }")
7878
7879 (define_insn "block_move_real"
7880   [(parallel [(set (mem:BLK (reg:SI R4_REG))
7881                    (mem:BLK (reg:SI R5_REG)))
7882               (use (match_operand:SI 0 "arith_reg_operand" "r"))
7883               (clobber (reg:SI PR_REG))
7884               (clobber (reg:SI R0_REG))])]
7885   "TARGET_SH1 && ! TARGET_HARD_SH4"
7886   "jsr  @%0%#"
7887   [(set_attr "type" "sfunc")
7888    (set_attr "needs_delay_slot" "yes")])
7889
7890 (define_insn "block_lump_real"
7891   [(parallel [(set (mem:BLK (reg:SI R4_REG))
7892                    (mem:BLK (reg:SI R5_REG)))
7893               (use (match_operand:SI 0 "arith_reg_operand" "r"))
7894               (use (reg:SI R6_REG))
7895               (clobber (reg:SI PR_REG))
7896               (clobber (reg:SI T_REG))
7897               (clobber (reg:SI R4_REG))
7898               (clobber (reg:SI R5_REG))
7899               (clobber (reg:SI R6_REG))
7900               (clobber (reg:SI R0_REG))])]
7901   "TARGET_SH1 && ! TARGET_HARD_SH4"
7902   "jsr  @%0%#"
7903   [(set_attr "type" "sfunc")
7904    (set_attr "needs_delay_slot" "yes")])
7905
7906 (define_insn "block_move_real_i4"
7907   [(parallel [(set (mem:BLK (reg:SI R4_REG))
7908                    (mem:BLK (reg:SI R5_REG)))
7909               (use (match_operand:SI 0 "arith_reg_operand" "r"))
7910               (clobber (reg:SI PR_REG))
7911               (clobber (reg:SI R0_REG))
7912               (clobber (reg:SI R1_REG))
7913               (clobber (reg:SI R2_REG))])]
7914   "TARGET_HARD_SH4"
7915   "jsr  @%0%#"
7916   [(set_attr "type" "sfunc")
7917    (set_attr "needs_delay_slot" "yes")])
7918
7919 (define_insn "block_lump_real_i4"
7920   [(parallel [(set (mem:BLK (reg:SI R4_REG))
7921                    (mem:BLK (reg:SI R5_REG)))
7922               (use (match_operand:SI 0 "arith_reg_operand" "r"))
7923               (use (reg:SI R6_REG))
7924               (clobber (reg:SI PR_REG))
7925               (clobber (reg:SI T_REG))
7926               (clobber (reg:SI R4_REG))
7927               (clobber (reg:SI R5_REG))
7928               (clobber (reg:SI R6_REG))
7929               (clobber (reg:SI R0_REG))
7930               (clobber (reg:SI R1_REG))
7931               (clobber (reg:SI R2_REG))
7932               (clobber (reg:SI R3_REG))])]
7933   "TARGET_HARD_SH4"
7934   "jsr  @%0%#"
7935   [(set_attr "type" "sfunc")
7936    (set_attr "needs_delay_slot" "yes")])
7937 \f
7938 ;; -------------------------------------------------------------------------
7939 ;; Floating point instructions.
7940 ;; -------------------------------------------------------------------------
7941
7942 ;; ??? All patterns should have a type attribute.
7943
7944 (define_expand "fpu_switch0"
7945   [(set (match_operand:SI 0 "" "") (match_dup 2))
7946    (set (match_dup 1) (mem:PSI (match_dup 0)))]
7947   "TARGET_SH4"
7948   "
7949 {
7950   operands[1] = get_fpscr_rtx ();
7951   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
7952   if (flag_pic)
7953     operands[2] = legitimize_pic_address (operands[2], SImode,
7954                                           no_new_pseudos ? operands[0] : 0);
7955 }")
7956
7957 (define_expand "fpu_switch1"
7958   [(set (match_operand:SI 0 "" "") (match_dup 2))
7959    (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
7960    (set (match_dup 1) (mem:PSI (match_dup 3)))]
7961   "TARGET_SH4"
7962   "
7963 {
7964   operands[1] = get_fpscr_rtx ();
7965   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
7966   if (flag_pic)
7967     operands[2] = legitimize_pic_address (operands[2], SImode,
7968                                           no_new_pseudos ? operands[0] : 0);
7969   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
7970 }")
7971
7972 (define_expand "movpsi"
7973   [(set (match_operand:PSI 0 "register_operand" "")
7974         (match_operand:PSI 1 "general_movsrc_operand" ""))]
7975   "TARGET_SH4"
7976   "")
7977
7978 ;; The c / m alternative is a fake to guide reload to load directly into
7979 ;; fpscr, since reload doesn't know how to use post-increment.
7980 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
7981 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
7982 ;; predicate after reload.
7983 ;; The gp_fpul type for r/!c might look a bit odd, but it actually schedules
7984 ;; like a gpr <-> fpul move.
7985 (define_insn "fpu_switch"
7986   [(set (match_operand:PSI 0 "register_operand" "=c,c,r,c,c,r,m,r")
7987         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c"))]
7988   "TARGET_SH4
7989    && (! reload_completed
7990        || true_regnum (operands[0]) != FPSCR_REG
7991        || GET_CODE (operands[1]) != MEM
7992        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
7993   "@
7994         ! precision stays the same
7995         lds.l   %1,fpscr
7996         mov.l   %1,%0
7997         #
7998         lds     %1,fpscr
7999         mov     %1,%0
8000         mov.l   %1,%0
8001         sts     fpscr,%0"
8002   [(set_attr "length" "0,2,2,4,2,2,2,2")
8003    (set_attr "type" "dfp_conv,dfp_conv,load,dfp_conv,dfp_conv,move,store,gp_fpul")
8004    (set_attr "insn_class" "ldsmem_to_fpscr,*,*,lds_to_fpscr,*,*,*,*")])
8005
8006 (define_split
8007   [(set (reg:PSI FPSCR_REG)
8008         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8009   "TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
8010   [(set (match_dup 0) (match_dup 0))]
8011   "
8012 {
8013   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8014                                         gen_rtx (MEM, PSImode,
8015                                                  gen_rtx (POST_INC, Pmode,
8016                                                           operands[0]))));
8017   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
8018 }")
8019
8020 (define_split
8021   [(set (reg:PSI FPSCR_REG)
8022         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8023   "TARGET_SH4"
8024   [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
8025   "
8026 {
8027   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8028                                         gen_rtx (MEM, PSImode,
8029                                                  gen_rtx (POST_INC, Pmode,
8030                                                           operands[0]))));
8031   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
8032 }")
8033
8034 ;; ??? This uses the fp unit, but has no type indicating that.
8035 ;; If we did that, this would either give a bogus latency or introduce
8036 ;; a bogus FIFO constraint.
8037 ;; Since this insn is currently only used for prologues/epilogues,
8038 ;; it is probably best to claim no function unit, which matches the
8039 ;; current setting.
8040 (define_insn "toggle_sz"
8041   [(set (reg:PSI FPSCR_REG)
8042         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
8043   "TARGET_SH4"
8044   "fschg")
8045
8046 (define_expand "addsf3"
8047   [(set (match_operand:SF 0 "arith_reg_operand" "")
8048         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
8049                  (match_operand:SF 2 "arith_reg_operand" "")))]
8050   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8051   "
8052 {
8053   if (TARGET_SH3E)
8054     {
8055       expand_sf_binop (&gen_addsf3_i, operands);
8056       DONE;
8057     }
8058 }")
8059
8060 (define_insn "*addsf3_media"
8061   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8062         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8063                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8064   "TARGET_SHMEDIA_FPU"
8065   "fadd.s       %1, %2, %0"
8066   [(set_attr "type" "fparith_media")])
8067
8068 (define_insn_and_split "unary_sf_op"
8069   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8070         (vec_select:V2SF
8071          (vec_concat:V2SF
8072           (vec_select:SF
8073            (match_dup 0)
8074            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
8075           (match_operator:SF 2 "unary_float_operator"
8076             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8077                             (parallel [(match_operand 4
8078                                         "const_int_operand" "n")]))]))
8079          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
8080   "TARGET_SHMEDIA_FPU"
8081   "#"
8082   "TARGET_SHMEDIA_FPU && reload_completed"
8083   [(set (match_dup 5) (match_dup 6))]
8084   "
8085 {
8086   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8087   rtx op1 = gen_rtx_REG (SFmode,
8088                          (true_regnum (operands[1])
8089                           + (INTVAL (operands[4]) ^ endian)));
8090
8091   operands[7] = gen_rtx_REG (SFmode,
8092                              (true_regnum (operands[0])
8093                               + (INTVAL (operands[3]) ^ endian)));
8094   operands[6] = gen_rtx (GET_CODE (operands[2]), SFmode, op1);
8095 }"
8096   [(set_attr "type" "fparith_media")])
8097
8098 (define_insn_and_split "binary_sf_op"
8099   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8100         (vec_select:V2SF
8101          (vec_concat:V2SF
8102           (vec_select:SF
8103            (match_dup 0)
8104            (parallel [(not:BI (match_operand 4 "const_int_operand" "n"))]))
8105           (match_operator:SF 3 "binary_float_operator"
8106             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8107                             (parallel [(match_operand 5
8108                                         "const_int_operand" "n")]))
8109              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
8110                             (parallel [(match_operand 6
8111                                         "const_int_operand" "n")]))]))
8112          (parallel [(not:BI (match_dup 4)) (match_dup 4)])))]
8113   "TARGET_SHMEDIA_FPU"
8114   "#"
8115   "TARGET_SHMEDIA_FPU && reload_completed"
8116   [(set (match_dup 7) (match_dup 8))]
8117   "
8118 {
8119   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8120   rtx op1 = gen_rtx_REG (SFmode,
8121                          (true_regnum (operands[1])
8122                           + (INTVAL (operands[5]) ^ endian)));
8123   rtx op2 = gen_rtx_REG (SFmode,
8124                          (true_regnum (operands[2])
8125                           + (INTVAL (operands[6]) ^ endian)));
8126
8127   operands[7] = gen_rtx_REG (SFmode,
8128                              (true_regnum (operands[0])
8129                               + (INTVAL (operands[4]) ^ endian)));
8130   operands[8] = gen_rtx (GET_CODE (operands[3]), SFmode, op1, op2);
8131 }"
8132   [(set_attr "type" "fparith_media")])
8133
8134 (define_insn "addsf3_i"
8135   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8136         (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
8137                  (match_operand:SF 2 "arith_reg_operand" "f")))
8138    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8139   "TARGET_SH3E"
8140   "fadd %2,%0"
8141   [(set_attr "type" "fp")
8142    (set_attr "fp_mode" "single")])
8143
8144 (define_expand "subsf3"
8145   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8146         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8147                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8148   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8149   "
8150 {
8151   if (TARGET_SH3E)
8152     {
8153       expand_sf_binop (&gen_subsf3_i, operands);
8154       DONE;
8155     }
8156 }")
8157
8158 (define_insn "*subsf3_media"
8159   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8160         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8161                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8162   "TARGET_SHMEDIA_FPU"
8163   "fsub.s       %1, %2, %0"
8164   [(set_attr "type" "fparith_media")])
8165
8166 (define_insn "subsf3_i"
8167   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8168         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8169                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8170    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8171   "TARGET_SH3E"
8172   "fsub %2,%0"
8173   [(set_attr "type" "fp")
8174    (set_attr "fp_mode" "single")])
8175
8176 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8177 ;; register in feeding fp instructions.  Thus, we cannot generate fmac for
8178 ;; mixed-precision SH4 targets.  To allow it to be still generated for the
8179 ;; SH3E, we use a separate insn for SH3E mulsf3.
8180
8181 (define_expand "mulsf3"
8182   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8183         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8184                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8185   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8186   "
8187 {
8188   if (TARGET_SH4)
8189     expand_sf_binop (&gen_mulsf3_i4, operands);
8190   else if (TARGET_SH3E)
8191     emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
8192   if (! TARGET_SHMEDIA)
8193     DONE;
8194 }")
8195
8196 (define_insn "*mulsf3_media"
8197   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8198         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8199                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8200   "TARGET_SHMEDIA_FPU"
8201   "fmul.s       %1, %2, %0"
8202   [(set_attr "type" "fparith_media")])
8203
8204 (define_insn "mulsf3_i4"
8205   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8206         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8207                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8208    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8209   "TARGET_SH3E"
8210   "fmul %2,%0"
8211   [(set_attr "type" "fp")
8212    (set_attr "fp_mode" "single")])
8213
8214 (define_insn "mulsf3_ie"
8215   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8216         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8217                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8218   "TARGET_SH3E && ! TARGET_SH4"
8219   "fmul %2,%0"
8220   [(set_attr "type" "fp")])
8221
8222 (define_insn "*mac_media"
8223   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8224         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8225                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8226                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8227   "TARGET_SHMEDIA_FPU"
8228   "fmac.s %1, %2, %0"
8229   [(set_attr "type" "fparith_media")])
8230
8231 (define_insn "*macsf3"
8232   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8233         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8234                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8235                  (match_operand:SF 3 "arith_reg_operand" "0")))
8236    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
8237   "TARGET_SH3E && ! TARGET_SH4"
8238   "fmac fr0,%2,%0"
8239   [(set_attr "type" "fp")
8240    (set_attr "fp_mode" "single")])
8241
8242 (define_expand "divsf3"
8243   [(set (match_operand:SF 0 "arith_reg_operand" "")
8244         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8245                 (match_operand:SF 2 "arith_reg_operand" "")))]
8246   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8247   "
8248 {
8249   if (TARGET_SH3E)
8250     {
8251       expand_sf_binop (&gen_divsf3_i, operands);
8252       DONE;
8253     }
8254 }")
8255
8256 (define_insn "*divsf3_media"
8257   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8258         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8259                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8260   "TARGET_SHMEDIA_FPU"
8261   "fdiv.s       %1, %2, %0"
8262   [(set_attr "type" "fdiv_media")])
8263
8264 (define_insn "divsf3_i"
8265   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8266         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
8267                  (match_operand:SF 2 "arith_reg_operand" "f")))
8268    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8269   "TARGET_SH3E"
8270   "fdiv %2,%0"
8271   [(set_attr "type" "fdiv")
8272    (set_attr "fp_mode" "single")])
8273
8274 (define_insn "floatdisf2"
8275   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8276         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8277   "TARGET_SHMEDIA_FPU"
8278   "float.qs %1, %0"
8279   [(set_attr "type" "fpconv_media")])
8280
8281 (define_expand "floatsisf2"
8282   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8283         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
8284   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8285   "
8286 {
8287   if (TARGET_SH4)
8288     {
8289       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8290       DONE;
8291     }
8292 }")
8293
8294 (define_insn "*floatsisf2_media"
8295   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8296         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8297   "TARGET_SHMEDIA_FPU"
8298   "float.ls     %1, %0"
8299   [(set_attr "type" "fpconv_media")])
8300
8301 (define_insn "floatsisf2_i4"
8302   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8303         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
8304    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8305   "TARGET_SH4"
8306   "float        %1,%0"
8307   [(set_attr "type" "fp")
8308    (set_attr "fp_mode" "single")])
8309
8310 (define_insn "*floatsisf2_ie"
8311   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8312         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
8313   "TARGET_SH3E && ! TARGET_SH4"
8314   "float        %1,%0"
8315   [(set_attr "type" "fp")])
8316
8317 (define_insn "fix_truncsfdi2"
8318   [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8319         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8320   "TARGET_SHMEDIA_FPU"
8321   "ftrc.sq %1, %0"
8322   [(set_attr "type" "fpconv_media")])
8323
8324 (define_expand "fix_truncsfsi2"
8325   [(set (match_operand:SI 0 "fpul_operand" "=y")
8326         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8327   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8328   "
8329 {
8330   if (TARGET_SH4)
8331     {
8332       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8333       DONE;
8334     }
8335 }")
8336
8337 (define_insn "*fix_truncsfsi2_media"
8338   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8339         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8340   "TARGET_SHMEDIA_FPU"
8341   "ftrc.sl      %1, %0"
8342   [(set_attr "type" "fpconv_media")])
8343
8344 (define_insn "fix_truncsfsi2_i4"
8345   [(set (match_operand:SI 0 "fpul_operand" "=y")
8346         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8347    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8348   "TARGET_SH4"
8349   "ftrc %1,%0"
8350   [(set_attr "type" "fp")
8351    (set_attr "fp_mode" "single")])
8352
8353 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
8354 ;; fix_truncsfsi2_i4.
8355 ;; (define_insn "fix_truncsfsi2_i4_2"
8356 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8357 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8358 ;;   (use (reg:PSI FPSCR_REG))
8359 ;;   (clobber (reg:SI FPUL_REG))]
8360 ;;  "TARGET_SH4"
8361 ;;  "#"
8362 ;;  [(set_attr "length" "4")
8363 ;;   (set_attr "fp_mode" "single")])
8364
8365 ;;(define_split
8366 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8367 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8368 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
8369 ;;   (clobber (reg:SI FPUL_REG))]
8370 ;;  "TARGET_SH4"
8371 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8372 ;;            (use (match_dup 2))])
8373 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
8374
8375 (define_insn "*fixsfsi"
8376   [(set (match_operand:SI 0 "fpul_operand" "=y")
8377         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8378   "TARGET_SH3E && ! TARGET_SH4"
8379   "ftrc %1,%0"
8380   [(set_attr "type" "fp")])
8381
8382 (define_insn "cmpgtsf_t"
8383   [(set (reg:SI T_REG)
8384         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8385                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8386   "TARGET_SH3E && ! TARGET_SH4"
8387   "fcmp/gt      %1,%0"
8388   [(set_attr "type" "fp")
8389    (set_attr "fp_mode" "single")])
8390
8391 (define_insn "cmpeqsf_t"
8392   [(set (reg:SI T_REG)
8393         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8394                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8395   "TARGET_SH3E && ! TARGET_SH4"
8396   "fcmp/eq      %1,%0"
8397   [(set_attr "type" "fp")
8398    (set_attr "fp_mode" "single")])
8399
8400 (define_insn "ieee_ccmpeqsf_t"
8401   [(set (reg:SI T_REG)
8402         (ior:SI (reg:SI T_REG)
8403                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8404                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
8405   "TARGET_SH3E && TARGET_IEEE && ! TARGET_SH4"
8406   "* return output_ieee_ccmpeq (insn, operands);"
8407   [(set_attr "length" "4")])
8408
8409
8410 (define_insn "cmpgtsf_t_i4"
8411   [(set (reg:SI T_REG)
8412         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8413                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8414    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8415   "TARGET_SH4"
8416   "fcmp/gt      %1,%0"
8417   [(set_attr "type" "fp")
8418    (set_attr "fp_mode" "single")])
8419
8420 (define_insn "cmpeqsf_t_i4"
8421   [(set (reg:SI T_REG)
8422         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8423                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8424    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8425   "TARGET_SH4"
8426   "fcmp/eq      %1,%0"
8427   [(set_attr "type" "fp")
8428    (set_attr "fp_mode" "single")])
8429
8430 (define_insn "*ieee_ccmpeqsf_t_4"
8431   [(set (reg:SI T_REG)
8432         (ior:SI (reg:SI T_REG)
8433                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8434                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
8435    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8436   "TARGET_IEEE && TARGET_SH4"
8437   "* return output_ieee_ccmpeq (insn, operands);"
8438   [(set_attr "length" "4")
8439    (set_attr "fp_mode" "single")])
8440
8441 (define_insn "cmpeqsf_media"
8442   [(set (match_operand:DI 0 "register_operand" "=r")
8443         (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8444                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8445   "TARGET_SHMEDIA_FPU"
8446   "fcmpeq.s     %1, %2, %0"
8447   [(set_attr "type" "fcmp_media")])
8448
8449 (define_insn "cmpgtsf_media"
8450   [(set (match_operand:DI 0 "register_operand" "=r")
8451         (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8452                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8453   "TARGET_SHMEDIA_FPU"
8454   "fcmpgt.s     %1, %2, %0"
8455   [(set_attr "type" "fcmp_media")])
8456
8457 (define_insn "cmpgesf_media"
8458   [(set (match_operand:DI 0 "register_operand" "=r")
8459         (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8460                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8461   "TARGET_SHMEDIA_FPU"
8462   "fcmpge.s     %1, %2, %0"
8463   [(set_attr "type" "fcmp_media")])
8464
8465 (define_insn "cmpunsf_media"
8466   [(set (match_operand:DI 0 "register_operand" "=r")
8467         (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8468                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8469   "TARGET_SHMEDIA_FPU"
8470   "fcmpun.s     %1, %2, %0"
8471   [(set_attr "type" "fcmp_media")])
8472
8473 (define_expand "cmpsf"
8474   [(set (reg:SI T_REG)
8475         (compare (match_operand:SF 0 "arith_operand" "")
8476                  (match_operand:SF 1 "arith_operand" "")))]
8477   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8478   "
8479 {
8480   sh_compare_op0 = operands[0];
8481   sh_compare_op1 = operands[1];
8482   DONE;
8483 }")
8484
8485 (define_expand "negsf2"
8486   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8487         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8488   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8489   "
8490 {
8491   if (TARGET_SH3E)
8492     {
8493       expand_sf_unop (&gen_negsf2_i, operands);
8494       DONE;
8495     }
8496 }")
8497
8498 (define_insn "*negsf2_media"
8499   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8500         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8501   "TARGET_SHMEDIA_FPU"
8502   "fneg.s       %1, %0"
8503   [(set_attr "type" "fmove_media")])
8504
8505 (define_insn "negsf2_i"
8506   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8507         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8508    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8509   "TARGET_SH3E"
8510   "fneg %0"
8511   [(set_attr "type" "fmove")
8512    (set_attr "fp_mode" "single")])
8513
8514 (define_expand "sqrtsf2"
8515   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8516         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8517   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8518   "
8519 {
8520   if (TARGET_SH3E)
8521     {
8522       expand_sf_unop (&gen_sqrtsf2_i, operands);
8523       DONE;
8524     }
8525 }")
8526
8527 (define_insn "*sqrtsf2_media"
8528   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8529         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8530   "TARGET_SHMEDIA_FPU"
8531   "fsqrt.s      %1, %0"
8532   [(set_attr "type" "fdiv_media")])
8533
8534 (define_insn "sqrtsf2_i"
8535   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8536         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8537    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8538   "TARGET_SH3E"
8539   "fsqrt        %0"
8540   [(set_attr "type" "fdiv")
8541    (set_attr "fp_mode" "single")])
8542
8543 (define_expand "abssf2"
8544   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8545         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8546   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8547   "
8548 {
8549   if (TARGET_SH3E)
8550     {
8551       expand_sf_unop (&gen_abssf2_i, operands);
8552       DONE;
8553     }
8554 }")
8555
8556 (define_insn "*abssf2_media"
8557   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8558         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8559   "TARGET_SHMEDIA_FPU"
8560   "fabs.s       %1, %0"
8561   [(set_attr "type" "fmove_media")])
8562
8563 (define_insn "abssf2_i"
8564   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8565         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8566    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8567   "TARGET_SH3E"
8568   "fabs %0"
8569   [(set_attr "type" "fmove")
8570    (set_attr "fp_mode" "single")])
8571
8572 (define_expand "adddf3"
8573   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8574         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8575                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8576   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8577   "
8578 {
8579   if (TARGET_SH4)
8580     {
8581       expand_df_binop (&gen_adddf3_i, operands);
8582       DONE;
8583     }
8584 }")
8585
8586 (define_insn "*adddf3_media"
8587   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8588         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8589                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8590   "TARGET_SHMEDIA_FPU"
8591   "fadd.d       %1, %2, %0"
8592   [(set_attr "type" "dfparith_media")])
8593
8594 (define_insn "adddf3_i"
8595   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8596         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8597                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8598    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8599   "TARGET_SH4"
8600   "fadd %2,%0"
8601   [(set_attr "type" "dfp_arith")
8602    (set_attr "fp_mode" "double")])
8603
8604 (define_expand "subdf3"
8605   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8606         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8607                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8608   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8609   "
8610 {
8611   if (TARGET_SH4)
8612     {
8613       expand_df_binop (&gen_subdf3_i, operands);
8614       DONE;
8615     }
8616 }")
8617
8618 (define_insn "*subdf3_media"
8619   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8620         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8621                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8622   "TARGET_SHMEDIA_FPU"
8623   "fsub.d       %1, %2, %0"
8624   [(set_attr "type" "dfparith_media")])
8625
8626 (define_insn "subdf3_i"
8627   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8628         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8629                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8630    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8631   "TARGET_SH4"
8632   "fsub %2,%0"
8633   [(set_attr "type" "dfp_arith")
8634    (set_attr "fp_mode" "double")])
8635
8636 (define_expand "muldf3"
8637   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8638         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8639                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8640   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8641   "
8642 {
8643   if (TARGET_SH4)
8644     {
8645       expand_df_binop (&gen_muldf3_i, operands);
8646       DONE;
8647     }
8648 }")
8649
8650 (define_insn "*muldf3_media"
8651   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8652         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8653                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8654   "TARGET_SHMEDIA_FPU"
8655   "fmul.d       %1, %2, %0"
8656   [(set_attr "type" "dfmul_media")])
8657
8658 (define_insn "muldf3_i"
8659   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8660         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8661                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8662    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8663   "TARGET_SH4"
8664   "fmul %2,%0"
8665   [(set_attr "type" "dfp_arith")
8666    (set_attr "fp_mode" "double")])
8667
8668 (define_expand "divdf3"
8669   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8670         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8671                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8672   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8673   "
8674 {
8675   if (TARGET_SH4)
8676     {
8677       expand_df_binop (&gen_divdf3_i, operands);
8678       DONE;
8679     }
8680 }")
8681
8682 (define_insn "*divdf3_media"
8683   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8684         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8685                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8686   "TARGET_SHMEDIA_FPU"
8687   "fdiv.d       %1, %2, %0"
8688   [(set_attr "type" "dfdiv_media")])
8689
8690 (define_insn "divdf3_i"
8691   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8692         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8693                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8694    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8695   "TARGET_SH4"
8696   "fdiv %2,%0"
8697   [(set_attr "type" "dfdiv")
8698    (set_attr "fp_mode" "double")])
8699
8700 (define_insn "floatdidf2"
8701   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8702         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8703   "TARGET_SHMEDIA_FPU"
8704   "float.qd     %1, %0"
8705   [(set_attr "type" "dfpconv_media")])
8706
8707 (define_expand "floatsidf2"
8708   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8709         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
8710   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8711   "
8712 {
8713   if (TARGET_SH4)
8714     {
8715       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
8716                                       get_fpscr_rtx ()));
8717       DONE;
8718     }
8719 }")
8720
8721 (define_insn "*floatsidf2_media"
8722   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8723         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8724   "TARGET_SHMEDIA_FPU"
8725   "float.ld     %1, %0"
8726   [(set_attr "type" "dfpconv_media")])
8727
8728 (define_insn "floatsidf2_i"
8729   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8730         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
8731    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8732   "TARGET_SH4"
8733   "float        %1,%0"
8734   [(set_attr "type" "dfp_conv")
8735    (set_attr "fp_mode" "double")])
8736
8737 (define_insn "fix_truncdfdi2"
8738   [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8739         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8740   "TARGET_SHMEDIA_FPU"
8741   "ftrc.dq      %1, %0"
8742   [(set_attr "type" "dfpconv_media")])
8743
8744 (define_expand "fix_truncdfsi2"
8745   [(set (match_operand:SI 0 "fpul_operand" "")
8746         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8747   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8748   "
8749 {
8750   if (TARGET_SH4)
8751     {
8752       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
8753                                           get_fpscr_rtx ()));
8754       DONE;
8755     }
8756 }")
8757
8758 (define_insn "*fix_truncdfsi2_media"
8759   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8760         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8761   "TARGET_SHMEDIA_FPU"
8762   "ftrc.dl      %1, %0"
8763   [(set_attr "type" "dfpconv_media")])
8764
8765 (define_insn "fix_truncdfsi2_i"
8766   [(set (match_operand:SI 0 "fpul_operand" "=y")
8767         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8768    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8769   "TARGET_SH4"
8770   "ftrc %1,%0"
8771   [(set_attr "type" "dfp_conv")
8772    (set_attr "fp_mode" "double")])
8773
8774 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
8775 ;; fix_truncdfsi2_i.
8776 ;; (define_insn "fix_truncdfsi2_i4"
8777 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8778 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8779 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
8780 ;;    (clobber (reg:SI FPUL_REG))]
8781 ;;   "TARGET_SH4"
8782 ;;   "#"
8783 ;;   [(set_attr "length" "4")
8784 ;;    (set_attr "fp_mode" "double")])
8785 ;;
8786 ;; (define_split
8787 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8788 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8789 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
8790 ;;    (clobber (reg:SI FPUL_REG))]
8791 ;;   "TARGET_SH4"
8792 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8793 ;;            (use (match_dup 2))])
8794 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
8795
8796 (define_insn "cmpgtdf_t"
8797   [(set (reg:SI T_REG)
8798         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
8799                (match_operand:DF 1 "arith_reg_operand" "f")))
8800    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8801   "TARGET_SH4"
8802   "fcmp/gt      %1,%0"
8803   [(set_attr "type" "dfp_cmp")
8804    (set_attr "fp_mode" "double")])
8805
8806 (define_insn "cmpeqdf_t"
8807   [(set (reg:SI T_REG)
8808         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8809                (match_operand:DF 1 "arith_reg_operand" "f")))
8810    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8811   "TARGET_SH4"
8812   "fcmp/eq      %1,%0"
8813   [(set_attr "type" "dfp_cmp")
8814    (set_attr "fp_mode" "double")])
8815
8816 (define_insn "*ieee_ccmpeqdf_t"
8817   [(set (reg:SI T_REG)
8818         (ior:SI (reg:SI T_REG)
8819                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8820                        (match_operand:DF 1 "arith_reg_operand" "f"))))
8821    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8822   "TARGET_IEEE && TARGET_SH4"
8823   "* return output_ieee_ccmpeq (insn, operands);"
8824   [(set_attr "length" "4")
8825    (set_attr "fp_mode" "double")])
8826
8827 (define_insn "cmpeqdf_media"
8828   [(set (match_operand:DI 0 "register_operand" "=r")
8829         (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8830                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8831   "TARGET_SHMEDIA_FPU"
8832   "fcmpeq.d     %1,%2,%0"
8833   [(set_attr "type" "fcmp_media")])
8834
8835 (define_insn "cmpgtdf_media"
8836   [(set (match_operand:DI 0 "register_operand" "=r")
8837         (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8838                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8839   "TARGET_SHMEDIA_FPU"
8840   "fcmpgt.d     %1,%2,%0"
8841   [(set_attr "type" "fcmp_media")])
8842
8843 (define_insn "cmpgedf_media"
8844   [(set (match_operand:DI 0 "register_operand" "=r")
8845         (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8846                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8847   "TARGET_SHMEDIA_FPU"
8848   "fcmpge.d     %1,%2,%0"
8849   [(set_attr "type" "fcmp_media")])
8850
8851 (define_insn "cmpundf_media"
8852   [(set (match_operand:DI 0 "register_operand" "=r")
8853         (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8854                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8855   "TARGET_SHMEDIA_FPU"
8856   "fcmpun.d     %1,%2,%0"
8857   [(set_attr "type" "fcmp_media")])
8858
8859 (define_expand "cmpdf"
8860   [(set (reg:SI T_REG)
8861         (compare (match_operand:DF 0 "arith_operand" "")
8862                  (match_operand:DF 1 "arith_operand" "")))]
8863   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8864   "
8865 {
8866   sh_compare_op0 = operands[0];
8867   sh_compare_op1 = operands[1];
8868   DONE;
8869 }")
8870
8871 (define_expand "negdf2"
8872   [(set (match_operand:DF 0 "arith_reg_operand" "")
8873         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8874   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8875   "
8876 {
8877   if (TARGET_SH4)
8878     {
8879       expand_df_unop (&gen_negdf2_i, operands);
8880       DONE;
8881     }
8882 }")
8883
8884 (define_insn "*negdf2_media"
8885   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8886         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8887   "TARGET_SHMEDIA_FPU"
8888   "fneg.d       %1, %0"
8889   [(set_attr "type" "fmove_media")])
8890
8891 (define_insn "negdf2_i"
8892   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8893         (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8894    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8895   "TARGET_SH4"
8896   "fneg %0"
8897   [(set_attr "type" "fmove")
8898    (set_attr "fp_mode" "double")])
8899
8900 (define_expand "sqrtdf2"
8901   [(set (match_operand:DF 0 "arith_reg_operand" "")
8902         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8903   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8904   "
8905 {
8906   if (TARGET_SH4)
8907     {
8908       expand_df_unop (&gen_sqrtdf2_i, operands);
8909       DONE;
8910     }
8911 }")
8912
8913 (define_insn "*sqrtdf2_media"
8914   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8915         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8916   "TARGET_SHMEDIA_FPU"
8917   "fsqrt.d      %1, %0"
8918   [(set_attr "type" "dfdiv_media")])
8919
8920 (define_insn "sqrtdf2_i"
8921   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8922         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8923    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8924   "TARGET_SH4"
8925   "fsqrt        %0"
8926   [(set_attr "type" "dfdiv")
8927    (set_attr "fp_mode" "double")])
8928
8929 (define_expand "absdf2"
8930   [(set (match_operand:DF 0 "arith_reg_operand" "")
8931         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8932   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8933   "
8934 {
8935   if (TARGET_SH4)
8936     {
8937       expand_df_unop (&gen_absdf2_i, operands);
8938       DONE;
8939     }
8940 }")
8941
8942 (define_insn "*absdf2_media"
8943   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8944         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8945   "TARGET_SHMEDIA_FPU"
8946   "fabs.d       %1, %0"
8947   [(set_attr "type" "fmove_media")])
8948
8949 (define_insn "absdf2_i"
8950   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8951         (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8952    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8953   "TARGET_SH4"
8954   "fabs %0"
8955   [(set_attr "type" "fmove")
8956    (set_attr "fp_mode" "double")])
8957
8958 (define_expand "extendsfdf2"
8959   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8960         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
8961   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8962   "
8963 {
8964   if (TARGET_SH4)
8965     {
8966       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
8967                                         get_fpscr_rtx ()));
8968       DONE;
8969     }
8970 }")
8971
8972 (define_insn "*extendsfdf2_media"
8973   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8974         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8975   "TARGET_SHMEDIA_FPU"
8976   "fcnv.sd      %1, %0"
8977   [(set_attr "type" "dfpconv_media")])
8978
8979 (define_insn "extendsfdf2_i4"
8980   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8981         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
8982    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8983   "TARGET_SH4"
8984   "fcnvsd  %1,%0"
8985   [(set_attr "type" "fp")
8986    (set_attr "fp_mode" "double")])
8987
8988 (define_expand "truncdfsf2"
8989   [(set (match_operand:SF 0 "fpul_operand" "")
8990         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8991   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8992   "
8993 {
8994   if (TARGET_SH4)
8995     {
8996       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
8997                                        get_fpscr_rtx ()));
8998       DONE;
8999     }
9000 }")
9001
9002 (define_insn "*truncdfsf2_media"
9003   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9004         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9005   "TARGET_SHMEDIA_FPU"
9006   "fcnv.ds      %1, %0"
9007   [(set_attr "type" "dfpconv_media")])
9008
9009 (define_insn "truncdfsf2_i4"
9010   [(set (match_operand:SF 0 "fpul_operand" "=y")
9011         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
9012    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9013   "TARGET_SH4"
9014   "fcnvds  %1,%0"
9015   [(set_attr "type" "fp")
9016    (set_attr "fp_mode" "double")])
9017 \f
9018 ;; Bit field extract patterns.  These give better code for packed bitfields,
9019 ;; because they allow auto-increment addresses to be generated.
9020
9021 (define_expand "insv"
9022   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
9023                          (match_operand:SI 1 "immediate_operand" "")
9024                          (match_operand:SI 2 "immediate_operand" ""))
9025         (match_operand:SI 3 "general_operand" ""))]
9026   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
9027   "
9028 {
9029   rtx addr_target, orig_address, shift_reg, qi_val;
9030   HOST_WIDE_INT bitsize, size, v;
9031   rtx x = operands[3];
9032
9033   /* ??? expmed doesn't care for non-register predicates.  */
9034   if (! memory_operand (operands[0], VOIDmode)
9035       || ! immediate_operand (operands[1], VOIDmode)
9036       || ! immediate_operand (operands[2], VOIDmode)
9037       || ! general_operand (x, VOIDmode))
9038     FAIL;
9039   /* If this isn't a 16 / 24 / 32 bit field, or if
9040      it doesn't start on a byte boundary, then fail.  */
9041   bitsize = INTVAL (operands[1]);
9042   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
9043       || (INTVAL (operands[2]) % 8) != 0)
9044     FAIL;
9045
9046   size = bitsize / 8;
9047   orig_address = XEXP (operands[0], 0);
9048   shift_reg = gen_reg_rtx (SImode);
9049   if (GET_CODE (x) == CONST_INT)
9050     {
9051       v = INTVAL (x);
9052       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
9053     }
9054   else
9055     {
9056       emit_insn (gen_movsi (shift_reg, operands[3]));
9057       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9058     }
9059   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
9060
9061   operands[0] = replace_equiv_address (operands[0], addr_target);
9062   emit_insn (gen_movqi (operands[0], qi_val));
9063
9064   while (size -= 1)
9065     {
9066       if (GET_CODE (x) == CONST_INT)
9067         qi_val
9068           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
9069       else
9070         {
9071           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
9072           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9073         }
9074       emit_insn (gen_addsi3 (addr_target, addr_target, GEN_INT (-1)));
9075       emit_insn (gen_movqi (operands[0], qi_val));
9076     }
9077
9078   DONE;
9079 }")
9080 \f
9081 ;; -------------------------------------------------------------------------
9082 ;; Peepholes
9083 ;; -------------------------------------------------------------------------
9084
9085 ;; This matches cases where a stack pointer increment at the start of the
9086 ;; epilogue combines with a stack slot read loading the return value.
9087
9088 (define_peephole
9089   [(set (match_operand:SI 0 "arith_reg_operand" "")
9090         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
9091    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9092   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
9093   "mov.l        @%1+,%0")
9094
9095 ;; See the comment on the dt combiner pattern above.
9096
9097 (define_peephole
9098   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9099         (plus:SI (match_dup 0)
9100                  (const_int -1)))
9101    (set (reg:SI T_REG)
9102         (eq:SI (match_dup 0)
9103                (const_int 0)))]
9104   "TARGET_SH2"
9105   "dt   %0")
9106
9107 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
9108 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
9109 ;; reload when the constant is too large for a reg+offset address.
9110
9111 ;; ??? We would get much better code if this was done in reload.  This would
9112 ;; require modifying find_reloads_address to recognize that if the constant
9113 ;; is out-of-range for an immediate add, then we get better code by reloading
9114 ;; the constant into a register than by reloading the sum into a register,
9115 ;; since the former is one instruction shorter if the address does not need
9116 ;; to be offsettable.  Unfortunately this does not work, because there is
9117 ;; only one register, r0, that can be used as an index register.  This register
9118 ;; is also the function return value register.  So, if we try to force reload
9119 ;; to use double-reg addresses, then we end up with some instructions that
9120 ;; need to use r0 twice.  The only way to fix this is to change the calling
9121 ;; convention so that r0 is not used to return values.
9122
9123 (define_peephole
9124   [(set (match_operand:SI 0 "register_operand" "=r")
9125         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9126    (set (mem:SI (match_dup 0))
9127         (match_operand:SI 2 "general_movsrc_operand" ""))]
9128   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9129   "mov.l        %2,@(%0,%1)")
9130
9131 (define_peephole
9132   [(set (match_operand:SI 0 "register_operand" "=r")
9133         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9134    (set (match_operand:SI 2 "general_movdst_operand" "")
9135         (mem:SI (match_dup 0)))]
9136   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9137   "mov.l        @(%0,%1),%2")
9138
9139 (define_peephole
9140   [(set (match_operand:SI 0 "register_operand" "=r")
9141         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9142    (set (mem:HI (match_dup 0))
9143         (match_operand:HI 2 "general_movsrc_operand" ""))]
9144   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9145   "mov.w        %2,@(%0,%1)")
9146
9147 (define_peephole
9148   [(set (match_operand:SI 0 "register_operand" "=r")
9149         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9150    (set (match_operand:HI 2 "general_movdst_operand" "")
9151         (mem:HI (match_dup 0)))]
9152   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9153   "mov.w        @(%0,%1),%2")
9154
9155 (define_peephole
9156   [(set (match_operand:SI 0 "register_operand" "=r")
9157         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9158    (set (mem:QI (match_dup 0))
9159         (match_operand:QI 2 "general_movsrc_operand" ""))]
9160   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9161   "mov.b        %2,@(%0,%1)")
9162
9163 (define_peephole
9164   [(set (match_operand:SI 0 "register_operand" "=r")
9165         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9166    (set (match_operand:QI 2 "general_movdst_operand" "")
9167         (mem:QI (match_dup 0)))]
9168   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9169   "mov.b        @(%0,%1),%2")
9170
9171 (define_peephole
9172   [(set (match_operand:SI 0 "register_operand" "=r")
9173         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9174    (set (mem:SF (match_dup 0))
9175         (match_operand:SF 2 "general_movsrc_operand" ""))]
9176   "TARGET_SH1 && REGNO (operands[0]) == 0
9177    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9178        || (GET_CODE (operands[2]) == SUBREG
9179            && REGNO (SUBREG_REG (operands[2])) < 16))
9180    && reg_unused_after (operands[0], insn)"
9181   "mov.l        %2,@(%0,%1)")
9182
9183 (define_peephole
9184   [(set (match_operand:SI 0 "register_operand" "=r")
9185         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9186    (set (match_operand:SF 2 "general_movdst_operand" "")
9187
9188         (mem:SF (match_dup 0)))]
9189   "TARGET_SH1 && REGNO (operands[0]) == 0
9190    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9191        || (GET_CODE (operands[2]) == SUBREG
9192            && REGNO (SUBREG_REG (operands[2])) < 16))
9193    && reg_unused_after (operands[0], insn)"
9194   "mov.l        @(%0,%1),%2")
9195
9196 (define_peephole
9197   [(set (match_operand:SI 0 "register_operand" "=r")
9198         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9199    (set (mem:SF (match_dup 0))
9200         (match_operand:SF 2 "general_movsrc_operand" ""))]
9201   "TARGET_SH3E && REGNO (operands[0]) == 0
9202    && ((GET_CODE (operands[2]) == REG
9203         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9204        || (GET_CODE (operands[2]) == SUBREG
9205            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9206    && reg_unused_after (operands[0], insn)"
9207   "fmov{.s|}    %2,@(%0,%1)")
9208
9209 (define_peephole
9210   [(set (match_operand:SI 0 "register_operand" "=r")
9211         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9212    (set (match_operand:SF 2 "general_movdst_operand" "")
9213
9214         (mem:SF (match_dup 0)))]
9215   "TARGET_SH3E && REGNO (operands[0]) == 0
9216    && ((GET_CODE (operands[2]) == REG
9217         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9218        || (GET_CODE (operands[2]) == SUBREG
9219            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9220    && reg_unused_after (operands[0], insn)"
9221   "fmov{.s|}    @(%0,%1),%2")
9222
9223 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
9224 (define_insn "sp_switch_1"
9225   [(const_int 1)]
9226   "TARGET_SH1"
9227   "*
9228 {
9229   rtx xoperands[1];
9230
9231   xoperands[0] = sp_switch;
9232   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9233   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9234   return \"mov r0,r15\";
9235 }"
9236   [(set_attr "length" "10")])
9237
9238 ;; Switch back to the original stack for interrupt functions with the
9239 ;; sp_switch attribute.  */
9240 (define_insn "sp_switch_2"
9241   [(const_int 2)]
9242   "TARGET_SH1"
9243   "mov.l @r15+,r15\;mov.l @r15+,r0"
9244   [(set_attr "length" "4")])
9245
9246 ;; Integer vector moves
9247
9248 (define_expand "movv8qi"
9249   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9250         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9251   "TARGET_SHMEDIA"
9252   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9253
9254 (define_insn "movv8qi_i"
9255   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
9256         (match_operand:V8QI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
9257   "TARGET_SHMEDIA
9258    && (register_operand (operands[0], V8QImode)
9259        || register_operand (operands[1], V8QImode))"
9260   "@
9261         add     %1, r63, %0
9262         movi    %1, %0
9263         #
9264         ld%M1.q %m1, %0
9265         st%M0.q %m0, %1"
9266   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9267    (set_attr "length" "4,4,16,4,4")])
9268
9269 (define_split
9270   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9271         (subreg:V8QI (const_int 0) 0))]
9272   "TARGET_SHMEDIA"
9273   [(set (match_dup 0)
9274         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9275                             (const_int 0) (const_int 0) (const_int 0)
9276                             (const_int 0) (const_int 0)]))])
9277
9278 (define_split
9279   [(set (match_operand 0 "arith_reg_dest" "")
9280         (match_operand 1 "sh_rep_vec" ""))]
9281   "TARGET_SHMEDIA && reload_completed
9282    && GET_MODE (operands[0]) == GET_MODE (operands[1])
9283    && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9284    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9285    && (XVECEXP (operands[1], 0, 0) != const0_rtx
9286        || XVECEXP (operands[1], 0, 1) != const0_rtx)"
9287   [(set (match_dup 0) (match_dup 1))
9288    (match_dup 2)]
9289   "
9290 {
9291   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9292   rtx elt1 = XVECEXP (operands[1], 0, 1);
9293
9294   if (unit_size > 2)
9295     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9296   else
9297     operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9298   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9299   operands[1] = XVECEXP (operands[1], 0, 0);
9300   if (unit_size < 2)
9301     {
9302       if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
9303         operands[1] = GEN_INT (TARGET_LITTLE_ENDIAN
9304                                ? INTVAL (operands[1]) + (INTVAL (elt1) << 8)
9305                                : (INTVAL (operands[1]) << 8) + INTVAL (elt1));
9306       else
9307         {
9308           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9309           operands[1]
9310             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9311         }
9312     }
9313 }")
9314
9315 (define_split
9316   [(set (match_operand 0 "arith_reg_dest" "")
9317         (match_operand 1 "sh_const_vec" ""))]
9318   "TARGET_SHMEDIA && reload_completed
9319    && GET_MODE (operands[0]) == GET_MODE (operands[1])
9320    && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9321    && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
9322   [(set (match_dup 0) (match_dup 1))]
9323   "
9324 {
9325   rtx v = operands[1];
9326   enum machine_mode new_mode
9327     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9328
9329   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9330   operands[1]
9331     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
9332 }")
9333
9334 (define_expand "movv2hi"
9335   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9336         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9337   "TARGET_SHMEDIA"
9338   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9339
9340 (define_insn "movv2hi_i"
9341   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9342         (match_operand:V2HI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
9343   "TARGET_SHMEDIA
9344    && (register_operand (operands[0], V2HImode)
9345        || register_operand (operands[1], V2HImode))"
9346   "@
9347         addz.l  %1, r63, %0
9348         movi    %1, %0
9349         #
9350         ld%M1.l %m1, %0
9351         st%M0.l %m0, %1"
9352   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9353    (set_attr "length" "4,4,16,4,4")])
9354
9355 (define_expand "movv4hi"
9356   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9357         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9358   "TARGET_SHMEDIA"
9359   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9360
9361 (define_insn "movv4hi_i"
9362   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9363         (match_operand:V4HI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
9364   "TARGET_SHMEDIA
9365    && (register_operand (operands[0], V4HImode)
9366        || register_operand (operands[1], V4HImode))"
9367   "@
9368         add     %1, r63, %0
9369         movi    %1, %0
9370         #
9371         ld%M1.q %m1, %0
9372         st%M0.q %m0, %1"
9373   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9374    (set_attr "length" "4,4,16,4,4")])
9375
9376 (define_expand "movv2si"
9377   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9378         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9379   "TARGET_SHMEDIA"
9380   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9381
9382 (define_insn "movv2si_i"
9383   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
9384         (match_operand:V2SI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
9385   "TARGET_SHMEDIA
9386    && (register_operand (operands[0], V2SImode)
9387        || register_operand (operands[1], V2SImode))"
9388   "@
9389         add     %1, r63, %0
9390         #
9391         #
9392         ld%M1.q %m1, %0
9393         st%M0.q %m0, %1"
9394   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9395    (set_attr "length" "4,4,16,4,4")])
9396
9397 ;; Multimedia Intrinsics
9398
9399 (define_insn "absv2si2"
9400   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9401         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9402   "TARGET_SHMEDIA"
9403   "mabs.l       %1, %0"
9404   [(set_attr "type" "mcmp_media")])
9405
9406 (define_insn "absv4hi2"
9407   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9408         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9409   "TARGET_SHMEDIA"
9410   "mabs.w       %1, %0"
9411   [(set_attr "type" "mcmp_media")])
9412
9413 (define_insn "addv2si3"
9414   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9415         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9416                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9417   "TARGET_SHMEDIA"
9418   "madd.l       %1, %2, %0"
9419   [(set_attr "type" "arith_media")])
9420
9421 (define_insn "addv4hi3"
9422   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9423         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9424                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9425   "TARGET_SHMEDIA"
9426   "madd.w       %1, %2, %0"
9427   [(set_attr "type" "arith_media")])
9428
9429 (define_insn "ssaddv2si3"
9430   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9431         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9432                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9433   "TARGET_SHMEDIA"
9434   "madds.l      %1, %2, %0"
9435   [(set_attr "type" "mcmp_media")])
9436
9437 (define_insn "usaddv8qi3"
9438   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9439         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9440                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9441   "TARGET_SHMEDIA"
9442   "madds.ub     %1, %2, %0"
9443   [(set_attr "type" "mcmp_media")])
9444
9445 (define_insn "ssaddv4hi3"
9446   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9447         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9448                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9449   "TARGET_SHMEDIA"
9450   "madds.w      %1, %2, %0"
9451   [(set_attr "type" "mcmp_media")])
9452
9453 (define_insn "negcmpeqv8qi"
9454   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9455         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rU")
9456                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))))]
9457   "TARGET_SHMEDIA"
9458   "mcmpeq.b     %N1, %N2, %0"
9459   [(set_attr "type" "mcmp_media")])
9460
9461 (define_insn "negcmpeqv2si"
9462   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9463         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rU")
9464                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9465   "TARGET_SHMEDIA"
9466   "mcmpeq.l     %N1, %N2, %0"
9467   [(set_attr "type" "mcmp_media")])
9468
9469 (define_insn "negcmpeqv4hi"
9470   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9471         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rU")
9472                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9473   "TARGET_SHMEDIA"
9474   "mcmpeq.w     %N1, %N2, %0"
9475   [(set_attr "type" "mcmp_media")])
9476
9477 (define_insn "negcmpgtuv8qi"
9478   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9479         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rU")
9480                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))))]
9481   "TARGET_SHMEDIA"
9482   "mcmpgt.ub    %N1, %N2, %0"
9483   [(set_attr "type" "mcmp_media")])
9484
9485 (define_insn "negcmpgtv2si"
9486   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9487         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rU")
9488                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9489   "TARGET_SHMEDIA"
9490   "mcmpgt.l     %N1, %N2, %0"
9491   [(set_attr "type" "mcmp_media")])
9492
9493 (define_insn "negcmpgtv4hi"
9494   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9495         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rU")
9496                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9497   "TARGET_SHMEDIA"
9498   "mcmpgt.w     %N1, %N2, %0"
9499   [(set_attr "type" "mcmp_media")])
9500
9501 (define_insn "mcmv"
9502   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9503         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9504                         (match_operand:DI 2 "arith_reg_operand" "r"))
9505                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9506                         (not:DI (match_dup 2)))))]
9507   "TARGET_SHMEDIA"
9508   "mcmv %N1, %2, %0"
9509   [(set_attr "type" "arith_media")])
9510
9511 (define_insn "mcnvs_lw"
9512   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9513         (vec_concat:V4HI
9514          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU"))
9515          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9516   "TARGET_SHMEDIA"
9517   "mcnvs.lw     %N1, %N2, %0"
9518   [(set_attr "type" "mcmp_media")])
9519
9520 (define_insn "mcnvs_wb"
9521   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9522         (vec_concat:V8QI
9523          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU"))
9524          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9525   "TARGET_SHMEDIA"
9526   "mcnvs.wb     %N1, %N2, %0"
9527   [(set_attr "type" "mcmp_media")])
9528
9529 (define_insn "mcnvs_wub"
9530   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9531         (vec_concat:V8QI
9532          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU"))
9533          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9534   "TARGET_SHMEDIA"
9535   "mcnvs.wub    %N1, %N2, %0"
9536   [(set_attr "type" "mcmp_media")])
9537
9538 (define_insn "mextr_rl"
9539   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9540         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9541                              (match_operand:HI 3 "mextr_bit_offset" "i"))
9542                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9543                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9544   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9545   "*
9546 {
9547   static char templ[16];
9548
9549   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9550            (int) INTVAL (operands[3]) >> 3);
9551   return templ;
9552 }"
9553   [(set_attr "type" "arith_media")])
9554
9555 (define_insn "*mextr_lr"
9556   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9557         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9558                            (match_operand:HI 3 "mextr_bit_offset" "i"))
9559                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9560                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9561   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9562   "*
9563 {
9564   static char templ[16];
9565
9566   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9567            (int) INTVAL (operands[4]) >> 3);
9568   return templ;
9569 }"
9570   [(set_attr "type" "arith_media")])
9571
9572 ; mextrN can be modelled with vec_select / vec_concat, but the selection
9573 ; vector then varies depending on endianness.
9574 (define_expand "mextr1"
9575   [(match_operand:DI 0 "arith_reg_dest" "")
9576    (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9577    (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9578   "TARGET_SHMEDIA"
9579   "
9580 {
9581   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9582                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
9583   DONE;
9584 }")
9585
9586 (define_expand "mextr2"
9587   [(match_operand:DI 0 "arith_reg_dest" "")
9588    (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9589    (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9590   "TARGET_SHMEDIA"
9591   "
9592 {
9593   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9594                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
9595   DONE;
9596 }")
9597
9598 (define_expand "mextr3"
9599   [(match_operand:DI 0 "arith_reg_dest" "")
9600    (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9601    (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9602   "TARGET_SHMEDIA"
9603   "
9604 {
9605   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9606                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
9607   DONE;
9608 }")
9609
9610 (define_expand "mextr4"
9611   [(match_operand:DI 0 "arith_reg_dest" "")
9612    (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9613    (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9614   "TARGET_SHMEDIA"
9615   "
9616 {
9617   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9618                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
9619   DONE;
9620 }")
9621
9622 (define_expand "mextr5"
9623   [(match_operand:DI 0 "arith_reg_dest" "")
9624    (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9625    (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9626   "TARGET_SHMEDIA"
9627   "
9628 {
9629   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9630                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
9631   DONE;
9632 }")
9633
9634 (define_expand "mextr6"
9635   [(match_operand:DI 0 "arith_reg_dest" "")
9636    (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9637    (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9638   "TARGET_SHMEDIA"
9639   "
9640 {
9641   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9642                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
9643   DONE;
9644 }")
9645
9646 (define_expand "mextr7"
9647   [(match_operand:DI 0 "arith_reg_dest" "")
9648    (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9649    (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9650   "TARGET_SHMEDIA"
9651   "
9652 {
9653   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9654                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
9655   DONE;
9656 }")
9657
9658 (define_expand "mmacfx_wl"
9659   [(match_operand:V2SI 0 "arith_reg_dest" "")
9660    (match_operand:V2HI 1 "extend_reg_operand" "")
9661    (match_operand:V2HI 2 "extend_reg_operand" "")
9662    (match_operand:V2SI 3 "arith_reg_operand" "")]
9663   "TARGET_SHMEDIA"
9664   "
9665 {
9666   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
9667                               operands[1], operands[2]));
9668   DONE;
9669 }")
9670
9671 (define_insn "mmacfx_wl_i"
9672   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9673         (ss_plus:V2SI
9674          (match_operand:V2SI 1 "arith_reg_operand" "0")
9675          (ss_truncate:V2SI
9676           (ashift:V2DI
9677            (sign_extend:V2DI
9678             (mult:V2SI
9679              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9680              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9681            (const_int 1)))))]
9682   "TARGET_SHMEDIA"
9683   "mmacfx.wl    %2, %3, %0"
9684   [(set_attr "type" "mac_media")])
9685
9686 (define_expand "mmacnfx_wl"
9687   [(match_operand:V2SI 0 "arith_reg_dest" "")
9688    (match_operand:V2HI 1 "extend_reg_operand" "")
9689    (match_operand:V2HI 2 "extend_reg_operand" "")
9690    (match_operand:V2SI 3 "arith_reg_operand" "")]
9691   "TARGET_SHMEDIA"
9692   "
9693 {
9694   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
9695                                operands[1], operands[2]));
9696   DONE;
9697 }")
9698
9699 (define_insn "mmacnfx_wl_i"
9700   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9701         (ss_minus:V2SI
9702          (match_operand:V2SI 1 "arith_reg_operand" "0")
9703          (ss_truncate:V2SI
9704           (ashift:V2DI
9705            (sign_extend:V2DI
9706             (mult:V2SI
9707              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9708              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9709            (const_int 1)))))]
9710   "TARGET_SHMEDIA"
9711   "mmacnfx.wl   %2, %3, %0"
9712   [(set_attr "type" "mac_media")])
9713
9714 (define_insn "mulv2si3"
9715   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9716         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9717                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9718   "TARGET_SHMEDIA"
9719   "mmul.l       %1, %2, %0"
9720   [(set_attr "type" "d2mpy_media")])
9721
9722 (define_insn "mulv4hi3"
9723   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9724         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9725                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9726   "TARGET_SHMEDIA"
9727   "mmul.w       %1, %2, %0"
9728   [(set_attr "type" "dmpy_media")])
9729
9730 (define_insn "mmulfx_l"
9731   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9732         (ss_truncate:V2SI
9733          (ashiftrt:V2DI
9734           (mult:V2DI
9735            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9736            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
9737           (const_int 31))))]
9738   "TARGET_SHMEDIA"
9739   "mmulfx.l     %1, %2, %0"
9740   [(set_attr "type" "d2mpy_media")])
9741
9742 (define_insn "mmulfx_w"
9743   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9744         (ss_truncate:V4HI
9745          (ashiftrt:V4SI
9746           (mult:V4SI
9747            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9748            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9749           (const_int 15))))]
9750   "TARGET_SHMEDIA"
9751   "mmulfx.w     %1, %2, %0"
9752   [(set_attr "type" "dmpy_media")])
9753
9754 (define_insn "mmulfxrp_w"
9755   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9756         (ss_truncate:V4HI
9757          (ashiftrt:V4SI
9758           (plus:V4SI
9759            (mult:V4SI
9760             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9761             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9762            (const_int 16384))
9763           (const_int 15))))]
9764   "TARGET_SHMEDIA"
9765   "mmulfxrp.w   %1, %2, %0"
9766   [(set_attr "type" "dmpy_media")])
9767
9768 (define_expand "mmulhi_wl"
9769   [(match_operand:V2SI 0 "arith_reg_dest" "")
9770    (match_operand:V4HI 1 "arith_reg_operand" "")
9771    (match_operand:V4HI 2 "arith_reg_operand" "")]
9772   "TARGET_SHMEDIA"
9773   "
9774 {
9775   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
9776              (operands[0], operands[1], operands[2]));
9777   DONE;
9778 }")
9779
9780 (define_expand "mmullo_wl"
9781   [(match_operand:V2SI 0 "arith_reg_dest" "")
9782    (match_operand:V4HI 1 "arith_reg_operand" "")
9783    (match_operand:V4HI 2 "arith_reg_operand" "")]
9784   "TARGET_SHMEDIA"
9785   "
9786 {
9787   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
9788              (operands[0], operands[1], operands[2]));
9789   DONE;
9790 }")
9791
9792 (define_insn "mmul23_wl"
9793   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9794         (vec_select:V2SI
9795          (mult:V4SI
9796           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9797           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9798          (parallel [(const_int 2) (const_int 3)])))]
9799   "TARGET_SHMEDIA"
9800   "* return (TARGET_LITTLE_ENDIAN
9801              ? \"mmulhi.wl      %1, %2, %0\"
9802              : \"mmullo.wl      %1, %2, %0\");"
9803   [(set_attr "type" "dmpy_media")])
9804
9805 (define_insn "mmul01_wl"
9806   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9807         (vec_select:V2SI
9808          (mult:V4SI
9809           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9810           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9811          (parallel [(const_int 0) (const_int 1)])))]
9812   "TARGET_SHMEDIA"
9813   "* return (TARGET_LITTLE_ENDIAN
9814              ? \"mmullo.wl      %1, %2, %0\"
9815              : \"mmulhi.wl      %1, %2, %0\");"
9816   [(set_attr "type" "dmpy_media")])
9817
9818 (define_expand "mmulsum_wq"
9819   [(match_operand:DI 0 "arith_reg_dest" "")
9820    (match_operand:V4HI 1 "arith_reg_operand" "")
9821    (match_operand:V4HI 2 "arith_reg_operand" "")
9822    (match_operand:DI 3 "arith_reg_operand" "")]
9823   "TARGET_SHMEDIA"
9824   "
9825 {
9826   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
9827                                operands[1], operands[2]));
9828   DONE;
9829 }")
9830
9831 (define_insn "mmulsum_wq_i"
9832   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9833         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
9834          (plus:DI
9835           (plus:DI
9836            (vec_select:DI
9837             (mult:V4DI
9838              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
9839              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
9840             (parallel [(const_int 0)]))
9841            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9842                                      (sign_extend:V4DI (match_dup 3)))
9843                           (parallel [(const_int 1)])))
9844           (plus:DI
9845            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9846                                      (sign_extend:V4DI (match_dup 3)))
9847                           (parallel [(const_int 2)]))
9848            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9849                                      (sign_extend:V4DI (match_dup 3)))
9850                           (parallel [(const_int 3)]))))))]
9851   "TARGET_SHMEDIA"
9852   "mmulsum.wq   %2, %3, %0"
9853   [(set_attr "type" "mac_media")])
9854
9855 (define_expand "mperm_w"
9856   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
9857    (match_operand:V4HI 1 "arith_reg_operand" "r")
9858    (match_operand:QI 2 "extend_reg_or_0_operand" "rU")]
9859   "TARGET_SHMEDIA"
9860   "
9861 {
9862   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
9863              (operands[0], operands[1], operands[2]));
9864 }")
9865
9866 ; This use of vec_select isn't exactly correct according to rtl.texi
9867 ; (because not constant), but it seems a straightforward extension.
9868 (define_insn "mperm_w_little"
9869   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9870         (vec_select:V4HI
9871          (match_operand:V4HI 1 "arith_reg_operand" "r")
9872          (parallel
9873           [(zero_extract (match_operand:QI 2 "extend_reg_or_0_operand" "rU")
9874                          (const_int 2) (const_int 0))
9875            (zero_extract (match_dup 2) (const_int 2) (const_int 2))
9876            (zero_extract (match_dup 2) (const_int 2) (const_int 4))
9877            (zero_extract (match_dup 2) (const_int 2) (const_int 6))])))]
9878   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
9879   "mperm.w      %1, %N2, %0"
9880   [(set_attr "type" "arith_media")])
9881
9882 (define_insn "mperm_w_big"
9883   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9884         (vec_select:V4HI
9885          (match_operand:V4HI 1 "arith_reg_operand" "r")
9886          (parallel
9887           [(zero_extract (not:QI (match_operand:QI 2
9888                                   "extend_reg_or_0_operand" "rU"))
9889                          (const_int 2) (const_int 0))
9890            (zero_extract (not:QI (match_dup 2)) (const_int 2) (const_int 2))
9891            (zero_extract (not:QI (match_dup 2)) (const_int 2) (const_int 4))
9892            (zero_extract (not:QI (match_dup 2)) (const_int 2) (const_int 6))])))]
9893   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
9894   "mperm.w      %1, %N2, %0"
9895   [(set_attr "type" "arith_media")])
9896
9897 (define_insn "mperm_w0"
9898   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9899         (vec_duplicate:V4HI (truncate:HI (match_operand 1
9900                                           "trunc_hi_operand" "r"))))]
9901   "TARGET_SHMEDIA"
9902   "mperm.w      %1, r63, %0"
9903   [(set_attr "type" "arith_media")])
9904
9905 (define_expand "msad_ubq"
9906   [(match_operand:DI 0 "arith_reg_dest" "")
9907    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
9908    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
9909    (match_operand:DI 3 "arith_reg_operand" "")]
9910   "TARGET_SHMEDIA"
9911   "
9912 {
9913   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
9914                              operands[1], operands[2]));
9915   DONE;
9916 }")
9917
9918 (define_insn "msad_ubq_i"
9919   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9920         (plus:DI
9921          (plus:DI
9922           (plus:DI
9923            (plus:DI
9924             (match_operand:DI 1 "arith_reg_operand" "0")
9925             (abs:DI (vec_select:DI
9926                      (minus:V8DI
9927                       (zero_extend:V8DI
9928                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "r"))
9929                       (zero_extend:V8DI
9930                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "r")))
9931                      (parallel [(const_int 0)]))))
9932            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9933                                               (zero_extend:V8DI (match_dup 3)))
9934                                   (parallel [(const_int 1)]))))
9935           (plus:DI
9936            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9937                                               (zero_extend:V8DI (match_dup 3)))
9938                                   (parallel [(const_int 2)])))
9939            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9940                                               (zero_extend:V8DI (match_dup 3)))
9941                                   (parallel [(const_int 3)])))))
9942          (plus:DI
9943           (plus:DI
9944            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9945                                               (zero_extend:V8DI (match_dup 3)))
9946                                   (parallel [(const_int 4)])))
9947            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9948                                               (zero_extend:V8DI (match_dup 3)))
9949                                   (parallel [(const_int 5)]))))
9950           (plus:DI
9951            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9952                                               (zero_extend:V8DI (match_dup 3)))
9953                                   (parallel [(const_int 6)])))
9954            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9955                                               (zero_extend:V8DI (match_dup 3)))
9956                                   (parallel [(const_int 7)])))))))]
9957   "TARGET_SHMEDIA"
9958   "msad.ubq     %N2, %N3, %0"
9959   [(set_attr "type" "mac_media")])
9960
9961 (define_insn "mshalds_l"
9962   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9963         (ss_truncate:V2SI
9964          (ashift:V2DI
9965           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9966           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
9967                   (const_int 31)))))]
9968   "TARGET_SHMEDIA"
9969   "mshalds.l    %1, %2, %0"
9970   [(set_attr "type" "mcmp_media")])
9971
9972 (define_insn "mshalds_w"
9973   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9974         (ss_truncate:V4HI
9975          (ashift:V4SI
9976           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9977           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
9978                   (const_int 15)))))]
9979   "TARGET_SHMEDIA"
9980   "mshalds.w    %1, %2, %0"
9981   [(set_attr "type" "mcmp_media")])
9982
9983 (define_insn "ashrv2si3"
9984   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9985         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9986                        (match_operand:DI 2 "arith_reg_operand" "r")))]
9987   "TARGET_SHMEDIA"
9988   "mshard.l     %1, %2, %0"
9989   [(set_attr "type" "arith_media")])
9990
9991 (define_insn "ashrv4hi3"
9992   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9993         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9994                        (match_operand:DI 2 "arith_reg_operand" "r")))]
9995   "TARGET_SHMEDIA"
9996   "mshard.w     %1, %2, %0"
9997   [(set_attr "type" "arith_media")])
9998
9999 (define_insn "mshards_q"
10000   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
10001         (ss_truncate:HI
10002          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
10003                       (match_operand:DI 2 "arith_reg_or_0_operand" "rU"))))]
10004   "TARGET_SHMEDIA"
10005   "mshards.q    %1, %N2, %0"
10006   [(set_attr "type" "mcmp_media")])
10007
10008 (define_expand "mshfhi_b"
10009   [(match_operand:V8QI 0 "arith_reg_dest" "")
10010    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
10011    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
10012   "TARGET_SHMEDIA"
10013   "
10014 {
10015   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
10016              (operands[0], operands[1], operands[2]));
10017   DONE;
10018 }")
10019
10020 (define_expand "mshflo_b"
10021   [(match_operand:V8QI 0 "arith_reg_dest" "")
10022    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
10023    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
10024   "TARGET_SHMEDIA"
10025   "
10026 {
10027   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
10028              (operands[0], operands[1], operands[2]));
10029   DONE;
10030 }")
10031
10032 (define_insn "mshf4_b"
10033   [(set
10034     (match_operand:V8QI 0 "arith_reg_dest" "=r")
10035     (vec_select:V8QI
10036      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
10037                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))
10038      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
10039                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
10040   "TARGET_SHMEDIA"
10041   "* return (TARGET_LITTLE_ENDIAN
10042              ? \"mshfhi.b       %N1, %N2, %0\"
10043              : \"mshflo.b       %N1, %N2, %0\");"
10044   [(set_attr "type" "arith_media")])
10045
10046 (define_insn "mshf0_b"
10047   [(set
10048     (match_operand:V8QI 0 "arith_reg_dest" "=r")
10049     (vec_select:V8QI
10050      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
10051                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))
10052      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
10053                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
10054   "TARGET_SHMEDIA"
10055   "* return (TARGET_LITTLE_ENDIAN
10056              ? \"mshflo.b       %N1, %N2, %0\"
10057              : \"mshfhi.b       %N1, %N2, %0\");"
10058   [(set_attr "type" "arith_media")])
10059
10060 (define_expand "mshfhi_l"
10061   [(match_operand:V2SI 0 "arith_reg_dest" "")
10062    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10063    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU")]
10064   "TARGET_SHMEDIA"
10065   "
10066 {
10067   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
10068              (operands[0], operands[1], operands[2]));
10069   DONE;
10070 }")
10071
10072 (define_expand "mshflo_l"
10073   [(match_operand:V2SI 0 "arith_reg_dest" "")
10074    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10075    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU")]
10076   "TARGET_SHMEDIA"
10077   "
10078 {
10079   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
10080              (operands[0], operands[1], operands[2]));
10081   DONE;
10082 }")
10083
10084 (define_insn "mshf4_l"
10085   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10086         (vec_select:V2SI
10087          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10088                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))
10089          (parallel [(const_int 1) (const_int 3)])))]
10090   "TARGET_SHMEDIA"
10091   "* return (TARGET_LITTLE_ENDIAN
10092              ? \"mshfhi.l       %N1, %N2, %0\"
10093              : \"mshflo.l       %N1, %N2, %0\");"
10094   [(set_attr "type" "arith_media")])
10095
10096 (define_insn "mshf0_l"
10097   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10098         (vec_select:V2SI
10099          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10100                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))
10101          (parallel [(const_int 0) (const_int 2)])))]
10102   "TARGET_SHMEDIA"
10103   "* return (TARGET_LITTLE_ENDIAN
10104              ? \"mshflo.l       %N1, %N2, %0\"
10105              : \"mshfhi.l       %N1, %N2, %0\");"
10106   [(set_attr "type" "arith_media")])
10107
10108 (define_expand "mshfhi_w"
10109   [(match_operand:V4HI 0 "arith_reg_dest" "")
10110    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10111    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU")]
10112   "TARGET_SHMEDIA"
10113   "
10114 {
10115   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
10116              (operands[0], operands[1], operands[2]));
10117   DONE;
10118 }")
10119
10120 (define_expand "mshflo_w"
10121   [(match_operand:V4HI 0 "arith_reg_dest" "")
10122    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10123    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU")]
10124   "TARGET_SHMEDIA"
10125   "
10126 {
10127   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
10128              (operands[0], operands[1], operands[2]));
10129   DONE;
10130 }")
10131
10132 (define_insn "mshf4_w"
10133   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10134         (vec_select:V4HI
10135          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10136                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))
10137          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
10138   "TARGET_SHMEDIA"
10139   "* return (TARGET_LITTLE_ENDIAN
10140              ? \"mshfhi.w       %N1, %N2, %0\"
10141              : \"mshflo.w       %N1, %N2, %0\");"
10142   [(set_attr "type" "arith_media")])
10143
10144 (define_insn "mshf0_w"
10145   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10146         (vec_select:V4HI
10147          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10148                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))
10149          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
10150   "TARGET_SHMEDIA"
10151   "* return (TARGET_LITTLE_ENDIAN
10152              ? \"mshflo.w       %N1, %N2, %0\"
10153              : \"mshfhi.w       %N1, %N2, %0\");"
10154   [(set_attr "type" "arith_media")])
10155
10156 (define_insn "mshflo_w_x"
10157   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10158         (vec_select:V4HI
10159          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rU")
10160                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rU"))
10161          (parallel [(const_int 0) (const_int 2) (const_int 1) (const_int 3)])))]
10162   "TARGET_SHMEDIA"
10163   "mshflo.w     %N1, %N2, %0"
10164   [(set_attr "type" "arith_media")])
10165
10166 /* These are useful to expand ANDs and as combiner patterns.  */
10167 (define_insn_and_split "mshfhi_l_di"
10168   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
10169         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU,f")
10170                              (const_int 32))
10171                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU,?f")
10172                         (const_int -4294967296))))]
10173   "TARGET_SHMEDIA"
10174   "@
10175         mshfhi.l        %N1, %N2, %0
10176         #"
10177   "TARGET_SHMEDIA && reload_completed
10178    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10179   [(set (match_dup 3) (match_dup 4))
10180    (set (match_dup 5) (match_dup 6))]
10181   "
10182 {
10183   operands[3] = gen_lowpart (SImode, operands[0]);
10184   operands[4] = gen_highpart (SImode, operands[1]);
10185   operands[5] = gen_highpart (SImode, operands[0]);
10186   operands[6] = gen_highpart (SImode, operands[2]);
10187 }"
10188   [(set_attr "type" "arith_media")])
10189
10190 (define_insn "*mshfhi_l_di_rev"
10191   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10192         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10193                         (const_int -4294967296))
10194                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10195                              (const_int 32))))]
10196   "TARGET_SHMEDIA"
10197   "mshfhi.l     %N2, %N1, %0"
10198   [(set_attr "type" "arith_media")])
10199
10200 (define_split
10201   [(set (match_operand:DI 0 "arith_reg_dest" "")
10202         (ior:DI (zero_extend:DI (match_operand:SI 1
10203                                               "extend_reg_or_0_operand" ""))
10204                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10205                         (const_int -4294967296))))
10206    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10207   "TARGET_SHMEDIA"
10208   [(const_int 0)]
10209   "
10210 {
10211   emit_insn (gen_ashldi3_media (operands[3],
10212                                 simplify_gen_subreg (DImode, operands[1],
10213                                                      SImode, 0),
10214                                 GEN_INT (32)));
10215   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10216   DONE;
10217 }")
10218
10219 (define_insn "mshflo_l_di"
10220   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10221         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10222                         (const_int 4294967295))
10223                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10224                            (const_int 32))))]
10225                                 
10226   "TARGET_SHMEDIA"
10227   "mshflo.l     %N1, %N2, %0"
10228   [(set_attr "type" "arith_media")])
10229
10230 (define_insn "*mshflo_l_di_rev"
10231   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10232         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10233                            (const_int 32))
10234                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10235                         (const_int 4294967295))))]
10236                                 
10237   "TARGET_SHMEDIA"
10238   "mshflo.l     %N2, %N1, %0"
10239   [(set_attr "type" "arith_media")])
10240
10241 ;; Combiner pattern for trampoline initialization.
10242 (define_insn_and_split "*double_shori"
10243   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10244         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10245                            (const_int 32))
10246                 (match_operand:DI 2 "const_int_operand" "n")))]
10247   "TARGET_SHMEDIA
10248    && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10249   "#"
10250   "rtx_equal_p (operands[0], operands[1])"
10251   [(const_int 0)]
10252   "
10253 {
10254   HOST_WIDE_INT v = INTVAL (operands[2]);
10255
10256   emit_insn (gen_shori_media (operands[0], operands[0],
10257              gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10258   emit_insn (gen_shori_media (operands[0], operands[0],
10259                               gen_int_mode (v, HImode)));
10260   DONE;
10261 }")
10262
10263
10264 (define_insn "*mshflo_l_di_x"
10265   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10266         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
10267                                  "rU"))
10268                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10269                            (const_int 32))))]
10270                                 
10271   "TARGET_SHMEDIA"
10272   "mshflo.l     %N1, %N2, %0"
10273   [(set_attr "type" "arith_media")])
10274
10275 (define_insn_and_split "concat_v2sf"
10276   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
10277 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rU,0,f")
10278         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rU,f,f")
10279                          (match_operand:SF 2 "register_operand" "rU,f,f")))]
10280                                 
10281   "TARGET_SHMEDIA"
10282   "@
10283         mshflo.l        %N1, %N2, %0
10284         #
10285         #"
10286   "TARGET_SHMEDIA && reload_completed
10287    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10288   [(set (match_dup 3) (match_dup 1))
10289    (set (match_dup 4) (match_dup 2))]
10290   "
10291 {
10292   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10293   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10294 }"
10295   [(set_attr "type" "arith_media")])
10296
10297 (define_insn "*mshflo_l_di_x_rev"
10298   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10299         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10300                            (const_int 32))
10301                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rU"))))]
10302                                 
10303   "TARGET_SHMEDIA"
10304   "mshflo.l     %N2, %N1, %0"
10305   [(set_attr "type" "arith_media")])
10306
10307 (define_insn "ashlv2si3"
10308   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10309         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10310                      (match_operand:DI 2 "arith_reg_operand" "r")))]
10311   "TARGET_SHMEDIA"
10312   "mshlld.l     %1, %2, %0"
10313   [(set_attr "type" "arith_media")])
10314
10315 (define_insn "ashlv4hi3"
10316   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10317         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10318                      (match_operand:DI 2 "arith_reg_operand" "r")))]
10319   "TARGET_SHMEDIA"
10320   "mshlld.w     %1, %2, %0"
10321   [(set_attr "type" "arith_media")])
10322
10323 (define_insn "lshrv2si3"
10324   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10325         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10326                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10327   "TARGET_SHMEDIA"
10328   "mshlrd.l     %1, %2, %0"
10329   [(set_attr "type" "arith_media")])
10330
10331 (define_insn "lshrv4hi3"
10332   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10333         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10334                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10335   "TARGET_SHMEDIA"
10336   "mshlrd.w     %1, %2, %0"
10337   [(set_attr "type" "arith_media")])
10338
10339 (define_insn "subv2si3"
10340   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10341         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10342                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10343   "TARGET_SHMEDIA"
10344   "msub.l       %N1, %2, %0"
10345   [(set_attr "type" "arith_media")])
10346
10347 (define_insn "subv4hi3"
10348   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10349         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10350                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10351   "TARGET_SHMEDIA"
10352   "msub.w       %N1, %2, %0"
10353   [(set_attr "type" "arith_media")])
10354
10355 (define_insn "sssubv2si3"
10356   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10357         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10358                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10359   "TARGET_SHMEDIA"
10360   "msubs.l      %N1, %2, %0"
10361   [(set_attr "type" "mcmp_media")])
10362
10363 (define_insn "ussubv8qi3"
10364   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10365         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10366                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10367   "TARGET_SHMEDIA"
10368   "msubs.ub     %1, %2, %0"
10369   [(set_attr "type" "mcmp_media")])
10370
10371 (define_insn "sssubv4hi3"
10372   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10373         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10374                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10375   "TARGET_SHMEDIA"
10376   "msubs.w      %N1, %2, %0"
10377   [(set_attr "type" "mcmp_media")])
10378
10379 ;; Floating Point Intrinsics
10380
10381 (define_insn "fcosa_s"
10382   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10383         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10384                    UNSPEC_FCOSA))]
10385   "TARGET_SHMEDIA"
10386   "fcosa.s      %1, %0"
10387   [(set_attr "type" "atrans_media")])
10388
10389 (define_insn "fsina_s"
10390   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10391         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10392                    UNSPEC_FSINA))]
10393   "TARGET_SHMEDIA"
10394   "fsina.s      %1, %0"
10395   [(set_attr "type" "atrans_media")])
10396
10397 (define_insn "fipr"
10398   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10399         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10400                                                     "fp_arith_reg_operand" "f")
10401                                                    (match_operand:V4SF 2
10402                                                     "fp_arith_reg_operand" "f"))
10403                                          (parallel [(const_int 0)]))
10404                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10405                                          (parallel [(const_int 1)])))
10406                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10407                                          (parallel [(const_int 2)]))
10408                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10409                                          (parallel [(const_int 3)])))))]
10410   "TARGET_SHMEDIA"
10411   "fipr %1, %2, %0"
10412   [(set_attr "type" "fparith_media")])
10413
10414 (define_insn "fsrra_s"
10415   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10416         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10417                    UNSPEC_FSRRA))]
10418   "TARGET_SHMEDIA"
10419   "fsrra.s      %1, %0"
10420   [(set_attr "type" "atrans_media")])
10421
10422 (define_insn "ftrv"
10423   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10424         (plus:V4SF
10425          (plus:V4SF
10426           (mult:V4SF
10427            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
10428                             (parallel [(const_int 0) (const_int 5)
10429                                        (const_int 10) (const_int 15)]))
10430            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10431           (mult:V4SF
10432            (vec_select:V4SF (match_dup 1)
10433                             (parallel [(const_int 4) (const_int 9)
10434                                        (const_int 14) (const_int 3)]))
10435            (vec_select:V4SF (match_dup 2)
10436                             (parallel [(const_int 1) (const_int 2)
10437                                       (const_int 3) (const_int 0)]))))
10438          (plus:V4SF
10439           (mult:V4SF
10440            (vec_select:V4SF (match_dup 1)
10441                             (parallel [(const_int 8) (const_int 13)
10442                                        (const_int 2) (const_int 7)]))
10443            (vec_select:V4SF (match_dup 2)
10444                             (parallel [(const_int 2) (const_int 3)
10445                                        (const_int 0) (const_int 1)])))
10446           (mult:V4SF
10447            (vec_select:V4SF (match_dup 1)
10448                             (parallel [(const_int 12) (const_int 1)
10449                                        (const_int 6) (const_int 11)]))
10450            (vec_select:V4SF (match_dup 2)
10451                             (parallel [(const_int 3) (const_int 0)
10452                                        (const_int 1) (const_int 2)]))))))]
10453   "TARGET_SHMEDIA"
10454   "ftrv %1, %2, %0"
10455   [(set_attr "type" "fparith_media")])
10456
10457 (define_insn "nsb"
10458   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10459         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10460                    UNSPEC_NSB))]
10461   "TARGET_SHMEDIA"
10462   "nsb  %1, %0"
10463   [(set_attr "type" "arith_media")])
10464
10465 (define_insn "nsbsi"
10466   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10467         (zero_extend:SI
10468          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10469                     UNSPEC_NSB)))]
10470   "TARGET_SHMEDIA"
10471   "nsb  %1, %0"
10472   [(set_attr "type" "arith_media")])
10473
10474 (define_insn "nsbdi"
10475   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10476         (zero_extend:DI
10477          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10478                     UNSPEC_NSB)))]
10479   "TARGET_SHMEDIA"
10480   "nsb  %1, %0"
10481   [(set_attr "type" "arith_media")])
10482
10483 (define_expand "ffsdi2"
10484   [(set (match_operand:DI 0 "arith_reg_dest" "")
10485         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10486   "TARGET_SHMEDIA"
10487   "
10488 {
10489   rtx scratch = gen_reg_rtx (DImode);
10490   rtx last;
10491
10492   emit_insn (gen_adddi3 (scratch, operands[1], GEN_INT (-1)));
10493   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10494   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10495   emit_insn (gen_nsbdi (scratch, scratch));
10496   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10497   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10498   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10499   REG_NOTES (last)
10500     = gen_rtx_EXPR_LIST (REG_EQUAL,
10501                          gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10502   DONE;
10503 }")
10504
10505 (define_expand "ffssi2"
10506   [(set (match_operand:SI 0 "arith_reg_dest" "")
10507         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10508   "TARGET_SHMEDIA"
10509   "
10510 {
10511   rtx scratch = gen_reg_rtx (SImode);
10512   rtx discratch = gen_reg_rtx (DImode);
10513   rtx last;
10514
10515   emit_insn (gen_adddi3z_media (discratch, operands[1],
10516                                 force_reg (SImode, GEN_INT (-1))));
10517   emit_insn (gen_andcdi3 (discratch, discratch,
10518                           simplify_gen_subreg (DImode, operands[1],
10519                                                SImode, 0)));
10520   emit_insn (gen_nsbsi (scratch, discratch));
10521   last = emit_insn (gen_subsi3 (operands[0],
10522                                 force_reg (SImode, GEN_INT (-64)), scratch));
10523   REG_NOTES (last)
10524     = gen_rtx_EXPR_LIST (REG_EQUAL,
10525                          gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10526   DONE;
10527 }")
10528
10529 (define_insn "byterev"
10530   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10531         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10532                          (parallel [(const_int 7) (const_int 6) (const_int 5)
10533                                     (const_int 4) (const_int 3) (const_int 2)
10534                                     (const_int 1) (const_int 0)])))]
10535   "TARGET_SHMEDIA"
10536   "byterev      %1, %0"
10537   [(set_attr "type" "arith_media")])
10538
10539 ;; The following description  models the
10540 ;; SH4 pipeline using the DFA based scheduler. 
10541 ;; The DFA based description is better way to model 
10542 ;; a superscalar pipeline as compared to function unit
10543 ;; reservation model.   
10544 ;; 1. The function unit based model is oriented to describe at most one 
10545 ;;    unit reservation by each insn. It is difficult to model unit reservations in multiple 
10546 ;;    pipeline units by same insn. This can be done using DFA based description.
10547 ;; 2. The execution performance of DFA based scheduler does not depend on processor complexity.
10548 ;; 3. Writing all unit reservations for an instruction class is more natural description 
10549 ;;    of the pipeline and makes interface of the hazard recognizer simpler than the 
10550 ;;    old function unit based model.
10551 ;; 4. The DFA model is richer and is a part of greater overall framework of RCSP.
10552
10553
10554 ;; Two automata are defined to reduce number of states
10555 ;; which a single large automaton will have.(Factoring)
10556
10557 (define_automaton "inst_pipeline,fpu_pipe")
10558
10559 ;; This unit is basically the decode unit of the processor.
10560 ;; Since SH4 is a dual issue machine,it is as if there are two 
10561 ;; units so that any insn can be processed by either one
10562 ;; of the decoding unit.
10563
10564 (define_cpu_unit "pipe_01,pipe_02" "inst_pipeline")
10565
10566
10567 ;; The fixed point arithmetic calculator(?? EX Unit).
10568
10569 (define_cpu_unit  "int" "inst_pipeline")
10570
10571 ;; f1_1 and f1_2 are floating point units.Actually there is
10572 ;; a f1 unit which can overlap with other f1 unit but
10573 ;; not another F1 unit.It is as though there were two
10574 ;; f1 units.
10575
10576 (define_cpu_unit "f1_1,f1_2" "fpu_pipe")
10577
10578 ;; The floating point units.
10579
10580 (define_cpu_unit "F1,F2,F3,FS" "fpu_pipe")
10581
10582 ;; This is basically the MA unit of SH4
10583 ;; used in LOAD/STORE pipeline.
10584
10585 (define_cpu_unit "memory" "inst_pipeline")
10586
10587 ;; The address calculator used for branch instructions.
10588 ;; This will be reserved with "issue" of branch instructions
10589 ;; and this is to make sure that  no two branch instructions 
10590 ;; can be issued in parallel. 
10591
10592 (define_cpu_unit "pcr_addrcalc" "inst_pipeline")
10593
10594 ;; ----------------------------------------------------
10595 ;; This reservation is to simplify the dual issue description.
10596
10597 (define_reservation  "issue"  "pipe_01|pipe_02")
10598
10599 ;; This is to express the locking of D stage.
10600
10601 (define_reservation  "d_lock" "pipe_01+pipe_02")
10602
10603 ;; This is to simplify description where F1,F2,FS
10604 ;; are used simultaneously.
10605
10606 (define_reservation "fpu" "F1+F2+FS")
10607
10608 ;; This is to highlight the fact that f1 
10609 ;; cannot overlap with F1.
10610
10611 (exclusion_set  "f1_1,f1_2" "F1")
10612
10613 ;; Although reg moves have a latency of zero 
10614 ;; we need to highlight that they use D stage
10615 ;; for one cycle.
10616
10617 (define_insn_reservation "reg_mov" 0
10618                (eq_attr "type" "move,fmove")
10619               "issue")
10620
10621 ;; Other MT  group intructions(1 step operations)
10622 ;; Group:       MT
10623 ;; Latency:     1
10624 ;; Issue Rate:  1
10625
10626 (define_insn_reservation "mt" 1
10627                       (eq_attr "insn_class" "mt_group")
10628                       "issue,nothing")
10629
10630 ;; Fixed Point Arithmetic Instructions(1 step operations)
10631 ;; Group:       EX
10632 ;; Latency:     1
10633 ;; Issue Rate:  1
10634
10635 (define_insn_reservation "simple_arith" 1 
10636             (eq_attr "insn_class" "ex_group")
10637             "issue,int")
10638
10639 ;; Load Store instructions. (MOV.[BWL]@(d,GBR)
10640 ;; Group:       LS
10641 ;; Latency:     2
10642 ;; Issue Rate:  1
10643
10644 (define_insn_reservation "load_store" 2
10645        (eq_attr "type" "load,load_si,pcload,pcload_si,store")
10646        "issue,memory*2")
10647
10648 ;; Branch (BF,BF/S,BT,BT/S,BRA)
10649 ;; Group:       BR
10650 ;; Latency:     2 (or 1) Actually Observed to be 5/7
10651 ;; Issue Rate:  1
10652 ;; The latency is 1 when displacement is 0.
10653 ;; This reservation can be further broken into 2
10654 ;;    1. branch_zero : One with latency 1 and in the TEST 
10655 ;;       part it also checks for 0 (ZERO) displacement 
10656 ;;    2. branch: Latency 2.
10657
10658 (define_insn_reservation "branch_zero"  5
10659              (and (eq_attr "type" "cbranch")
10660                   (eq_attr "length" "2"))
10661              "(issue+pcr_addrcalc),pcr_addrcalc,nothing")
10662
10663 (define_insn_reservation "branch"  7
10664              (eq_attr "type" "cbranch")
10665              "(issue+pcr_addrcalc),pcr_addrcalc,nothing")
10666
10667 ;; Branch Far (JMP,RTS,BRAF)
10668 ;; Group:       CO
10669 ;; Latency:     3
10670 ;; Issue Rate:  2
10671 ;;    Since issue stage (D stage) is blocked for 2nd cycle, 
10672 ;;    cpu_unit  int  is reserved since it might be required for far
10673 ;;    address calculation.
10674
10675 (define_insn_reservation "branch_far" 12
10676          (and (eq_attr "type" "jump,return")
10677               (eq_attr "length" "6"))
10678          "d_lock*2,int+pcr_addrcalc,pcr_addrcalc")
10679
10680 ;; RTE
10681 ;; Group:       CO
10682 ;; atency:      5
10683 ;; Issue Rate:  5
10684 ;; this instruction can be executed in any of the pipelines 
10685 ;; and blocks the pipeline for next 4 stages.
10686
10687 (define_insn_reservation "return_from_exp" 5
10688           (eq_attr "type" "rte")
10689          "(issue+pcr_addrcalc),d_lock*4,int+pcr_addrcalc,nothing")
10690
10691 ;; OCBP, OCBWB
10692 ;; Group:       CO
10693 ;; Latency:     5
10694 ;; Issue Rate:  1
10695
10696 (define_insn_reservation "ocbwb"  5
10697           (eq_attr "insn_class" "cwb") 
10698            "issue,(int+memory),memory*5")
10699                 
10700 ;; LDS to PR,JSR
10701 ;; Group:       CO
10702 ;; Latency:     3
10703 ;; Issue Rate:  2
10704 ;; The SX stage is blocked for last 2 cycles.
10705
10706 (define_insn_reservation "lds_to_pr" 3 
10707           (eq_attr "type" "prset,call,sfunc") 
10708           "(issue+pcr_addrcalc),(issue+int+pcr_addrcalc),(int+pcr_addrcalc)*2")
10709
10710 ;; LDS.L to PR 
10711 ;; Group:       CO
10712 ;; Latency:     3
10713 ;; Issue Rate:  2
10714 ;; The SX unit is blocked for last 2 cycles.
10715  
10716 (define_insn_reservation "ldsmem_to_pr"  3
10717       (eq_attr "type" "pload") 
10718      "(issue+pcr_addrcalc),(issue+int+pcr_addrcalc),(int+memory+pcr_addrcalc),(int+pcr_addrcalc)")
10719
10720 ;; STS from PR
10721 ;; Group:       CO
10722 ;; Latency:     2
10723 ;; Issue Rate:  2
10724 ;; The SX unit in second and third cycles.
10725
10726 (define_insn_reservation "sts_from_pr" 2
10727         (eq_attr "type" "prget")
10728        "(issue+pcr_addrcalc),(pipe_01+int+pcr_addrcalc),(int+pcr_addrcalc),nothing")
10729
10730 ;; STS.L from PR
10731 ;; Group:       CO
10732 ;; Latency:     2
10733 ;; Issue Rate:  2
10734
10735 (define_insn_reservation "prload_mem" 2 
10736           (eq_attr "type" "pstore")
10737            "(issue+pcr_addrcalc),(pipe_01+int+pcr_addrcalc),(int+memory+pcr_addrcalc),memory")
10738
10739 ;; LDS to FPSCR
10740 ;; Group:       CO
10741 ;; Latency:     4
10742 ;; Issue Rate:  1
10743 ;; F1 is blocked for last three cycles. 
10744
10745 (define_insn_reservation "fpscr_store" 4
10746         (eq_attr "insn_class" "lds_to_fpscr")
10747        "issue,int,F1*3")
10748
10749 ;; LDS.L to FPSCR
10750 ;; Group:       CO
10751 ;; Latency:     1 / 4
10752 ;; Latency to update Rn is 1 and latency to update FPSCR is 4
10753 ;; Issue Rate:  1
10754 ;; F1 is blocked for last three cycles.
10755
10756 (define_insn_reservation "fpscr_store_mem" 4
10757         (eq_attr "insn_class"  "ldsmem_to_fpscr") 
10758         "issue,(int+memory),(F1+memory),F1*2")
10759
10760 \f
10761 ;; Fixed point multiplication (DMULS.L DMULU.L MUL.L MULS.W,MULU.W)
10762 ;; Group:       CO
10763 ;; Latency:     4 / 4
10764 ;; Issue Rate:  1
10765
10766 (define_insn_reservation "multi" 4
10767         (eq_attr "type" "smpy,dmpy")
10768         "issue,(issue+int+f1_1),(int+f1_1),(f1_1|f1_2)*2,F2,FS")
10769
10770
10771 ;; Single precision floating point computation FCMP/EQ,
10772 ;; FCP/GT, FADD, FLOAT, FMAC, FMUL, FSUB, FTRC, FRVHG, FSCHG
10773 ;; Group:       FE
10774 ;; Latency:     4
10775 ;; Issue Rate:  1
10776
10777 (define_insn_reservation "fp_arith"  4
10778               (eq_attr "type" "fp")
10779               "issue,F1,F2,FS")
10780
10781 ;; Single Precision FDIV/SQRT
10782 ;; Group:       FE
10783 ;; Latency:     12/13
10784 ;; Issue Rate:  1
10785
10786 (define_insn_reservation "fp_div" 13
10787                (eq_attr "type" "fdiv")
10788                "issue,F1+F3,F1+F2+F3,F3*7,F1+F3,F2,FS")
10789
10790 ;; Double Precision floating point computation
10791 ;; (FCNVDS, FCNVSD, FLOAT, FTRC)
10792 ;; Group:       FE
10793 ;; Latency:     (3,4)/5
10794 ;; Issue Rate:  1
10795
10796 (define_insn_reservation "dp_float" 5
10797          (eq_attr "type" "dfp_conv")
10798          "issue,F1,F1+F2,F2+FS,FS")
10799
10800 ;; Double-precision floating-point (FADD ,FMUL,FSUB) 
10801 ;; Group:       FE
10802 ;; Latency:     (7,8)/9
10803 ;; Issue Rate:  1
10804
10805 (define_insn_reservation "fp_double_arith" 9
10806         (eq_attr "type" "dfp_arith")
10807         "issue,F1,F1+F2,fpu*4,F2+FS,FS")
10808
10809 ;; Double-precision FCMP (FCMP/EQ,FCMP/GT) 
10810 ;; Group:       FE
10811 ;; Latency:     3/5
10812 ;; Issue Rate:  2
10813
10814 (define_insn_reservation "fp_double_cmp" 5 
10815         (eq_attr "type" "dfp_cmp")
10816         "issue,(issue+F1),F1+F2,F2+FS,FS")
10817
10818 ;; Double precision FDIV/SQRT
10819 ;; Group:       FE
10820 ;; Latency:     (24,25)/26
10821 ;; Issue Rate:  1
10822
10823 (define_insn_reservation "dp_div" 26
10824         (eq_attr "type" "dfdiv")
10825         "issue,F1+F3,F1+F2+F3,F2+F3+FS,F3*16,F1+F3,F1+F2+F3,fpu+F3,F2+FS,FS")
10826