OSDN Git Service

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