OSDN Git Service

* sh.h (binary_logical_operator): Declare.
[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 ;; fload        Likewise, but load to fp register.
187 ;; store        to memory
188 ;; move         general purpose register to register
189 ;; mt_group     other sh4 mt instructions
190 ;; fmove        register to register, floating point
191 ;; smpy         word precision integer multiply
192 ;; dmpy         longword or doublelongword precision integer multiply
193 ;; return       rts
194 ;; pload        load of pr reg, which can't be put into delay slot of rts
195 ;; prset        copy register to pr reg, ditto
196 ;; pstore       store of pr reg, which can't be put into delay slot of jsr
197 ;; prget        copy pr to register, ditto
198 ;; pcload       pc relative load of constant value
199 ;; pcfload      Likewise, but load to fp register.
200 ;; pcload_si    Likewise, SImode variant for general register.
201 ;; rte          return from exception
202 ;; sfunc        special function call with known used registers
203 ;; call         function call
204 ;; fp           floating point
205 ;; fdiv         floating point divide (or square root)
206 ;; gp_fpul      move from general purpose register to fpul
207 ;; fpul_gp      move from fpul to general purpose register
208 ;; mac_gp       move from mac[lh] to general purpose register
209 ;; dfp_arith, dfp_cmp,dfp_conv
210 ;; ftrc_s       fix_truncsfsi2_i4
211 ;; dfdiv        double precision floating point divide (or square root)
212 ;; cwb          ic_invalidate_line_i
213 ;; arith_media  SHmedia arithmetic, logical, and shift instructions
214 ;; cbranch_media SHmedia conditional branch instructions
215 ;; cmp_media    SHmedia compare instructions
216 ;; dfdiv_media  SHmedia double precision divide and square root
217 ;; dfmul_media  SHmedia double precision multiply instruction
218 ;; dfparith_media SHmedia double precision floating point arithmetic
219 ;; dfpconv_media SHmedia double precision floating point conversions
220 ;; dmpy_media   SHmedia longword multiply
221 ;; fcmp_media   SHmedia floating point compare instructions
222 ;; fdiv_media   SHmedia single precision divide and square root
223 ;; fload_media  SHmedia floating point register load instructions
224 ;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
225 ;; fparith_media SHmedia single precision floating point arithmetic
226 ;; fpconv_media SHmedia single precision floating point conversions
227 ;; fstore_media SHmedia floating point register store instructions
228 ;; gettr_media  SHmedia gettr instruction
229 ;; invalidate_line_media SHmedia invaldiate_line sequence
230 ;; jump_media   SHmedia unconditional branch instructions
231 ;; load_media   SHmedia general register load instructions
232 ;; pt_media     SHmedia pt instruction (expanded by assembler)
233 ;; ptabs_media  SHmedia ptabs instruction
234 ;; store_media  SHmedia general register store instructions
235 ;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
236 ;; mac_media    SHmedia mac-style fixed point operations
237 ;; d2mpy_media  SHmedia: two 32 bit integer multiplies
238 ;; atrans       SHmedia approximate transcendential functions
239 ;; ustore_media SHmedia unaligned stores
240 ;; nil          no-op move, will be deleted.
241
242 (define_attr "type"
243  "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,move,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fdiv,ftrc_s,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,mem_fpscr,gp_fpscr,cwb,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"
244   (const_string "other"))
245
246 ;; We define a new attribute namely "insn_class".We use
247 ;; this for the DFA based pipeline description.
248 ;;
249 ;; mt_group      SH4 "mt" group instructions.
250 ;;
251 ;; ex_group      SH4 "ex" group instructions.
252 ;;
253 ;; ls_group      SH4 "ls" group instructions.
254 ;;
255
256 (define_attr "insn_class"
257   "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
258   (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
259          (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
260          (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
261          (eq_attr "type" "cbranch,jump") (const_string "br_group")
262          (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
263            (const_string "fe_group")
264          (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb") (const_string "co_group")]
265         (const_string "none")))
266 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
267 ;; so these do not belong in an insn group, although they are modeled
268 ;; with their own define_insn_reservations.
269
270 ;; Indicate what precision must be selected in fpscr for this insn, if any.
271
272 (define_attr "fp_mode" "single,double,none" (const_string "none"))
273
274 ; If a conditional branch destination is within -252..258 bytes away
275 ; from the instruction it can be 2 bytes long.  Something in the
276 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
277 ; branches are initially assumed to be 16 bytes long.
278 ; In machine_dependent_reorg, we split all branches that are longer than
279 ; 2 bytes.
280
281 ;; The maximum range used for SImode constant pool entries is 1018.  A final
282 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
283 ;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
284 ;; instruction around the pool table, 2 bytes of alignment before the table,
285 ;; and 30 bytes of alignment after the table.  That gives a maximum total
286 ;; pool size of 1058 bytes.
287 ;; Worst case code/pool content size ratio is 1:2 (using asms).
288 ;; Thus, in the worst case, there is one instruction in front of a maximum
289 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
290 ;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
291 ;; If we have a forward branch, the initial table will be put after the
292 ;; unconditional branch.
293 ;;
294 ;; ??? We could do much better by keeping track of the actual pcloads within
295 ;; the branch range and in the pcload range in front of the branch range.
296
297 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
298 ;; inside an le.
299 (define_attr "short_cbranch_p" "no,yes"
300   (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
301          (const_string "no")
302          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
303          (const_string "yes")
304          (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
305          (const_string "no")
306          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
307          (const_string "yes")
308          ] (const_string "no")))
309
310 (define_attr "med_branch_p" "no,yes"
311   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
312               (const_int 1988))
313          (const_string "yes")
314          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
315          (const_string "no")
316          (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
317               (const_int 8186))
318          (const_string "yes")
319          ] (const_string "no")))
320
321 (define_attr "med_cbranch_p" "no,yes"
322   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
323               (const_int 1986))
324          (const_string "yes")
325          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
326          (const_string "no")
327          (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
328                (const_int 8184))
329          (const_string "yes")
330          ] (const_string "no")))
331
332 (define_attr "braf_branch_p" "no,yes"
333   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
334          (const_string "no")
335          (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
336               (const_int 20660))
337          (const_string "yes")
338          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
339          (const_string "no")
340          (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
341               (const_int 65530))
342          (const_string "yes")
343          ] (const_string "no")))
344
345 (define_attr "braf_cbranch_p" "no,yes"
346   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
347          (const_string "no")
348          (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
349               (const_int 20658))
350          (const_string "yes")
351          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
352          (const_string "no")
353          (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
354               (const_int 65528))
355          (const_string "yes")
356          ] (const_string "no")))
357
358 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
359 ; For wider ranges, we need a combination of a code and a data part.
360 ; If we can get a scratch register for a long range jump, the code
361 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
362 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
363 ; long; otherwise, it must be 6 bytes long.
364
365 ; All other instructions are two bytes long by default.
366
367 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
368 ;; but getattrtab doesn't understand this.
369 (define_attr "length" ""
370   (cond [(eq_attr "type" "cbranch")
371          (cond [(eq_attr "short_cbranch_p" "yes")
372                 (const_int 2)
373                 (eq_attr "med_cbranch_p" "yes")
374                 (const_int 6)
375                 (eq_attr "braf_cbranch_p" "yes")
376                 (const_int 12)
377 ;; ??? using pc is not computed transitively.
378                 (ne (match_dup 0) (match_dup 0))
379                 (const_int 14)
380                 (ne (symbol_ref ("flag_pic")) (const_int 0))
381                 (const_int 24)
382                 ] (const_int 16))
383          (eq_attr "type" "jump")
384          (cond [(eq_attr "med_branch_p" "yes")
385                 (const_int 2)
386                 (and (eq (symbol_ref "GET_CODE (PREV_INSN (insn))")
387                          (symbol_ref "INSN"))
388                      (eq (symbol_ref "INSN_CODE (PREV_INSN (insn))")
389                          (symbol_ref "code_for_indirect_jump_scratch")))
390                 (if_then_else (eq_attr "braf_branch_p" "yes")
391                               (const_int 6)
392                               (const_int 10))
393                 (eq_attr "braf_branch_p" "yes")
394                 (const_int 10)
395 ;; ??? using pc is not computed transitively.
396                 (ne (match_dup 0) (match_dup 0))
397                 (const_int 12)
398                 (ne (symbol_ref ("flag_pic")) (const_int 0))
399                 (const_int 22)
400                 ] (const_int 14))
401          (eq_attr "type" "pt_media")
402          (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
403                        (const_int 20) (const_int 12))
404          ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
405                          (const_int 4)
406                          (const_int 2))))
407
408 ;; (define_function_unit {name} {num-units} {n-users} {test}
409 ;;                       {ready-delay} {issue-delay} [{conflict-list}])
410
411 ;; Load and store instructions save a cycle if they are aligned on a
412 ;; four byte boundary.  Using a function unit for stores encourages
413 ;; gcc to separate load and store instructions by one instruction,
414 ;; which makes it more likely that the linker will be able to word
415 ;; align them when relaxing.
416
417 ;; Loads have a latency of two.
418 ;; However, call insns can have a delay slot, so that we want one more
419 ;; insn to be scheduled between the load of the function address and the call.
420 ;; This is equivalent to a latency of three.
421 ;; We cannot use a conflict list for this, because we need to distinguish
422 ;; between the actual call address and the function arguments.
423 ;; ADJUST_COST can only properly handle reductions of the cost, so we
424 ;; use a latency of three here.
425 ;; We only do this for SImode loads of general registers, to make the work
426 ;; for ADJUST_COST easier.
427 (define_function_unit "memory" 1 0
428   (and (eq_attr "pipe_model" "sh1")
429        (eq_attr "type" "load_si,pcload_si"))
430   3 2)
431 (define_function_unit "memory" 1 0
432   (and (eq_attr "pipe_model" "sh1")
433        (eq_attr "type" "load,pcload,pload,store,pstore"))
434   2 2)
435
436 (define_function_unit "int"    1 0
437   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "arith3,arith3b")) 3 3)
438
439 (define_function_unit "int"    1 0
440   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dyn_shift")) 2 2)
441
442 (define_function_unit "int"    1 0
443   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "!arith3,arith3b,dyn_shift")) 1 1)
444
445 ;; ??? These are approximations.
446 (define_function_unit "mpy"    1 0
447   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "smpy")) 2 2)
448 (define_function_unit "mpy"    1 0
449   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dmpy")) 3 3)
450
451 (define_function_unit "fp"     1 0
452   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fp,fmove")) 2 1)
453 (define_function_unit "fp"     1 0
454   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fdiv")) 13 12)
455
456
457 ;; SH-5 SHmedia scheduling
458 ;; When executing SHmedia code, the SH-5 is a fairly straightforward
459 ;; single-issue machine.  It has four pipelines, the branch unit (br),
460 ;; the integer and multimedia unit (imu), the load/store unit (lsu), and
461 ;; the floating point unit (fpu).
462 ;; Here model the instructions with a latency greater than one cycle.
463
464 ;; Every instruction on SH-5 occupies the issue resource for at least one
465 ;; cycle.
466 (define_function_unit "sh5issue" 1 0
467   (and (eq_attr "pipe_model" "sh5media")
468        (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)
469
470 ;; Specify the various types of instruction which have latency > 1
471 (define_function_unit "sh5issue" 1 0
472   (and (eq_attr "pipe_model" "sh5media")
473        (eq_attr "type" "mcmp_media")) 2 1)
474
475 (define_function_unit "sh5issue" 1 0
476   (and (eq_attr "pipe_model" "sh5media")
477        (eq_attr "type" "dmpy_media,load_media,fcmp_media,mac_media")) 3 1)
478 ;; but see sh_adjust_cost for mac_media exception.
479
480 (define_function_unit "sh5issue" 1 0
481   (and (eq_attr "pipe_model" "sh5media")
482        (eq_attr "type" "fload_media,fmove_media")) 4 1)
483
484 (define_function_unit "sh5issue" 1 0
485   (and (eq_attr "pipe_model" "sh5media")
486        (eq_attr "type" "d2mpy_media")) 4 2)
487
488 (define_function_unit "sh5issue" 1 0
489   (and (eq_attr "pipe_model" "sh5media")
490        (eq_attr "type" "pt_media,ptabs_media")) 5 1)
491
492 (define_function_unit "sh5issue" 1 0
493   (and (eq_attr "pipe_model" "sh5media")
494        (eq_attr "type" "fparith_media,dfparith_media,fpconv_media,dfpconv_media")) 6 1)
495
496 (define_function_unit "sh5issue" 1 0
497   (and (eq_attr "pipe_model" "sh5media")
498        (eq_attr "type" "invalidate_line_media")) 7 7)
499
500 (define_function_unit "sh5issue" 1 0
501   (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfmul_media")) 9 4)
502
503 (define_function_unit "sh5issue" 1 0
504   (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "atrans_media")) 10 5)
505
506 ;; Floating-point divide and square-root occupy an additional resource,
507 ;; which is not internally pipelined.  However, other instructions
508 ;; can continue to issue.
509 (define_function_unit "sh5fds" 1 0
510   (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "fdiv_media"))  19 19)
511
512 (define_function_unit "sh5fds" 1 0
513   (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfdiv_media")) 35 35)
514
515 ; Definitions for filling branch delay slots.
516
517 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
518
519 ;; ??? This should be (nil) instead of (const_int 0)
520 (define_attr "hit_stack" "yes,no"
521         (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
522                    (const_int 0))
523                (const_string "no")]
524               (const_string "yes")))
525
526 (define_attr "interrupt_function" "no,yes"
527   (const (symbol_ref "current_function_interrupt")))
528
529 (define_attr "in_delay_slot" "yes,no"
530   (cond [(eq_attr "type" "cbranch") (const_string "no")
531          (eq_attr "type" "pcload,pcload_si") (const_string "no")
532          (eq_attr "needs_delay_slot" "yes") (const_string "no")
533          (eq_attr "length" "2") (const_string "yes")
534          ] (const_string "no")))
535
536 (define_attr "cond_delay_slot" "yes,no"
537   (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
538          ] (const_string "no")))
539
540 (define_attr "is_sfunc" ""
541   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
542
543 (define_attr "is_mac_media" ""
544   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
545
546 (define_attr "branch_zero" "yes,no"
547   (cond [(eq_attr "type" "!cbranch") (const_string "no")
548          (ne (symbol_ref "(next_active_insn (insn)\
549                            == (prev_active_insn\
550                                (XEXP (SET_SRC (PATTERN (insn)), 1))))\
551                           && get_attr_length (next_active_insn (insn)) == 2")
552              (const_int 0))
553          (const_string "yes")]
554         (const_string "no")))
555
556 ;; SH4 Double-precision computation with double-precision result -
557 ;; the two halves are ready at different times.
558 (define_attr "dfp_comp" "yes,no"
559   (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
560         (const_string "no")))
561
562 ;; Insns for which the latency of a preceding fp insn is decreased by one.
563 (define_attr "late_fp_use" "yes,no" (const_string "no"))
564 ;; And feeding insns for which this relevant.
565 (define_attr "any_fp_comp" "yes,no"
566   (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
567          (const_string "yes")]
568         (const_string "no")))
569
570 (define_attr "any_int_load" "yes,no"
571   (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
572          (const_string "yes")]
573         (const_string "no")))
574
575 (define_delay
576   (eq_attr "needs_delay_slot" "yes")
577   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
578
579 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
580 ;; and thus we can't put a pop instruction in its delay slot.
581 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
582 ;; instruction can go in the delay slot.
583
584 ;; Since a normal return (rts) implicitly uses the PR register,
585 ;; we can't allow PR register loads in an rts delay slot.
586
587 (define_delay
588   (eq_attr "type" "return")
589   [(and (eq_attr "in_delay_slot" "yes")
590         (ior (and (eq_attr "interrupt_function" "no")
591                   (eq_attr "type" "!pload,prset"))
592              (and (eq_attr "interrupt_function" "yes")
593                   (ior
594                    (ne (symbol_ref "TARGET_SH3") (const_int 0))
595                    (eq_attr "hit_stack" "no"))))) (nil) (nil)])
596
597 ;; Since a call implicitly uses the PR register, we can't allow
598 ;; a PR register store in a jsr delay slot.
599
600 (define_delay
601   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
602   [(and (eq_attr "in_delay_slot" "yes")
603         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
604
605 ;; Say that we have annulled true branches, since this gives smaller and
606 ;; faster code when branches are predicted as not taken.
607
608 (define_delay
609   (and (eq_attr "type" "cbranch")
610        (ne (symbol_ref "TARGET_SH2") (const_int 0)))
611   [(eq_attr "in_delay_slot" "yes") (eq_attr "cond_delay_slot" "yes") (nil)])
612 \f
613 ;; -------------------------------------------------------------------------
614 ;; SImode signed integer comparisons
615 ;; -------------------------------------------------------------------------
616
617 (define_insn ""
618   [(set (reg:SI T_REG)
619         (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
620                        (match_operand:SI 1 "arith_operand" "L,r"))
621                (const_int 0)))]
622   "TARGET_SH1"
623   "tst  %1,%0"
624   [(set_attr "type" "mt_group")])
625
626 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
627 ;; That would still allow reload to create cmpi instructions, but would
628 ;; perhaps allow forcing the constant into a register when that is better.
629 ;; Probably should use r0 for mem/imm compares, but force constant into a
630 ;; register for pseudo/imm compares.
631
632 (define_insn "cmpeqsi_t"
633   [(set (reg:SI T_REG)
634         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
635                (match_operand:SI 1 "arith_operand" "N,rI,r")))]
636   "TARGET_SH1"
637   "@
638         tst     %0,%0
639         cmp/eq  %1,%0
640         cmp/eq  %1,%0"
641    [(set_attr "type" "mt_group")])
642
643 (define_insn "cmpgtsi_t"
644   [(set (reg:SI T_REG)
645         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
646                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
647   "TARGET_SH1"
648   "@
649         cmp/gt  %1,%0
650         cmp/pl  %0"
651    [(set_attr "type" "mt_group")])
652
653 (define_insn "cmpgesi_t"
654   [(set (reg:SI T_REG)
655         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
656                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
657   "TARGET_SH1"
658   "@
659         cmp/ge  %1,%0
660         cmp/pz  %0"
661    [(set_attr "type" "mt_group")])
662
663 ;; -------------------------------------------------------------------------
664 ;; SImode unsigned integer comparisons
665 ;; -------------------------------------------------------------------------
666
667 (define_insn "cmpgeusi_t"
668   [(set (reg:SI T_REG)
669         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
670                 (match_operand:SI 1 "arith_reg_operand" "r")))]
671   "TARGET_SH1"
672   "cmp/hs       %1,%0"
673    [(set_attr "type" "mt_group")])
674
675 (define_insn "cmpgtusi_t"
676   [(set (reg:SI T_REG)
677         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
678                 (match_operand:SI 1 "arith_reg_operand" "r")))]
679   "TARGET_SH1"
680   "cmp/hi       %1,%0"
681    [(set_attr "type" "mt_group")])
682
683 ;; We save the compare operands in the cmpxx patterns and use them when
684 ;; we generate the branch.
685
686 (define_expand "cmpsi"
687   [(set (reg:SI T_REG)
688         (compare (match_operand:SI 0 "arith_operand" "")
689                  (match_operand:SI 1 "arith_operand" "")))]
690   "TARGET_SH1"
691   "
692 {
693   sh_compare_op0 = operands[0];
694   sh_compare_op1 = operands[1];
695   DONE;
696 }")
697 \f
698 ;; -------------------------------------------------------------------------
699 ;; DImode signed integer comparisons
700 ;; -------------------------------------------------------------------------
701
702 ;; ??? Could get better scheduling by splitting the initial test from the
703 ;; rest of the insn after reload.  However, the gain would hardly justify
704 ;; the sh.md size increase necessary to do that.
705
706 (define_insn ""
707   [(set (reg:SI T_REG)
708         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
709                        (match_operand:DI 1 "arith_operand" "r"))
710                (const_int 0)))]
711   "TARGET_SH1"
712   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
713                                  insn, operands);"
714   [(set_attr "length" "6")
715    (set_attr "type" "arith3b")])
716
717 (define_insn "cmpeqdi_t"
718   [(set (reg:SI T_REG)
719         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
720                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
721   "TARGET_SH1"
722   "@
723         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
724         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
725   [(set_attr "length" "6")
726    (set_attr "type" "arith3b")])
727
728 (define_split
729   [(set (reg:SI T_REG)
730         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
731                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
732 ;; If we applied this split when not optimizing, it would only be
733 ;; applied during the machine-dependent reorg, when no new basic blocks
734 ;; may be created.
735   "TARGET_SH1 && reload_completed && optimize"
736   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
737    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
738                            (label_ref (match_dup 6))
739                            (pc)))
740    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
741    (match_dup 6)]
742   "
743 {
744   operands[2]
745     = gen_rtx_REG (SImode,
746                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
747   operands[3]
748     = (operands[1] == const0_rtx
749        ? const0_rtx
750        : gen_rtx_REG (SImode,
751                       true_regnum (operands[1])
752                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
753   operands[4] = gen_lowpart (SImode, operands[0]);
754   operands[5] = gen_lowpart (SImode, operands[1]);
755   operands[6] = gen_label_rtx ();
756 }")
757
758 (define_insn "cmpgtdi_t"
759   [(set (reg:SI T_REG)
760         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
761                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
762   "TARGET_SH2"
763   "@
764         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
765         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
766   [(set_attr "length" "8")
767    (set_attr "type" "arith3")])
768
769 (define_insn "cmpgedi_t"
770   [(set (reg:SI T_REG)
771         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
772                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
773   "TARGET_SH2"
774   "@
775         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
776         cmp/pz\\t%S0"
777   [(set_attr "length" "8,2")
778    (set_attr "type" "arith3,mt_group")])
779 \f
780 ;; -------------------------------------------------------------------------
781 ;; DImode unsigned integer comparisons
782 ;; -------------------------------------------------------------------------
783
784 (define_insn "cmpgeudi_t"
785   [(set (reg:SI T_REG)
786         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
787                 (match_operand:DI 1 "arith_reg_operand" "r")))]
788   "TARGET_SH2"
789   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
790   [(set_attr "length" "8")
791    (set_attr "type" "arith3")])
792
793 (define_insn "cmpgtudi_t"
794   [(set (reg:SI T_REG)
795         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
796                 (match_operand:DI 1 "arith_reg_operand" "r")))]
797   "TARGET_SH2"
798   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
799   [(set_attr "length" "8")
800    (set_attr "type" "arith3")])
801
802 (define_insn "cmpeqdi_media"
803   [(set (match_operand:DI 0 "register_operand" "=r")
804         (eq:DI (match_operand:DI 1 "register_operand" "%r")
805                (match_operand:DI 2 "arith_reg_or_0_operand" "Nr")))]
806   "TARGET_SHMEDIA"
807   "cmpeq        %1, %N2, %0"
808   [(set_attr "type" "cmp_media")])
809
810 (define_insn "cmpgtdi_media"
811   [(set (match_operand:DI 0 "register_operand" "=r")
812         (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
813                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
814   "TARGET_SHMEDIA"
815   "cmpgt        %N1, %N2, %0"
816   [(set_attr "type" "cmp_media")])
817
818 (define_insn "cmpgtudi_media"
819   [(set (match_operand:DI 0 "register_operand" "=r")
820         (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
821                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
822   "TARGET_SHMEDIA"
823   "cmpgtu       %N1, %N2, %0"
824   [(set_attr "type" "cmp_media")])
825
826 ;; We save the compare operands in the cmpxx patterns and use them when
827 ;; we generate the branch.
828
829 (define_expand "cmpdi"
830   [(set (reg:SI T_REG)
831         (compare (match_operand:DI 0 "arith_operand" "")
832                  (match_operand:DI 1 "arith_operand" "")))]
833   "TARGET_SH2 || TARGET_SHMEDIA"
834   "
835 {
836   sh_compare_op0 = operands[0];
837   sh_compare_op1 = operands[1];
838   DONE;
839 }")
840 ;; -------------------------------------------------------------------------
841 ;; Conditional move instructions
842 ;; -------------------------------------------------------------------------
843
844 ;; The insn names may seem reversed, but note that cmveq performs the move
845 ;; if op1 == 0, and cmvne does it if op1 != 0.
846
847 (define_insn "movdicc_false"
848   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
849         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
850                              (const_int 0))
851          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
852          (match_operand:DI 3 "arith_reg_operand" "0")))]
853   "TARGET_SHMEDIA"
854   "cmveq        %1, %N2, %0"
855   [(set_attr "type" "arith_media")])
856
857 (define_insn "movdicc_true"
858   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
859         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
860                              (const_int 0))
861          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
862          (match_operand:DI 3 "arith_reg_operand" "0")))]
863   "TARGET_SHMEDIA"
864   "cmvne        %1, %N2, %0"
865   [(set_attr "type" "arith_media")])
866
867 (define_expand "movdicc"
868   [(set (match_operand:DI 0 "register_operand" "")
869         (if_then_else:DI (match_operand 1 "comparison_operator" "")
870                          (match_operand:DI 2 "register_operand" "")
871                          (match_operand:DI 3 "register_operand" "")))]
872   "TARGET_SHMEDIA"
873   "
874 {
875   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
876       && GET_MODE (sh_compare_op0) == DImode
877       && sh_compare_op1 == const0_rtx)
878     operands[1] = gen_rtx (GET_CODE (operands[1]), VOIDmode,
879                            sh_compare_op0, sh_compare_op1);
880   else
881     {
882       rtx tmp;
883
884       if (no_new_pseudos)
885         FAIL;
886
887       tmp = gen_reg_rtx (DImode);
888
889       switch (GET_CODE (operands[1]))
890         {
891         case EQ:
892           emit_insn (gen_seq (tmp));
893           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
894           break;
895
896         case NE:
897           emit_insn (gen_seq (tmp));
898           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
899           break;
900
901         case GT:
902           emit_insn (gen_sgt (tmp));
903           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
904           break;
905
906         case LT:
907           emit_insn (gen_slt (tmp));
908           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
909           break;
910
911         case GE:
912           emit_insn (gen_slt (tmp));
913           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
914           break;
915
916         case LE:
917           emit_insn (gen_sgt (tmp));
918           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
919           break;
920
921         case GTU:
922           emit_insn (gen_sgtu (tmp));
923           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
924           break;
925
926         case LTU:
927           emit_insn (gen_sltu (tmp));
928           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
929           break;
930
931         case GEU:
932           emit_insn (gen_sltu (tmp));
933           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
934           break;
935
936         case LEU:
937           emit_insn (gen_sgtu (tmp));
938           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
939           break;
940
941         case UNORDERED:
942           emit_insn (gen_sunordered (tmp));
943           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
944           break;
945
946         case ORDERED:
947           emit_insn (gen_sunordered (tmp));
948           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
949           break;
950
951         case UNEQ:
952         case UNGE:
953         case UNGT:
954         case UNLE:
955         case UNLT:
956         case LTGT:
957           FAIL;
958
959         default:
960           abort ();
961         }
962     }
963 }")
964 \f
965 ;; -------------------------------------------------------------------------
966 ;; Addition instructions
967 ;; -------------------------------------------------------------------------
968
969 (define_expand "adddi3"
970   [(set (match_operand:DI 0 "arith_reg_operand" "")
971         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
972                  (match_operand:DI 2 "arith_operand" "")))]
973   ""
974   "
975 {
976   if (TARGET_SH1)
977     {
978       if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
979         FAIL;
980       operands[2] = force_reg (DImode, operands[2]);
981       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
982       DONE;
983     }
984 }")
985
986 (define_insn "*adddi3_media"
987   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
988         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
989                  (match_operand:DI 2 "arith_operand" "r,P")))]
990   "TARGET_SHMEDIA"
991   "@
992         add     %1, %2, %0
993         addi    %1, %2, %0"
994   [(set_attr "type" "arith_media")])
995
996 (define_insn "adddi3z_media"
997   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
998         (zero_extend:DI
999          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1000                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1001   "TARGET_SHMEDIA"
1002   "addz.l       %1, %N2, %0"
1003   [(set_attr "type" "arith_media")])
1004
1005 (define_insn "adddi3_compact"
1006   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1007         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1008                  (match_operand:DI 2 "arith_reg_operand" "r")))
1009    (clobber (reg:SI T_REG))]
1010   "TARGET_SH1"
1011   "#"
1012   [(set_attr "length" "6")])
1013
1014 (define_split
1015   [(set (match_operand:DI 0 "arith_reg_operand" "")
1016         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1017                  (match_operand:DI 2 "arith_reg_operand" "")))
1018    (clobber (reg:SI T_REG))]
1019   "TARGET_SH1 && reload_completed"
1020   [(const_int 0)]
1021   "
1022 {
1023   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1024   high0 = gen_rtx_REG (SImode,
1025                        true_regnum (operands[0])
1026                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1027   high2 = gen_rtx_REG (SImode,
1028                        true_regnum (operands[2])
1029                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1030   emit_insn (gen_clrt ());
1031   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1032   emit_insn (gen_addc1 (high0, high0, high2));
1033   DONE;
1034 }")
1035
1036 (define_insn "addc"
1037   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1038         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1039                           (match_operand:SI 2 "arith_reg_operand" "r"))
1040                  (reg:SI T_REG)))
1041    (set (reg:SI T_REG)
1042         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1043   "TARGET_SH1"
1044   "addc %2,%0"
1045   [(set_attr "type" "arith")])
1046
1047 (define_insn "addc1"
1048   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1049         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1050                           (match_operand:SI 2 "arith_reg_operand" "r"))
1051                  (reg:SI T_REG)))
1052    (clobber (reg:SI T_REG))]
1053   "TARGET_SH1"
1054   "addc %2,%0"
1055   [(set_attr "type" "arith")])
1056
1057 (define_expand "addsi3"
1058   [(set (match_operand:SI 0 "arith_reg_operand" "")
1059         (plus:SI (match_operand:SI 1 "arith_operand" "")
1060                  (match_operand:SI 2 "arith_operand" "")))]
1061   ""
1062   "
1063 {
1064   if (TARGET_SHMEDIA)
1065     operands[1] = force_reg (SImode, operands[1]);
1066 }")
1067
1068 (define_insn "addsi3_media"
1069   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
1070         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1071                  (match_operand:SI 2 "arith_operand" "r,P")))]
1072   "TARGET_SHMEDIA"
1073   "@
1074         add.l   %1, %2, %0
1075         addi.l  %1, %2, %0"
1076   [(set_attr "type" "arith_media")])
1077
1078 (define_insn "*addsi3_compact"
1079   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1080         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1081                  (match_operand:SI 2 "arith_operand" "rI")))]
1082   "TARGET_SH1"
1083   "add  %2,%0"
1084   [(set_attr "type" "arith")])
1085
1086 ;; -------------------------------------------------------------------------
1087 ;; Subtraction instructions
1088 ;; -------------------------------------------------------------------------
1089
1090 (define_expand "subdi3"
1091   [(set (match_operand:DI 0 "arith_reg_operand" "")
1092         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1093                   (match_operand:DI 2 "arith_reg_operand" "")))]
1094   ""
1095   "
1096 {
1097   if (TARGET_SH1)
1098     {
1099       operands[1] = force_reg (DImode, operands[1]);
1100       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1101       DONE;
1102     }
1103 }")
1104
1105 (define_insn "*subdi3_media"
1106   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1107         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1108                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1109   "TARGET_SHMEDIA"
1110   "sub  %N1, %2, %0"
1111   [(set_attr "type" "arith_media")])
1112
1113 (define_insn "subdi3_compact"
1114   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1115         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1116                  (match_operand:DI 2 "arith_reg_operand" "r")))
1117    (clobber (reg:SI T_REG))]
1118   "TARGET_SH1"
1119   "#"
1120   [(set_attr "length" "6")])
1121
1122 (define_split
1123   [(set (match_operand:DI 0 "arith_reg_operand" "")
1124         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1125                   (match_operand:DI 2 "arith_reg_operand" "")))
1126    (clobber (reg:SI T_REG))]
1127   "TARGET_SH1 && reload_completed"
1128   [(const_int 0)]
1129   "
1130 {
1131   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1132   high0 = gen_rtx_REG (SImode,
1133                        true_regnum (operands[0])
1134                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1135   high2 = gen_rtx_REG (SImode,
1136                        true_regnum (operands[2])
1137                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1138   emit_insn (gen_clrt ());
1139   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1140   emit_insn (gen_subc1 (high0, high0, high2));
1141   DONE;
1142 }")
1143
1144 (define_insn "subc"
1145   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1146         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1147                             (match_operand:SI 2 "arith_reg_operand" "r"))
1148                   (reg:SI T_REG)))
1149    (set (reg:SI T_REG)
1150         (gtu:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1151   "TARGET_SH1"
1152   "subc %2,%0"
1153   [(set_attr "type" "arith")])
1154
1155 (define_insn "subc1"
1156   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1157         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1158                             (match_operand:SI 2 "arith_reg_operand" "r"))
1159                   (reg:SI T_REG)))
1160    (clobber (reg:SI T_REG))]
1161   "TARGET_SH1"
1162   "subc %2,%0"
1163   [(set_attr "type" "arith")])
1164
1165 (define_insn "*subsi3_internal"
1166   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1167         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1168                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1169   "TARGET_SH1"
1170   "sub  %2,%0"
1171   [(set_attr "type" "arith")])
1172
1173 (define_insn "*subsi3_media"
1174   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1175         (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN")
1176                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1177   "TARGET_SHMEDIA"
1178   "sub.l        %N1, %2, %0"
1179   [(set_attr "type" "arith_media")])
1180
1181 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1182 ;; will sometimes save one instruction.  Otherwise we might get
1183 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1184 ;; are the same.
1185
1186 (define_expand "subsi3"
1187   [(set (match_operand:SI 0 "arith_reg_operand" "")
1188         (minus:SI (match_operand:SI 1 "arith_operand" "")
1189                   (match_operand:SI 2 "arith_reg_operand" "")))]
1190   ""
1191   "
1192 {
1193   if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1194     {
1195       emit_insn (gen_negsi2 (operands[0], operands[2]));
1196       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1197       DONE;
1198     }
1199   if (TARGET_SHMEDIA)
1200     {
1201       if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1202         FAIL;
1203       if (operands[1] != const0_rtx)
1204         operands[1] = force_reg (SImode, operands[1]);
1205     }
1206 }")
1207 \f
1208 ;; -------------------------------------------------------------------------
1209 ;; Division instructions
1210 ;; -------------------------------------------------------------------------
1211
1212 ;; We take advantage of the library routines which don't clobber as many
1213 ;; registers as a normal function call would.
1214
1215 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1216 ;; also has an effect on the register that holds the address of the sfunc.
1217 ;; To make this work, we have an extra dummy insn that shows the use
1218 ;; of this register for reorg.
1219
1220 (define_insn "use_sfunc_addr"
1221   [(set (reg:SI PR_REG)
1222         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1223   "TARGET_SH1"
1224   ""
1225   [(set_attr "length" "0")])
1226
1227 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1228 ;; hard register 0.  If we used hard register 0, then the next instruction
1229 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1230 ;; gets allocated to a stack slot that needs its address reloaded, then
1231 ;; there is nothing to prevent reload from using r0 to reload the address.
1232 ;; This reload would clobber the value in r0 we are trying to store.
1233 ;; If we let reload allocate r0, then this problem can never happen.
1234
1235 (define_insn "udivsi3_i1"
1236   [(set (match_operand:SI 0 "register_operand" "=z")
1237         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1238    (clobber (reg:SI T_REG))
1239    (clobber (reg:SI PR_REG))
1240    (clobber (reg:SI R4_REG))
1241    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1242   "TARGET_SH1 && ! TARGET_SH4"
1243   "jsr  @%1%#"
1244   [(set_attr "type" "sfunc")
1245    (set_attr "needs_delay_slot" "yes")])
1246
1247 ; Since shmedia-nofpu code could be linked against shcompact code, and
1248 ; the udivsi3 libcall has the same name, we must consider all registers
1249 ; clobbered that are in the union of the registers clobbered by the
1250 ; shmedia and the shcompact implementation.  Note, if the shcompact
1251 ; implemenation actually used shcompact code, we'd need to clobber
1252 ; also r23 and fr23.
1253 (define_insn "udivsi3_i1_media"
1254   [(set (match_operand:SI 0 "register_operand" "=z")
1255         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1256    (clobber (reg:SI T_MEDIA_REG))
1257    (clobber (reg:SI PR_MEDIA_REG))
1258    (clobber (reg:SI R20_REG))
1259    (clobber (reg:SI R21_REG))
1260    (clobber (reg:SI R22_REG))
1261    (clobber (reg:DI TR0_REG))
1262    (clobber (reg:DI TR1_REG))
1263    (clobber (reg:DI TR2_REG))
1264    (use (match_operand:DI 1 "target_operand" "b"))]
1265   "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1266   "blink        %1, r18"
1267   [(set_attr "type" "sfunc")
1268    (set_attr "needs_delay_slot" "yes")])
1269
1270 (define_expand "udivsi3_i4_media"
1271   [(set (match_dup 3)
1272         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1273    (set (match_dup 4)
1274         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1275    (set (match_dup 5) (float:DF (match_dup 3)))
1276    (set (match_dup 6) (float:DF (match_dup 4)))
1277    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1278    (set (match_dup 8) (fix:DI (match_dup 7)))
1279    (set (match_operand:SI 0 "register_operand" "")
1280         (truncate:SI (match_dup 8)))]
1281   "TARGET_SHMEDIA_FPU"
1282   "
1283 {
1284   operands[3] = gen_reg_rtx (DImode);
1285   operands[4] = gen_reg_rtx (DImode);
1286   operands[5] = gen_reg_rtx (DFmode);
1287   operands[6] = gen_reg_rtx (DFmode);
1288   operands[7] = gen_reg_rtx (DFmode);
1289   operands[8] = gen_reg_rtx (DImode);
1290 }")
1291
1292 (define_insn "udivsi3_i4"
1293   [(set (match_operand:SI 0 "register_operand" "=y")
1294         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1295    (clobber (reg:SI T_REG))
1296    (clobber (reg:SI PR_REG))
1297    (clobber (reg:DF DR0_REG))
1298    (clobber (reg:DF DR2_REG))
1299    (clobber (reg:DF DR4_REG))
1300    (clobber (reg:SI R0_REG))
1301    (clobber (reg:SI R1_REG))
1302    (clobber (reg:SI R4_REG))
1303    (clobber (reg:SI R5_REG))
1304    (use (reg:PSI FPSCR_REG))
1305    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1306   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1307   "jsr  @%1%#"
1308   [(set_attr "type" "sfunc")
1309    (set_attr "fp_mode" "double")
1310    (set_attr "needs_delay_slot" "yes")])
1311
1312 (define_insn "udivsi3_i4_single"
1313   [(set (match_operand:SI 0 "register_operand" "=y")
1314         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1315    (clobber (reg:SI T_REG))
1316    (clobber (reg:SI PR_REG))
1317    (clobber (reg:DF DR0_REG))
1318    (clobber (reg:DF DR2_REG))
1319    (clobber (reg:DF DR4_REG))
1320    (clobber (reg:SI R0_REG))
1321    (clobber (reg:SI R1_REG))
1322    (clobber (reg:SI R4_REG))
1323    (clobber (reg:SI R5_REG))
1324    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1325   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1326   "jsr  @%1%#"
1327   [(set_attr "type" "sfunc")
1328    (set_attr "needs_delay_slot" "yes")])
1329
1330 (define_expand "udivsi3"
1331   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1332    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1333    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1334    (parallel [(set (match_operand:SI 0 "register_operand" "")
1335                    (udiv:SI (reg:SI R4_REG)
1336                             (reg:SI R5_REG)))
1337               (clobber (reg:SI T_REG))
1338               (clobber (reg:SI PR_REG))
1339               (clobber (reg:SI R4_REG))
1340               (use (match_dup 3))])]
1341   ""
1342   "
1343 {
1344   rtx first = 0, last;
1345
1346   operands[3] = gen_reg_rtx (Pmode);
1347   /* Emit the move of the address to a pseudo outside of the libcall.  */
1348   if (TARGET_HARD_SH4 && TARGET_SH3E)
1349     {
1350       emit_move_insn (operands[3],
1351                       gen_rtx_SYMBOL_REF (SImode, \"__udivsi3_i4\"));
1352       if (TARGET_FPU_SINGLE)
1353         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1354       else
1355         last = gen_udivsi3_i4 (operands[0], operands[3]);
1356     }
1357   else if (TARGET_SHMEDIA_FPU)
1358     {
1359       operands[1] = force_reg (SImode, operands[1]);
1360       operands[2] = force_reg (SImode, operands[2]);
1361       last = gen_udivsi3_i4_media (operands[0], operands[1], operands[2]);
1362       first = last;
1363     }
1364   else if (TARGET_SH5)
1365     {
1366       emit_move_insn (operands[3],
1367                       gen_rtx_SYMBOL_REF (Pmode,
1368                                           (TARGET_FPU_ANY
1369                                            ? \"__udivsi3_i4\"
1370                                            : \"__udivsi3\")));
1371
1372       if (TARGET_SHMEDIA)
1373         last = gen_udivsi3_i1_media (operands[0],
1374                                      Pmode == DImode
1375                                      ? operands[3]
1376                                      : gen_rtx_SUBREG (DImode, operands[3],
1377                                                        0));
1378       else if (TARGET_FPU_ANY)
1379         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1380       else
1381         last = gen_udivsi3_i1 (operands[0], operands[3]);
1382     }
1383   else
1384     {
1385       emit_move_insn (operands[3],
1386                       gen_rtx_SYMBOL_REF (SImode, \"__udivsi3\"));
1387       last = gen_udivsi3_i1 (operands[0], operands[3]);
1388     }
1389   if (! first)
1390     {
1391       first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1392       emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1393     }
1394   last = emit_insn (last);
1395   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1396      invariant code motion can move it.  */
1397   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1398   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1399   DONE;
1400 }")
1401
1402 (define_insn "divsi3_i1"
1403   [(set (match_operand:SI 0 "register_operand" "=z")
1404         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1405    (clobber (reg:SI T_REG))
1406    (clobber (reg:SI PR_REG))
1407    (clobber (reg:SI R1_REG))
1408    (clobber (reg:SI R2_REG))
1409    (clobber (reg:SI R3_REG))
1410    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1411   "TARGET_SH1 && ! TARGET_SH4"
1412   "jsr  @%1%#"
1413   [(set_attr "type" "sfunc")
1414    (set_attr "needs_delay_slot" "yes")])
1415
1416 ; Since shmedia-nofpu code could be linked against shcompact code, and
1417 ; the sdivsi3 libcall has the same name, we must consider all registers
1418 ; clobbered that are in the union of the registers clobbered by the
1419 ; shmedia and the shcompact implementation.  Note, if the shcompact
1420 ; implemenation actually used shcompact code, we'd need to clobber
1421 ; also r22, r23 and fr23.
1422 (define_insn "divsi3_i1_media"
1423   [(set (match_operand:SI 0 "register_operand" "=z")
1424         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1425    (clobber (reg:SI T_MEDIA_REG))
1426    (clobber (reg:SI PR_MEDIA_REG))
1427    (clobber (reg:SI R1_REG))
1428    (clobber (reg:SI R2_REG))
1429    (clobber (reg:SI R3_REG))
1430    (clobber (reg:SI R20_REG))
1431    (clobber (reg:SI R21_REG))
1432    (clobber (reg:DI TR0_REG))
1433    (clobber (reg:DI TR1_REG))
1434    (clobber (reg:DI TR2_REG))
1435    (use (match_operand:DI 1 "target_operand" "b"))]
1436   "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1437   "blink        %1, r18"
1438   [(set_attr "type" "sfunc")])
1439
1440 (define_expand "divsi3_i4_media"
1441   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1442    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1443    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1444    (set (match_operand:SI 0 "register_operand" "=r")
1445         (fix:SI (match_dup 5)))]
1446   "TARGET_SHMEDIA_FPU"
1447   "
1448 {
1449   operands[3] = gen_reg_rtx (DFmode);
1450   operands[4] = gen_reg_rtx (DFmode);
1451   operands[5] = gen_reg_rtx (DFmode);
1452 }")
1453
1454 (define_insn "divsi3_i4"
1455   [(set (match_operand:SI 0 "register_operand" "=y")
1456         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1457    (clobber (reg:SI PR_REG))
1458    (clobber (reg:DF DR0_REG))
1459    (clobber (reg:DF DR2_REG))
1460    (use (reg:PSI FPSCR_REG))
1461    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1462   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1463   "jsr  @%1%#"
1464   [(set_attr "type" "sfunc")
1465    (set_attr "fp_mode" "double")
1466    (set_attr "needs_delay_slot" "yes")])
1467
1468 (define_insn "divsi3_i4_single"
1469   [(set (match_operand:SI 0 "register_operand" "=y")
1470         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1471    (clobber (reg:SI PR_REG))
1472    (clobber (reg:DF DR0_REG))
1473    (clobber (reg:DF DR2_REG))
1474    (clobber (reg:SI R2_REG))
1475    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1476   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1477   "jsr  @%1%#"
1478   [(set_attr "type" "sfunc")
1479    (set_attr "needs_delay_slot" "yes")])
1480
1481 (define_expand "divsi3"
1482   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1483    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1484    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1485    (parallel [(set (match_operand:SI 0 "register_operand" "")
1486                    (div:SI (reg:SI R4_REG)
1487                            (reg:SI R5_REG)))
1488               (clobber (reg:SI T_REG))
1489               (clobber (reg:SI PR_REG))
1490               (clobber (reg:SI R1_REG))
1491               (clobber (reg:SI R2_REG))
1492               (clobber (reg:SI R3_REG))
1493               (use (match_dup 3))])]
1494   ""
1495   "
1496 {
1497   rtx first = 0, last;
1498
1499   operands[3] = gen_reg_rtx (Pmode);
1500   /* Emit the move of the address to a pseudo outside of the libcall.  */
1501   if (TARGET_HARD_SH4 && TARGET_SH3E)
1502     {
1503       emit_move_insn (operands[3],
1504                       gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3_i4\"));
1505       if (TARGET_FPU_SINGLE)
1506         last = gen_divsi3_i4_single (operands[0], operands[3]);
1507       else
1508         last = gen_divsi3_i4 (operands[0], operands[3]);
1509     }
1510   else if (TARGET_SHMEDIA_FPU)
1511     {
1512       operands[1] = force_reg (SImode, operands[1]);
1513       operands[2] = force_reg (SImode, operands[2]);
1514       last = gen_divsi3_i4_media (operands[0], operands[1], operands[2]);
1515       first = last;
1516     }
1517   else if (TARGET_SH5)
1518     {
1519       emit_move_insn (operands[3],
1520                       gen_rtx_SYMBOL_REF (Pmode,
1521                                           (TARGET_FPU_ANY
1522                                            ? \"__sdivsi3_i4\"
1523                                            : \"__sdivsi3\")));
1524
1525       if (TARGET_SHMEDIA)
1526         last = gen_divsi3_i1_media (operands[0],
1527                                     Pmode == DImode
1528                                     ? operands[3]
1529                                     : gen_rtx_SUBREG (DImode, operands[3],
1530                                                       0));
1531       else if (TARGET_FPU_ANY)
1532         last = gen_divsi3_i4_single (operands[0], operands[3]);
1533       else
1534         last = gen_divsi3_i1 (operands[0], operands[3]);
1535     }
1536   else
1537     {
1538       emit_move_insn (operands[3], gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3\"));
1539       last = gen_divsi3_i1 (operands[0], operands[3]);
1540     }
1541   if (! first)
1542     {
1543       first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1544       emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1545     }
1546   last = emit_insn (last);
1547   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1548      invariant code motion can move it.  */
1549   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1550   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1551   DONE;
1552 }")
1553 \f
1554 ;; -------------------------------------------------------------------------
1555 ;; Multiplication instructions
1556 ;; -------------------------------------------------------------------------
1557
1558 (define_insn "umulhisi3_i"
1559   [(set (reg:SI MACL_REG)
1560         (mult:SI (zero_extend:SI
1561                   (match_operand:HI 0 "arith_reg_operand" "r"))
1562                  (zero_extend:SI
1563                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
1564   "TARGET_SH1"
1565   "mulu.w       %1,%0"
1566   [(set_attr "type" "smpy")])
1567
1568 (define_insn "mulhisi3_i"
1569   [(set (reg:SI MACL_REG)
1570         (mult:SI (sign_extend:SI
1571                   (match_operand:HI 0 "arith_reg_operand" "r"))
1572                  (sign_extend:SI
1573                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
1574   "TARGET_SH1"
1575   "muls.w       %1,%0"
1576   [(set_attr "type" "smpy")])
1577
1578 (define_expand "mulhisi3"
1579   [(set (reg:SI MACL_REG)
1580         (mult:SI (sign_extend:SI
1581                   (match_operand:HI 1 "arith_reg_operand" ""))
1582                  (sign_extend:SI
1583                   (match_operand:HI 2 "arith_reg_operand" ""))))
1584    (set (match_operand:SI 0 "arith_reg_operand" "")
1585         (reg:SI MACL_REG))]
1586   "TARGET_SH1"
1587   "
1588 {
1589   rtx first, last;
1590
1591   first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1592   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1593   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1594      invariant code motion can move it.  */
1595   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1596   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1597   /* expand_binop can't find a suitable code in umul_widen_optab to
1598      make a REG_EQUAL note from, so make one here.
1599      See also smulsi3_highpart.
1600      ??? Alternatively, we could put this at the calling site of expand_binop,
1601      i.e. expand_expr.  */
1602   REG_NOTES (last)
1603     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1604                          REG_NOTES (last));
1605   DONE;
1606 }")
1607
1608 (define_expand "umulhisi3"
1609   [(set (reg:SI MACL_REG)
1610         (mult:SI (zero_extend:SI
1611                   (match_operand:HI 1 "arith_reg_operand" ""))
1612                  (zero_extend:SI
1613                   (match_operand:HI 2 "arith_reg_operand" ""))))
1614    (set (match_operand:SI 0 "arith_reg_operand" "")
1615         (reg:SI MACL_REG))]
1616   "TARGET_SH1"
1617   "
1618 {
1619   rtx first, last;
1620
1621   first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1622   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1623   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1624      invariant code motion can move it.  */
1625   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1626   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1627   /* expand_binop can't find a suitable code in umul_widen_optab to
1628      make a REG_EQUAL note from, so make one here.
1629      See also smulsi3_highpart.
1630      ??? Alternatively, we could put this at the calling site of expand_binop,
1631      i.e. expand_expr.  */
1632   REG_NOTES (last)
1633     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1634                          REG_NOTES (last));
1635   DONE;
1636 }")
1637
1638 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1639 ;; a call to a routine which clobbers known registers.
1640
1641 (define_insn ""
1642   [(set (match_operand:SI 1 "register_operand" "=z")
1643         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1644    (clobber (reg:SI MACL_REG))
1645    (clobber (reg:SI T_REG))
1646    (clobber (reg:SI PR_REG))
1647    (clobber (reg:SI R3_REG))
1648    (clobber (reg:SI R2_REG))
1649    (clobber (reg:SI R1_REG))
1650    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1651   "TARGET_SH1"
1652   "jsr  @%0%#"
1653   [(set_attr "type" "sfunc")
1654    (set_attr "needs_delay_slot" "yes")])
1655
1656 (define_expand "mulsi3_call"
1657   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1658    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1659    (parallel[(set (match_operand:SI 0 "register_operand" "")
1660                   (mult:SI (reg:SI R4_REG)
1661                            (reg:SI R5_REG)))
1662              (clobber (reg:SI MACL_REG))
1663              (clobber (reg:SI T_REG))
1664              (clobber (reg:SI PR_REG))
1665              (clobber (reg:SI R3_REG))
1666              (clobber (reg:SI R2_REG))
1667              (clobber (reg:SI R1_REG))
1668              (use (match_operand:SI 3 "register_operand" ""))])]
1669   "TARGET_SH1"
1670   "")
1671
1672 (define_insn "mul_l"
1673   [(set (reg:SI MACL_REG)
1674         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1675                  (match_operand:SI 1 "arith_reg_operand" "r")))]
1676   "TARGET_SH2"
1677   "mul.l        %1,%0"
1678   [(set_attr "type" "dmpy")])
1679
1680 (define_expand "mulsi3"
1681   [(set (reg:SI MACL_REG)
1682         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
1683                   (match_operand:SI 2 "arith_reg_operand" "")))
1684    (set (match_operand:SI 0 "arith_reg_operand" "")
1685         (reg:SI MACL_REG))]
1686   "TARGET_SH1"
1687   "
1688 {
1689   rtx first, last;
1690
1691   if (!TARGET_SH2)
1692     {
1693       /* The address must be set outside the libcall,
1694          since it goes into a pseudo.  */
1695       rtx sym = gen_rtx_SYMBOL_REF (SImode, \"__mulsi3\");
1696       rtx addr = force_reg (SImode, sym);
1697       rtx insns = gen_mulsi3_call (operands[0], operands[1],
1698                                    operands[2], addr);
1699       first = insns;
1700       last = emit_insn (insns);
1701     }
1702   else
1703     {
1704       rtx macl = gen_rtx_REG (SImode, MACL_REG);
1705
1706       first = emit_insn (gen_mul_l (operands[1], operands[2]));
1707       /* consec_sets_giv can only recognize the first insn that sets a
1708          giv as the giv insn.  So we must tag this also with a REG_EQUAL
1709          note.  */
1710       last = emit_insn (gen_movsi_i ((operands[0]), macl));
1711     }
1712   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1713      invariant code motion can move it.  */
1714   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1715   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1716   DONE;
1717 }")
1718
1719 (define_insn "mulsidi3_i"
1720   [(set (reg:SI MACH_REG)
1721         (truncate:SI
1722          (lshiftrt:DI
1723           (mult:DI
1724            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1725            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1726           (const_int 32))))
1727    (set (reg:SI MACL_REG)
1728         (mult:SI (match_dup 0)
1729                  (match_dup 1)))]
1730   "TARGET_SH2"
1731   "dmuls.l      %1,%0"
1732   [(set_attr "type" "dmpy")])
1733
1734 (define_expand "mulsidi3"
1735   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1736         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1737                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1738   "TARGET_SH2 || TARGET_SHMEDIA"
1739   "
1740 {
1741   if (TARGET_SH2)
1742     {
1743        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1744                                         operands[2]));
1745        DONE;
1746     }
1747 }")
1748
1749 (define_insn "mulsidi3_media"
1750   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1751         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1752                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1753   "TARGET_SHMEDIA"
1754   "muls.l       %1, %2, %0"
1755   [(set_attr "type" "dmpy_media")])
1756
1757 (define_insn "mulsidi3_compact"
1758   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1759         (mult:DI
1760          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1761          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1762    (clobber (reg:SI MACH_REG))
1763    (clobber (reg:SI MACL_REG))]
1764   "TARGET_SH2"
1765   "#")
1766
1767 (define_split
1768   [(set (match_operand:DI 0 "arith_reg_operand" "")
1769         (mult:DI
1770          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1771          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1772    (clobber (reg:SI MACH_REG))
1773    (clobber (reg:SI MACL_REG))]
1774   "TARGET_SH2"
1775   [(const_int 0)]
1776   "
1777 {
1778   rtx low_dst = gen_lowpart (SImode, operands[0]);
1779   rtx high_dst = gen_highpart (SImode, operands[0]);
1780
1781   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1782
1783   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1784   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1785   /* We need something to tag the possible REG_EQUAL notes on to.  */
1786   emit_move_insn (operands[0], operands[0]);
1787   DONE;
1788 }")
1789
1790 (define_insn "umulsidi3_i"
1791   [(set (reg:SI MACH_REG)
1792         (truncate:SI
1793          (lshiftrt:DI
1794           (mult:DI
1795            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1796            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1797           (const_int 32))))
1798    (set (reg:SI MACL_REG)
1799         (mult:SI (match_dup 0)
1800                  (match_dup 1)))]
1801   "TARGET_SH2"
1802   "dmulu.l      %1,%0"
1803   [(set_attr "type" "dmpy")])
1804
1805 (define_expand "umulsidi3"
1806   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1807         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1808                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1809   "TARGET_SH2 || TARGET_SHMEDIA"
1810   "
1811 {
1812   if (TARGET_SH2)
1813     {
1814        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1815                                          operands[2]));
1816        DONE;
1817     }
1818 }")
1819
1820 (define_insn "umulsidi3_media"
1821   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1822         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1823                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1824   "TARGET_SHMEDIA"
1825   "mulu.l       %1, %2, %0"
1826   [(set_attr "type" "dmpy_media")])
1827
1828 (define_insn "umulsidi3_compact"
1829   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1830         (mult:DI
1831          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1832          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1833    (clobber (reg:SI MACH_REG))
1834    (clobber (reg:SI MACL_REG))]
1835   "TARGET_SH2"
1836   "#")
1837
1838 (define_split
1839   [(set (match_operand:DI 0 "arith_reg_operand" "")
1840         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1841                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1842    (clobber (reg:SI MACH_REG))
1843    (clobber (reg:SI MACL_REG))]
1844   "TARGET_SH2"
1845   [(const_int 0)]
1846   "
1847 {
1848   rtx low_dst = gen_lowpart (SImode, operands[0]);
1849   rtx high_dst = gen_highpart (SImode, operands[0]);
1850
1851   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1852
1853   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1854   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1855   /* We need something to tag the possible REG_EQUAL notes on to.  */
1856   emit_move_insn (operands[0], operands[0]);
1857   DONE;
1858 }")
1859
1860 (define_insn "smulsi3_highpart_i"
1861   [(set (reg:SI MACH_REG)
1862         (truncate:SI
1863          (lshiftrt:DI
1864           (mult:DI
1865            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1866            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1867           (const_int 32))))
1868    (clobber (reg:SI MACL_REG))]
1869   "TARGET_SH2"
1870   "dmuls.l      %1,%0"
1871   [(set_attr "type" "dmpy")])
1872
1873 (define_expand "smulsi3_highpart"
1874   [(parallel
1875     [(set (reg:SI MACH_REG)
1876           (truncate:SI
1877            (lshiftrt:DI
1878             (mult:DI
1879              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1880              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1881             (const_int 32))))
1882     (clobber (reg:SI MACL_REG))])
1883    (set (match_operand:SI 0 "arith_reg_operand" "")
1884         (reg:SI MACH_REG))]
1885   "TARGET_SH2"
1886   "
1887 {
1888   rtx first, last;
1889
1890   first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1891   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1892   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1893      invariant code motion can move it.  */
1894   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1895   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1896   /* expand_binop can't find a suitable code in mul_highpart_optab to
1897      make a REG_EQUAL note from, so make one here.
1898      See also {,u}mulhisi.
1899      ??? Alternatively, we could put this at the calling site of expand_binop,
1900      i.e. expand_mult_highpart.  */
1901   REG_NOTES (last)
1902     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1903                          REG_NOTES (last));
1904   DONE;
1905 }")
1906
1907 (define_insn "umulsi3_highpart_i"
1908   [(set (reg:SI MACH_REG)
1909         (truncate:SI
1910          (lshiftrt:DI
1911           (mult:DI
1912            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1913            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1914           (const_int 32))))
1915    (clobber (reg:SI MACL_REG))]
1916   "TARGET_SH2"
1917   "dmulu.l      %1,%0"
1918   [(set_attr "type" "dmpy")])
1919
1920 (define_expand "umulsi3_highpart"
1921   [(parallel
1922     [(set (reg:SI MACH_REG)
1923           (truncate:SI
1924            (lshiftrt:DI
1925             (mult:DI
1926              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1927              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1928             (const_int 32))))
1929     (clobber (reg:SI MACL_REG))])
1930    (set (match_operand:SI 0 "arith_reg_operand" "")
1931         (reg:SI MACH_REG))]
1932   "TARGET_SH2"
1933   "
1934 {
1935   rtx first, last;
1936
1937   first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1938   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1939   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1940      invariant code motion can move it.  */
1941   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1942   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1943   DONE;
1944 }")
1945 \f
1946 ;; -------------------------------------------------------------------------
1947 ;; Logical operations
1948 ;; -------------------------------------------------------------------------
1949
1950 (define_insn "*andsi3_compact"
1951   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1952         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1953                 (match_operand:SI 2 "logical_operand" "r,L")))]
1954   "TARGET_SH1"
1955   "and  %2,%0"
1956   [(set_attr "type" "arith")])
1957
1958 ;; If the constant is 255, then emit an extu.b instruction instead of an
1959 ;; and, since that will give better code.
1960
1961 (define_expand "andsi3"
1962   [(set (match_operand:SI 0 "arith_reg_operand" "")
1963         (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1964                 (match_operand:SI 2 "logical_operand" "")))]
1965   "TARGET_SH1"
1966   "
1967 {
1968   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1969     {
1970       emit_insn (gen_zero_extendqisi2 (operands[0],
1971                                        gen_lowpart (QImode, operands[1])));
1972       DONE;
1973     }
1974 }")
1975
1976 (define_insn_and_split "anddi3"
1977   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1978         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
1979                 (match_operand:DI 2 "and_operand" "r,P,n")))]
1980   "TARGET_SHMEDIA"
1981   "@
1982         and     %1, %2, %0
1983         andi    %1, %2, %0
1984         #"
1985   "reload_completed
1986    && ! logical_operand (operands[2], DImode)"
1987   [(const_int 0)]
1988   "
1989 {
1990   if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
1991     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
1992   else
1993     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
1994   DONE;
1995 }"
1996   [(set_attr "type" "arith_media")])
1997
1998 (define_insn "andcdi3"
1999   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2000         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
2001                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
2002   "TARGET_SHMEDIA"
2003   "andc %1,%2,%0"
2004   [(set_attr "type" "arith_media")])
2005
2006 (define_insn "iorsi3"
2007   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
2008         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2009                 (match_operand:SI 2 "logical_operand" "r,L")))]
2010   "TARGET_SH1"
2011   "or   %2,%0"
2012   [(set_attr "type" "arith")])
2013
2014 (define_insn "iordi3"
2015   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2016         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2017                 (match_operand:DI 2 "logical_operand" "r,P")))]
2018   "TARGET_SHMEDIA"
2019   "@
2020         or      %1, %2, %0
2021         ori     %1, %2, %0"
2022   [(set_attr "type" "arith_media")])
2023
2024 (define_insn "xorsi3"
2025   [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
2026         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2027                 (match_operand:SI 2 "logical_operand" "L,r")))]
2028   "TARGET_SH1"
2029   "xor  %2,%0"
2030   [(set_attr "type" "arith")])
2031
2032 (define_insn "xordi3"
2033   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2034         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2035                 (match_operand:DI 2 "shmedia_6bit_operand" "r,O")))]
2036   "TARGET_SHMEDIA"
2037   "@
2038         xor     %1, %2, %0
2039         xori    %1, %2, %0"
2040   [(set_attr "type" "arith_media")])
2041
2042 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
2043 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
2044 (define_split
2045   [(set (match_operand:DI 0 "arith_reg_operand" "")
2046         (sign_extend:DI (match_operator 4 "binary_logical_operator"
2047                           [(match_operand 1 "any_register_operand" "")
2048                            (match_operand 2 "any_register_operand" "")])))]
2049   "TARGET_SHMEDIA"
2050   [(set (match_dup 5) (match_dup 4))
2051    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
2052 "
2053 {
2054   enum machine_mode inmode = GET_MODE (operands[1]);
2055   int regno, offset = 0;
2056
2057   if (GET_CODE (operands[0]) == SUBREG)
2058     {
2059       offset = SUBREG_BYTE (operands[0]);
2060       operands[0] = SUBREG_REG (operands[0]);
2061     }
2062   if (GET_CODE (operands[0]) != REG)
2063     abort ();
2064   if (! TARGET_LITTLE_ENDIAN)
2065     offset += 8 - GET_MODE_SIZE (inmode);
2066   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
2067 }")
2068 \f
2069 ;; -------------------------------------------------------------------------
2070 ;; Shifts and rotates
2071 ;; -------------------------------------------------------------------------
2072
2073 (define_expand "rotldi3"
2074   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2075         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2076                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
2077   "TARGET_SHMEDIA"
2078   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2079
2080 (define_insn "rotldi3_mextr"
2081   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2082         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2083                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
2084   "TARGET_SHMEDIA"
2085   "*
2086 {
2087   static char templ[16];
2088
2089   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2090            8 - (int) (INTVAL (operands[2]) >> 3));
2091   return templ;
2092 }"
2093   [(set_attr "type" "arith_media")])
2094
2095 (define_expand "rotrdi3"
2096   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2097         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2098                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
2099   "TARGET_SHMEDIA"
2100   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2101
2102 (define_insn "rotrdi3_mextr"
2103   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2104         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2105                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
2106   "TARGET_SHMEDIA"
2107   "*
2108 {
2109   static char templ[16];
2110
2111   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2112   return templ;
2113 }"
2114   [(set_attr "type" "arith_media")])
2115
2116 (define_insn "rotlsi3_1"
2117   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2118         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2119                    (const_int 1)))
2120    (set (reg:SI T_REG)
2121         (lshiftrt:SI (match_dup 1) (const_int 31)))]
2122   "TARGET_SH1"
2123   "rotl %0"
2124   [(set_attr "type" "arith")])
2125
2126 (define_insn "rotlsi3_31"
2127   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2128         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2129                    (const_int 31)))
2130    (clobber (reg:SI T_REG))]
2131   "TARGET_SH1"
2132   "rotr %0"
2133   [(set_attr "type" "arith")])
2134
2135 (define_insn "rotlsi3_16"
2136   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2137         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2138                    (const_int 16)))]
2139   "TARGET_SH1"
2140   "swap.w       %1,%0"
2141   [(set_attr "type" "arith")])
2142
2143 (define_expand "rotlsi3"
2144   [(set (match_operand:SI 0 "arith_reg_operand" "")
2145         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2146                    (match_operand:SI 2 "immediate_operand" "")))]
2147   "TARGET_SH1"
2148   "
2149 {
2150   static const char rot_tab[] = {
2151     000, 000, 000, 000, 000, 000, 010, 001,
2152     001, 001, 011, 013, 003, 003, 003, 003,
2153     003, 003, 003, 003, 003, 013, 012, 002,
2154     002, 002, 010, 000, 000, 000, 000, 000,
2155   };
2156
2157   int count, choice;
2158
2159   if (GET_CODE (operands[2]) != CONST_INT)
2160     FAIL;
2161   count = INTVAL (operands[2]);
2162   choice = rot_tab[count];
2163   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2164     FAIL;
2165   choice &= 7;
2166   switch (choice)
2167     {
2168     case 0:
2169       emit_move_insn (operands[0], operands[1]);
2170       count -= (count & 16) * 2;
2171       break;
2172     case 3:
2173      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2174      count -= 16;
2175      break;
2176     case 1:
2177     case 2:
2178       {
2179         rtx parts[2];
2180         parts[0] = gen_reg_rtx (SImode);
2181         parts[1] = gen_reg_rtx (SImode);
2182         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2183         parts[choice-1] = operands[1];
2184         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2185         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2186         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2187         count = (count & ~16) - 8;
2188       }
2189     }
2190
2191   for (; count > 0; count--)
2192     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2193   for (; count < 0; count++)
2194     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2195
2196   DONE;
2197 }")
2198
2199 (define_insn "*rotlhi3_8"
2200   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2201         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2202                    (const_int 8)))]
2203   "TARGET_SH1"
2204   "swap.b       %1,%0"
2205   [(set_attr "type" "arith")])
2206
2207 (define_expand "rotlhi3"
2208   [(set (match_operand:HI 0 "arith_reg_operand" "")
2209         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2210                    (match_operand:HI 2 "immediate_operand" "")))]
2211   "TARGET_SH1"
2212   "
2213 {
2214   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2215     FAIL;
2216 }")
2217
2218 ;;
2219 ;; shift left
2220
2221 ;; This pattern is used by init_expmed for computing the costs of shift
2222 ;; insns.
2223
2224 (define_insn_and_split "ashlsi3_std"
2225   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2226         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2227                    (match_operand:SI 2 "nonmemory_operand" "r,M,K,?ri")))
2228    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2229   "TARGET_SH3
2230    || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2231        && CONST_OK_FOR_K (INTVAL (operands[2])))"
2232   "@
2233    shld %2,%0
2234    add  %0,%0
2235    shll%O2      %0
2236    #"
2237   "TARGET_SH3
2238    && reload_completed
2239    && GET_CODE (operands[2]) == CONST_INT
2240    && ! CONST_OK_FOR_K (INTVAL (operands[2]))"
2241   [(set (match_dup 3) (match_dup 2))
2242    (parallel
2243     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2244      (clobber (match_dup 4))])]
2245   "operands[4] = gen_rtx_SCRATCH (SImode);"
2246   [(set_attr "length" "*,*,*,4")
2247    (set_attr "type" "dyn_shift,arith,arith,arith")])
2248
2249 (define_insn "ashlhi3_k"
2250   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2251         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2252                    (match_operand:HI 2 "const_int_operand" "M,K")))]
2253   "TARGET_SH1 && CONST_OK_FOR_K (INTVAL (operands[2]))"
2254   "@
2255         add     %0,%0
2256         shll%O2 %0"
2257   [(set_attr "type" "arith")])
2258
2259 (define_insn "ashlsi3_n"
2260   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2261         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2262                    (match_operand:SI 2 "const_int_operand" "n")))
2263    (clobber (reg:SI T_REG))]
2264   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2265   "#"
2266   [(set (attr "length")
2267         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2268                (const_string "2")
2269                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2270                (const_string "4")
2271                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2272                (const_string "6")]
2273               (const_string "8")))
2274    (set_attr "type" "arith")])
2275
2276 (define_split
2277   [(set (match_operand:SI 0 "arith_reg_operand" "")
2278         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2279                    (match_operand:SI 2 "const_int_operand" "")))
2280    (clobber (reg:SI T_REG))]
2281   "TARGET_SH1 && reload_completed"
2282   [(use (reg:SI R0_REG))]
2283   "
2284 {
2285   gen_shifty_op (ASHIFT, operands);
2286   DONE;
2287 }")
2288
2289 (define_insn "ashlsi3_media"
2290   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2291         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2292                    (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2293   "TARGET_SHMEDIA"
2294   "@
2295         shlld.l %1, %2, %0
2296         shlli.l %1, %2, %0"
2297   [(set_attr "type" "arith_media")])
2298
2299 (define_expand "ashlsi3"
2300   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2301                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2302                               (match_operand:SI 2 "nonmemory_operand" "")))
2303               (clobber (reg:SI T_REG))])]
2304   ""
2305   "
2306 {
2307   if (TARGET_SHMEDIA)
2308     {
2309       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2310       DONE;
2311     }
2312   if (GET_CODE (operands[2]) == CONST_INT
2313       && sh_dynamicalize_shift_p (operands[2]))
2314     operands[2] = force_reg (SImode, operands[2]);
2315   if (TARGET_SH3)
2316     {
2317       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2318       DONE;
2319     }
2320   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2321     FAIL;
2322 }")
2323
2324 (define_insn "ashlhi3"
2325   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2326         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2327                    (match_operand:HI 2 "const_int_operand" "n")))
2328    (clobber (reg:SI T_REG))]
2329   "TARGET_SH1"
2330   "#"
2331   [(set (attr "length")
2332         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2333                (const_string "2")
2334                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2335                (const_string "4")]
2336               (const_string "6")))
2337    (set_attr "type" "arith")])
2338
2339 (define_split
2340   [(set (match_operand:HI 0 "arith_reg_operand" "")
2341         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2342                    (match_operand:HI 2 "const_int_operand" "")))
2343    (clobber (reg:SI T_REG))]
2344   "TARGET_SH1 && reload_completed"
2345   [(use (reg:SI R0_REG))]
2346   "
2347 {
2348   gen_shifty_hi_op (ASHIFT, operands);
2349   DONE;
2350 }")
2351
2352 ;
2353 ; arithmetic shift right
2354 ;
2355
2356 (define_insn "ashrsi3_k"
2357   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2358         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2359                      (match_operand:SI 2 "const_int_operand" "M")))
2360    (clobber (reg:SI T_REG))]
2361   "TARGET_SH1 && INTVAL (operands[2]) == 1"
2362   "shar %0"
2363   [(set_attr "type" "arith")])
2364
2365 ;; We can't do HImode right shifts correctly unless we start out with an
2366 ;; explicit zero / sign extension; doing that would result in worse overall
2367 ;; code, so just let the machine independent code widen the mode.
2368 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2369
2370
2371 ;; ??? This should be a define expand.
2372
2373 (define_insn "ashrsi2_16"
2374   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2375         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2376                      (const_int 16)))]
2377   "TARGET_SH1"
2378   "#"
2379   [(set_attr "length" "4")])
2380
2381 (define_split
2382   [(set (match_operand:SI 0 "arith_reg_operand" "")
2383         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2384                      (const_int 16)))]
2385   "TARGET_SH1"
2386   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2387    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2388   "operands[2] = gen_lowpart (HImode, operands[0]);")
2389
2390 ;; ??? This should be a define expand.
2391
2392 (define_insn "ashrsi2_31"
2393   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2394         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2395                      (const_int 31)))
2396    (clobber (reg:SI T_REG))]
2397   "TARGET_SH1"
2398   "#"
2399   [(set_attr "length" "4")])
2400
2401 (define_split
2402   [(set (match_operand:SI 0 "arith_reg_operand" "")
2403         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2404                      (const_int 31)))
2405    (clobber (reg:SI T_REG))]
2406   "TARGET_SH1"
2407   [(const_int 0)]
2408   "
2409 {
2410   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2411   emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2412   DONE;
2413 }")
2414
2415 (define_insn "ashlsi_c"
2416   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2417         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2418    (set (reg:SI T_REG)
2419         (lt:SI (match_dup 1) (const_int 0)))]
2420   "TARGET_SH1"
2421   "shll %0"
2422   [(set_attr "type" "arith")])
2423
2424 (define_insn "ashrsi3_d"
2425   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2426         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2427                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2428   "TARGET_SH3"
2429   "shad %2,%0"
2430   [(set_attr "type" "dyn_shift")])
2431
2432 (define_insn "ashrsi3_n"
2433   [(set (reg:SI R4_REG)
2434         (ashiftrt:SI (reg:SI R4_REG)
2435                      (match_operand:SI 0 "const_int_operand" "i")))
2436    (clobber (reg:SI T_REG))
2437    (clobber (reg:SI PR_REG))
2438    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2439   "TARGET_SH1"
2440   "jsr  @%1%#"
2441   [(set_attr "type" "sfunc")
2442    (set_attr "needs_delay_slot" "yes")])
2443
2444 (define_insn "ashrsi3_media"
2445   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2446         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2447                      (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2448   "TARGET_SHMEDIA"
2449   "@
2450         shard.l %1, %2, %0
2451         shari.l %1, %2, %0"
2452   [(set_attr "type" "arith_media")])
2453
2454 (define_expand "ashrsi3"
2455   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2456                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2457                                 (match_operand:SI 2 "nonmemory_operand" "")))
2458               (clobber (reg:SI T_REG))])]
2459   ""
2460   "
2461 {
2462   if (TARGET_SHMEDIA)
2463     {
2464       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2465       DONE;
2466     }
2467   if (expand_ashiftrt (operands))
2468     DONE;
2469   else
2470     FAIL;
2471 }")
2472
2473 ;; logical shift right
2474
2475 (define_insn "lshrsi3_d"
2476   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2477         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2478                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2479   "TARGET_SH3"
2480   "shld %2,%0"
2481   [(set_attr "type" "dyn_shift")])
2482
2483 ;;  Only the single bit shift clobbers the T bit.
2484
2485 (define_insn "lshrsi3_m"
2486   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2487         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2488                      (match_operand:SI 2 "const_int_operand" "M")))
2489    (clobber (reg:SI T_REG))]
2490   "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2491   "shlr %0"
2492   [(set_attr "type" "arith")])
2493
2494 (define_insn "lshrsi3_k"
2495   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2496         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2497                      (match_operand:SI 2 "const_int_operand" "K")))]
2498   "TARGET_SH1 && CONST_OK_FOR_K (INTVAL (operands[2]))
2499    && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2500   "shlr%O2      %0"
2501   [(set_attr "type" "arith")])
2502
2503 (define_insn "lshrsi3_n"
2504   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2505         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2506                      (match_operand:SI 2 "const_int_operand" "n")))
2507    (clobber (reg:SI T_REG))]
2508   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2509   "#"
2510   [(set (attr "length")
2511         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2512                (const_string "2")
2513                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2514                (const_string "4")
2515                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2516                (const_string "6")]
2517               (const_string "8")))
2518    (set_attr "type" "arith")])
2519
2520 (define_split
2521   [(set (match_operand:SI 0 "arith_reg_operand" "")
2522         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2523                      (match_operand:SI 2 "const_int_operand" "")))
2524    (clobber (reg:SI T_REG))]
2525   "TARGET_SH1 && reload_completed"
2526   [(use (reg:SI R0_REG))]
2527   "
2528 {
2529   gen_shifty_op (LSHIFTRT, operands);
2530   DONE;
2531 }")
2532
2533 (define_insn "lshrsi3_media"
2534   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2535         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2536                      (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2537   "TARGET_SHMEDIA"
2538   "@
2539         shlrd.l %1, %2, %0
2540         shlri.l %1, %2, %0"
2541   [(set_attr "type" "arith_media")])
2542
2543 (define_expand "lshrsi3"
2544   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2545                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2546                                 (match_operand:SI 2 "nonmemory_operand" "")))
2547               (clobber (reg:SI T_REG))])]
2548   ""
2549   "
2550 {
2551   if (TARGET_SHMEDIA)
2552     {
2553       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2554       DONE;
2555     }
2556   if (GET_CODE (operands[2]) == CONST_INT
2557       && sh_dynamicalize_shift_p (operands[2]))
2558     operands[2] = force_reg (SImode, operands[2]);
2559   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2560     {
2561       rtx count = copy_to_mode_reg (SImode, operands[2]);
2562       emit_insn (gen_negsi2 (count, count));
2563       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2564       DONE;
2565     }
2566   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2567     FAIL;
2568 }")
2569
2570 ;; ??? This should be a define expand.
2571
2572 (define_insn "ashldi3_k"
2573   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2574         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2575                    (const_int 1)))
2576    (clobber (reg:SI T_REG))]
2577   "TARGET_SH1"
2578   "shll %R0\;rotcl      %S0"
2579   [(set_attr "length" "4")
2580    (set_attr "type" "arith")])
2581
2582 (define_insn "ashldi3_media"
2583   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2584         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2585                    (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2586   "TARGET_SHMEDIA"
2587   "@
2588         shlld   %1, %2, %0
2589         shlli   %1, %2, %0"
2590   [(set_attr "type" "arith_media")])
2591
2592 (define_expand "ashldi3"
2593   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2594                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2595                               (match_operand:DI 2 "immediate_operand" "")))
2596               (clobber (reg:SI T_REG))])]
2597   ""
2598   "
2599 {
2600   if (TARGET_SHMEDIA)
2601     {
2602       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2603       DONE;
2604     }
2605   if (GET_CODE (operands[2]) != CONST_INT
2606       || INTVAL (operands[2]) != 1)
2607     FAIL;
2608 }")
2609
2610 ;; ??? This should be a define expand.
2611
2612 (define_insn "lshrdi3_k"
2613   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2614         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2615                      (const_int 1)))
2616    (clobber (reg:SI T_REG))]
2617   "TARGET_SH1"
2618   "shlr %S0\;rotcr      %R0"
2619   [(set_attr "length" "4")
2620    (set_attr "type" "arith")])
2621
2622 (define_insn "lshrdi3_media"
2623   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2624         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2625                      (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2626   "TARGET_SHMEDIA"
2627   "@
2628         shlrd   %1, %2, %0
2629         shlri   %1, %2, %0"
2630   [(set_attr "type" "arith_media")])
2631
2632 (define_expand "lshrdi3"
2633   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2634                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2635                                (match_operand:DI 2 "immediate_operand" "")))
2636              (clobber (reg:SI T_REG))])]
2637   ""
2638   "
2639 {
2640   if (TARGET_SHMEDIA)
2641     {
2642       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2643       DONE;
2644     }
2645   if (GET_CODE (operands[2]) != CONST_INT
2646       || INTVAL (operands[2]) != 1)
2647     FAIL;
2648 }")
2649
2650 ;; ??? This should be a define expand.
2651
2652 (define_insn "ashrdi3_k"
2653   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2654         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2655                      (const_int 1)))
2656    (clobber (reg:SI T_REG))]
2657   "TARGET_SH1"
2658   "shar %S0\;rotcr      %R0"
2659   [(set_attr "length" "4")
2660    (set_attr "type" "arith")])
2661
2662 (define_insn "ashrdi3_media"
2663   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2664         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2665                      (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2666   "TARGET_SHMEDIA"
2667   "@
2668         shard   %1, %2, %0
2669         shari   %1, %2, %0"
2670   [(set_attr "type" "arith_media")])
2671
2672 (define_expand "ashrdi3"
2673   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2674                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2675                                 (match_operand:DI 2 "immediate_operand" "")))
2676               (clobber (reg:SI T_REG))])]
2677   ""
2678   "
2679 {
2680   if (TARGET_SHMEDIA)
2681     {
2682       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2683       DONE;
2684     }
2685   if (GET_CODE (operands[2]) != CONST_INT
2686       || INTVAL (operands[2]) != 1)
2687     FAIL;
2688 }")
2689
2690 ;; combined left/right shift
2691
2692 (define_split
2693   [(set (match_operand:SI 0 "register_operand" "")
2694         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2695                            (match_operand:SI 2 "const_int_operand" ""))
2696                 (match_operand:SI 3 "const_int_operand" "")))]
2697   "TARGET_SH1 && (unsigned)INTVAL (operands[2]) < 32"
2698   [(use (reg:SI R0_REG))]
2699   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2700    DONE;")
2701
2702 (define_split
2703   [(set (match_operand:SI 0 "register_operand" "")
2704         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2705                            (match_operand:SI 2 "const_int_operand" ""))
2706                 (match_operand:SI 3 "const_int_operand" "")))
2707    (clobber (reg:SI T_REG))]
2708   "TARGET_SH1 && (unsigned)INTVAL (operands[2]) < 32"
2709   [(use (reg:SI R0_REG))]
2710   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2711    DONE;")
2712
2713 (define_insn ""
2714   [(set (match_operand:SI 0 "register_operand" "=r")
2715         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2716                            (match_operand:SI 2 "const_int_operand" "n"))
2717                 (match_operand:SI 3 "const_int_operand" "n")))
2718    (clobber (reg:SI T_REG))]
2719   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2720  "#"
2721   [(set (attr "length")
2722         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2723                (const_string "4")
2724                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2725                (const_string "6")
2726                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2727                (const_string "8")
2728                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2729                (const_string "10")
2730                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2731                (const_string "12")
2732                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2733                (const_string "14")
2734                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2735                (const_string "16")]
2736               (const_string "18")))
2737    (set_attr "type" "arith")])
2738
2739 (define_insn ""
2740   [(set (match_operand:SI 0 "register_operand" "=z")
2741         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2742                            (match_operand:SI 2 "const_int_operand" "n"))
2743                 (match_operand:SI 3 "const_int_operand" "n")))
2744    (clobber (reg:SI T_REG))]
2745   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2746  "#"
2747   [(set (attr "length")
2748         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2749                (const_string "4")
2750                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2751                (const_string "6")
2752                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2753                (const_string "8")]
2754               (const_string "10")))
2755    (set_attr "type" "arith")])
2756
2757 ;; shift left / and combination with a scratch register: The combine pass
2758 ;; does not accept the individual instructions, even though they are
2759 ;; cheap.  But it needs a precise description so that it is usable after
2760 ;; reload.
2761 (define_insn "and_shl_scratch"
2762   [(set (match_operand:SI 0 "register_operand" "=r,&r")
2763         (lshiftrt:SI
2764          (ashift:SI
2765           (and:SI
2766            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2767                         (match_operand:SI 2 "const_int_operand" "N,n"))
2768            (match_operand:SI 3 "" "0,r"))
2769           (match_operand:SI 4 "const_int_operand" "n,n"))
2770          (match_operand:SI 5 "const_int_operand" "n,n")))
2771    (clobber (reg:SI T_REG))]
2772   "TARGET_SH1"
2773   "#"
2774   [(set (attr "length")
2775         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2776                (const_string "4")
2777                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2778                (const_string "6")
2779                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2780                (const_string "8")
2781                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2782                (const_string "10")]
2783               (const_string "12")))
2784    (set_attr "type" "arith")])
2785
2786 (define_split
2787   [(set (match_operand:SI 0 "register_operand" "")
2788         (lshiftrt:SI
2789          (ashift:SI
2790           (and:SI
2791            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2792                         (match_operand:SI 2 "const_int_operand" ""))
2793            (match_operand:SI 3 "register_operand" ""))
2794           (match_operand:SI 4 "const_int_operand" ""))
2795          (match_operand:SI 5 "const_int_operand" "")))
2796    (clobber (reg:SI T_REG))]
2797   "TARGET_SH1"
2798   [(use (reg:SI R0_REG))]
2799   "
2800 {
2801   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2802
2803   if (INTVAL (operands[2]))
2804     {
2805       gen_shifty_op (LSHIFTRT, operands);
2806     }
2807   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2808   operands[2] = operands[4];
2809   gen_shifty_op (ASHIFT, operands);
2810   if (INTVAL (operands[5]))
2811     {
2812       operands[2] = operands[5];
2813       gen_shifty_op (LSHIFTRT, operands);
2814     }
2815   DONE;
2816 }")
2817
2818 ;; signed left/right shift combination.
2819 (define_split
2820   [(set (match_operand:SI 0 "register_operand" "")
2821         (sign_extract:SI
2822          (ashift:SI (match_operand:SI 1 "register_operand" "")
2823                     (match_operand:SI 2 "const_int_operand" ""))
2824          (match_operand:SI 3 "const_int_operand" "")
2825          (const_int 0)))
2826    (clobber (reg:SI T_REG))]
2827   "TARGET_SH1"
2828   [(use (reg:SI R0_REG))]
2829   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2830    DONE;")
2831
2832 (define_insn "shl_sext_ext"
2833   [(set (match_operand:SI 0 "register_operand" "=r")
2834         (sign_extract:SI
2835          (ashift:SI (match_operand:SI 1 "register_operand" "0")
2836                     (match_operand:SI 2 "const_int_operand" "n"))
2837          (match_operand:SI 3 "const_int_operand" "n")
2838          (const_int 0)))
2839    (clobber (reg:SI T_REG))]
2840   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2841   "#"
2842   [(set (attr "length")
2843         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2844                (const_string "2")
2845                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2846                (const_string "4")
2847                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2848                (const_string "6")
2849                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2850                (const_string "8")
2851                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2852                (const_string "10")
2853                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2854                (const_string "12")
2855                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2856                (const_string "14")
2857                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2858                (const_string "16")]
2859               (const_string "18")))
2860     (set_attr "type" "arith")])
2861
2862 (define_insn "shl_sext_sub"
2863   [(set (match_operand:SI 0 "register_operand" "=z")
2864         (sign_extract:SI
2865          (ashift:SI (match_operand:SI 1 "register_operand" "0")
2866                     (match_operand:SI 2 "const_int_operand" "n"))
2867          (match_operand:SI 3 "const_int_operand" "n")
2868          (const_int 0)))
2869    (clobber (reg:SI T_REG))]
2870   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2871   "#"
2872   [(set (attr "length")
2873         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2874                (const_string "6")
2875                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2876                (const_string "8")
2877                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2878                (const_string "10")
2879                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2880                (const_string "12")]
2881               (const_string "14")))
2882     (set_attr "type" "arith")])
2883
2884 ;; These patterns are found in expansions of DImode shifts by 16, and
2885 ;; allow the xtrct instruction to be generated from C source.
2886
2887 (define_insn "xtrct_left"
2888   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2889         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2890                            (const_int 16))
2891                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2892                              (const_int 16))))]
2893   "TARGET_SH1"
2894   "xtrct        %1,%0"
2895   [(set_attr "type" "arith")])
2896
2897 (define_insn "xtrct_right"
2898   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2899         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2900                              (const_int 16))
2901                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2902                            (const_int 16))))]
2903   "TARGET_SH1"
2904   "xtrct        %2,%0"
2905   [(set_attr "type" "arith")])
2906
2907 ;; -------------------------------------------------------------------------
2908 ;; Unary arithmetic
2909 ;; -------------------------------------------------------------------------
2910
2911 (define_insn "negc"
2912   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2913         (neg:SI (plus:SI (reg:SI T_REG)
2914                          (match_operand:SI 1 "arith_reg_operand" "r"))))
2915    (set (reg:SI T_REG)
2916         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2917                (const_int 0)))]
2918   "TARGET_SH1"
2919   "negc %1,%0"
2920   [(set_attr "type" "arith")])
2921
2922 (define_insn "*negdi_media"
2923   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2924         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2925   "TARGET_SHMEDIA"
2926   "sub  r63, %1, %0"
2927   [(set_attr "type" "arith_media")])
2928
2929 (define_expand "negdi2"
2930   [(set (match_operand:DI 0 "arith_reg_operand" "")
2931         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
2932   ""
2933   "
2934 {
2935   if (TARGET_SH1)
2936     {
2937       int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2938       int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2939
2940       rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2941       rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2942
2943       rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2944       rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2945
2946       emit_insn (gen_clrt ());
2947       emit_insn (gen_negc (low_dst, low_src));
2948       emit_insn (gen_negc (high_dst, high_src));
2949       DONE;
2950     }
2951 }")
2952
2953 (define_insn "negsi2"
2954   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2955         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2956   "TARGET_SH1"
2957   "neg  %1,%0"
2958   [(set_attr "type" "arith")])
2959
2960 (define_insn "one_cmplsi2"
2961   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2962         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2963   "TARGET_SH1"
2964   "not  %1,%0"
2965   [(set_attr "type" "arith")])
2966
2967 (define_expand "one_cmpldi2"
2968   [(set (match_operand:DI 0 "arith_reg_operand" "")
2969         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2970                 (const_int -1)))]
2971   "TARGET_SHMEDIA" "")
2972 \f
2973 ;; -------------------------------------------------------------------------
2974 ;; Zero extension instructions
2975 ;; -------------------------------------------------------------------------
2976
2977 (define_insn "zero_extendsidi2"
2978   [(set (match_operand:DI 0 "register_operand" "=r")
2979         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
2980   "TARGET_SHMEDIA"
2981   "addz.l       %1, r63, %0"
2982   [(set_attr "type" "arith_media")])
2983
2984 (define_insn "zero_extendhidi2"
2985   [(set (match_operand:DI 0 "register_operand" "=r,r")
2986         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
2987   "TARGET_SHMEDIA"
2988   "@
2989         #
2990         ld%M1.uw        %m1, %0"
2991   [(set_attr "type" "*,load_media")])
2992
2993 (define_split
2994   [(set (match_operand:DI 0 "register_operand" "")
2995         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
2996   "TARGET_SHMEDIA && reload_completed"
2997   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
2998    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
2999   "
3000 {
3001   if (GET_CODE (operands[1]) == TRUNCATE)
3002     operands[1] = XEXP (operands[1], 0);
3003 }")
3004
3005 ;; ??? when a truncated input to a zero_extrend is reloaded, reload will
3006 ;; reload the entrire truncate expression.
3007 (define_insn_and_split "*loaddi_trunc"
3008   [(set (match_operand 0 "int_gpr_dest" "=r")
3009         (truncate (match_operand:DI 1 "memory_operand" "m")))]
3010   "TARGET_SHMEDIA && reload_completed"
3011   "#"
3012   "TARGET_SHMEDIA && reload_completed"
3013   [(set (match_dup 0) (match_dup 1))]
3014   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
3015
3016 (define_insn "zero_extendqidi2"
3017   [(set (match_operand:DI 0 "register_operand" "=r,r")
3018         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3019   "TARGET_SHMEDIA"
3020   "@
3021         andi    %1, 255, %0
3022         ld%M1.ub        %m1, %0"
3023   [(set_attr "type" "arith_media,load_media")])
3024
3025 (define_expand "zero_extendhisi2"
3026   [(set (match_operand:SI 0 "arith_reg_operand" "")
3027         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3028   ""
3029   "
3030 {
3031   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3032     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3033 }")
3034
3035 (define_insn "*zero_extendhisi2_compact"
3036   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3037         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
3038   "TARGET_SH1"
3039   "extu.w       %1,%0"
3040   [(set_attr "type" "arith")])
3041
3042 (define_insn "*zero_extendhisi2_media"
3043   [(set (match_operand:SI 0 "register_operand" "=r,r")
3044         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3045   "TARGET_SHMEDIA"
3046   "@
3047         #
3048         ld%M1.uw        %m1, %0"
3049   [(set_attr "type" "arith_media,load_media")])
3050
3051 (define_split
3052   [(set (match_operand:SI 0 "register_operand" "")
3053         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3054   "TARGET_SHMEDIA && reload_completed"
3055   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3056    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3057   "
3058 {
3059   if (GET_CODE (operands[1]) == TRUNCATE)
3060     operands[1] = XEXP (operands[1], 0);
3061 }")
3062
3063 (define_expand "zero_extendqisi2"
3064   [(set (match_operand:SI 0 "arith_reg_operand" "")
3065         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3066   ""
3067   "
3068 {
3069   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3070     operands[1] = copy_to_mode_reg (QImode, operands[1]);
3071 }")
3072
3073 (define_insn "*zero_extendqisi2_compact"
3074   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3075         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
3076   "TARGET_SH1"
3077   "extu.b       %1,%0"
3078   [(set_attr "type" "arith")])
3079
3080 (define_insn "*zero_extendqisi2_media"
3081   [(set (match_operand:SI 0 "register_operand" "=r,r")
3082         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3083   "TARGET_SHMEDIA"
3084   "@
3085         andi    %1, 255, %0
3086         ld%M1.ub        %m1, %0"
3087   [(set_attr "type" "arith_media,load_media")])
3088
3089 (define_insn "zero_extendqihi2"
3090   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3091         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
3092   "TARGET_SH1"
3093   "extu.b       %1,%0"
3094   [(set_attr "type" "arith")])
3095
3096 ;; -------------------------------------------------------------------------
3097 ;; Sign extension instructions
3098 ;; -------------------------------------------------------------------------
3099
3100 ;; ??? This should be a define expand.
3101 ;; ??? Or perhaps it should be dropped?
3102
3103 ;; convert_move generates good code for SH[1-4].
3104 (define_insn "extendsidi2"
3105   [(set (match_operand:DI 0 "register_operand" "=r,r")
3106         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3107   "TARGET_SHMEDIA"
3108   "@
3109         add.l   %1, r63, %0
3110         ld%M1.l %m1, %0"
3111   [(set_attr "type" "arith_media,load_media")])
3112
3113 (define_insn "extendhidi2"
3114   [(set (match_operand:DI 0 "register_operand" "=r,r")
3115         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3116   "TARGET_SHMEDIA"
3117   "@
3118         #
3119         ld%M1.w %m1, %0"
3120   [(set_attr "type" "*,load_media")])
3121
3122 (define_split
3123   [(set (match_operand:DI 0 "register_operand" "")
3124         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3125   "TARGET_SHMEDIA && reload_completed"
3126   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3127    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3128   "
3129 {
3130   if (GET_CODE (operands[1]) == TRUNCATE)
3131     operands[1] = XEXP (operands[1], 0);
3132 }")
3133
3134 (define_insn "extendqidi2"
3135   [(set (match_operand:DI 0 "register_operand" "=r,r")
3136         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3137   "TARGET_SHMEDIA"
3138   "@
3139         #
3140         ld%M1.b %m1, %0"
3141   [(set_attr "type" "*,load_media")])
3142
3143 (define_split
3144   [(set (match_operand:DI 0 "register_operand" "")
3145         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
3146   "TARGET_SHMEDIA && reload_completed"
3147   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3148    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3149   "
3150 {
3151   if (GET_CODE (operands[1]) == TRUNCATE)
3152     operands[1] = XEXP (operands[1], 0);
3153 }")
3154
3155 (define_expand "extendhisi2"
3156   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3157        (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3158   ""
3159   "")
3160
3161 (define_insn "*extendhisi2_compact"
3162   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3163         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3164   "TARGET_SH1"
3165   "@
3166         exts.w  %1,%0
3167         mov.w   %1,%0"
3168   [(set_attr "type" "arith,load")])
3169
3170 (define_insn "*extendhisi2_media"
3171   [(set (match_operand:SI 0 "register_operand" "=r,r")
3172         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3173   "TARGET_SHMEDIA"
3174   "@
3175         #
3176         ld%M1.w %m1, %0"
3177   [(set_attr "type" "arith_media,load_media")])
3178
3179 (define_split
3180   [(set (match_operand:SI 0 "register_operand" "")
3181         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3182   "TARGET_SHMEDIA && reload_completed"
3183   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3184    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3185   "
3186 {
3187   if (GET_CODE (operands[1]) == TRUNCATE)
3188     operands[1] = XEXP (operands[1], 0);
3189 }")
3190
3191 (define_expand "extendqisi2"
3192   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3193         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3194   ""
3195   "")
3196
3197 (define_insn "*extendqisi2_compact"
3198   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3199         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3200   "TARGET_SH1"
3201   "@
3202         exts.b  %1,%0
3203         mov.b   %1,%0"
3204   [(set_attr "type" "arith,load")])
3205
3206 (define_insn "*extendqisi2_media"
3207   [(set (match_operand:SI 0 "register_operand" "=r,r")
3208         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3209   "TARGET_SHMEDIA"
3210   "@
3211         #
3212         ld%M1.b %m1, %0"
3213   [(set_attr "type" "arith_media,load_media")])
3214
3215 (define_split
3216   [(set (match_operand:SI 0 "register_operand" "")
3217         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
3218   "TARGET_SHMEDIA && reload_completed"
3219   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3220    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3221    "
3222 {
3223   if (GET_CODE (operands[1]) == TRUNCATE)
3224     operands[1] = XEXP (operands[1], 0);
3225 }")
3226
3227 (define_insn "extendqihi2"
3228   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3229         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3230   "TARGET_SH1"
3231   "@
3232         exts.b  %1,%0
3233         mov.b   %1,%0"
3234   [(set_attr "type" "arith,load")])
3235
3236 /* It would seem useful to combine the truncXi patterns into the movXi
3237    patterns, but unary operators are ignored when matching constraints,
3238    so we need separate patterns.  */
3239 (define_insn "truncdisi2"
3240   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
3241         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3242   "TARGET_SHMEDIA"
3243   "@
3244         add.l   %1, r63, %0
3245         st%M0.l %m0, %1
3246         fst%M0.s        %m0, %T1
3247         fmov.ls %1, %0
3248         fmov.sl %T1, %0
3249         fmov.s  %T1, %0"
3250   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3251
3252
3253 (define_insn "truncdihi2"
3254   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
3255         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3256   "TARGET_SHMEDIA"
3257   "@
3258         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3259         st%M0.w %m0, %1"
3260   [(set_attr "type"   "arith_media,store_media")
3261    (set_attr "length" "8,4")])
3262
3263 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3264 ; Because we use zero extension, we can't provide signed QImode compares
3265 ; using a simple compare or conditional banch insn.
3266 (define_insn "truncdiqi2"
3267   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3268         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3269   "TARGET_SHMEDIA"
3270   "@
3271         and     %1, 255, %0
3272         st%M0.b %m0, %1"
3273   [(set_attr "type"   "arith_media,store")])
3274
3275 ;; -------------------------------------------------------------------------
3276 ;; Move instructions
3277 ;; -------------------------------------------------------------------------
3278
3279 ;; define push and pop so it is easy for sh.c
3280 ;; We can't use push and pop on SHcompact because the stack must always
3281 ;; be 8-byte aligned.
3282
3283 (define_expand "push"
3284   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3285         (match_operand:SI 0 "register_operand" "r,l,x"))]
3286   "TARGET_SH1 && ! TARGET_SH5"
3287   "")
3288
3289 (define_expand "pop"
3290   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3291         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3292   "TARGET_SH1 && ! TARGET_SH5"
3293   "")
3294
3295 (define_expand "push_e"
3296   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3297                    (match_operand:SF 0 "" ""))
3298               (use (reg:PSI FPSCR_REG))
3299               (clobber (scratch:SI))])]
3300   "TARGET_SH1 && ! TARGET_SH5"
3301   "")
3302
3303 (define_insn "push_fpul"
3304   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3305   "TARGET_SH3E && ! TARGET_SH5"
3306   "sts.l        fpul,@-r15"
3307   [(set_attr "type" "store")
3308    (set_attr "late_fp_use" "yes")
3309    (set_attr "hit_stack" "yes")])
3310
3311 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3312 ;; so use that.
3313 (define_expand "push_4"
3314   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3315                    (match_operand:DF 0 "" ""))
3316               (use (reg:PSI FPSCR_REG))
3317               (clobber (scratch:SI))])]
3318   "TARGET_SH1 && ! TARGET_SH5"
3319   "")
3320
3321 (define_expand "pop_e"
3322   [(parallel [(set (match_operand:SF 0 "" "")
3323               (mem:SF (post_inc:SI (reg:SI SP_REG))))
3324               (use (reg:PSI FPSCR_REG))
3325               (clobber (scratch:SI))])]
3326   "TARGET_SH1 && ! TARGET_SH5"
3327   "")
3328
3329 (define_insn "pop_fpul"
3330   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3331   "TARGET_SH3E && ! TARGET_SH5"
3332   "lds.l        @r15+,fpul"
3333   [(set_attr "type" "load")
3334    (set_attr "hit_stack" "yes")])
3335
3336 (define_expand "pop_4"
3337   [(parallel [(set (match_operand:DF 0 "" "")
3338                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
3339               (use (reg:PSI FPSCR_REG))
3340               (clobber (scratch:SI))])]
3341   "TARGET_SH1 && ! TARGET_SH5"
3342   "")
3343
3344 ;; These two patterns can happen as the result of optimization, when
3345 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3346 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3347
3348 (define_insn "clrt"
3349   [(set (reg:SI T_REG) (const_int 0))]
3350   "TARGET_SH1"
3351   "clrt")
3352
3353 (define_insn "sett"
3354   [(set (reg:SI T_REG) (const_int 1))]
3355   "TARGET_SH1"
3356   "sett")
3357
3358 ;; t/r must come after r/r, lest reload will try to reload stuff like
3359 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3360 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3361 (define_insn "movsi_i"
3362   [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3363         (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3364   "TARGET_SH1
3365    && ! TARGET_SH3E
3366    && (register_operand (operands[0], SImode)
3367        || register_operand (operands[1], SImode))"
3368   "@
3369         mov.l   %1,%0
3370         mov     %1,%0
3371         cmp/pl  %1
3372         mov.l   %1,%0
3373         sts     %1,%0
3374         sts     %1,%0
3375         movt    %0
3376         mov.l   %1,%0
3377         sts.l   %1,%0
3378         sts.l   %1,%0
3379         lds     %1,%0
3380         lds     %1,%0
3381         lds.l   %1,%0
3382         lds.l   %1,%0
3383         fake    %1,%0"
3384   [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3385    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3386
3387 ;; t/r must come after r/r, lest reload will try to reload stuff like
3388 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3389 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3390 ;; will require a reload.
3391 (define_insn "movsi_ie"
3392   [(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")
3393         (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y"))]
3394   "TARGET_SH3E
3395    && (register_operand (operands[0], SImode)
3396        || register_operand (operands[1], SImode))"
3397   "@
3398         mov.l   %1,%0
3399         mov     %1,%0
3400         cmp/pl  %1
3401         mov.l   %1,%0
3402         sts     %1,%0
3403         sts     %1,%0
3404         movt    %0
3405         mov.l   %1,%0
3406         sts.l   %1,%0
3407         sts.l   %1,%0
3408         lds     %1,%0
3409         lds     %1,%0
3410         lds.l   %1,%0
3411         lds.l   %1,%0
3412         lds.l   %1,%0
3413         sts.l   %1,%0
3414         fake    %1,%0
3415         lds     %1,%0
3416         sts     %1,%0
3417         ! move optimized away"
3418   [(set_attr "type" "pcload_si,move,*,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,load,store,pcload_si,gp_fpul,fpul_gp,nil")
3419    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*")
3420    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3421
3422 (define_insn "movsi_i_lowpart"
3423   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3424         (match_operand:SI 1 "general_movsrc_operand" "Q,rI,mr,x,l,t,r,i"))]
3425    "TARGET_SH1
3426     && (register_operand (operands[0], SImode)
3427         || register_operand (operands[1], SImode))"
3428   "@
3429         mov.l   %1,%0
3430         mov     %1,%0
3431         mov.l   %1,%0
3432         sts     %1,%0
3433         sts     %1,%0
3434         movt    %0
3435         mov.l   %1,%0
3436         fake    %1,%0"
3437   [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
3438
3439 (define_insn "*movsi_media"
3440   [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
3441         (match_operand:SI 1 "general_movsrc_operand" "r,JS,ns,m,r,m,f,rU,f,f,r,*b,T"))]
3442   "TARGET_SHMEDIA_FPU
3443    && (register_operand (operands[0], SImode)
3444        || register_operand (operands[1], SImode))"
3445   "@
3446         add.l   %1, r63, %0
3447         movi    %1, %0
3448         #
3449         ld%M1.l %m1, %0
3450         st%M0.l %m0, %1
3451         fld%M1.s        %m1, %0
3452         fst%M0.s        %m0, %1
3453         fmov.ls %N1, %0
3454         fmov.sl %1, %0
3455         fmov.s  %1, %0
3456         ptabs   %1, %0
3457         gettr   %1, %0
3458         pt      %1, %0"
3459   [(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")
3460    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3461
3462 (define_insn "*movsi_media_nofpu"
3463   [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,m,*b,r,b")
3464         (match_operand:SI 1 "general_movsrc_operand" "r,JS,ns,m,r,r,*b,T"))]
3465   "TARGET_SHMEDIA
3466    && (register_operand (operands[0], SImode)
3467        || register_operand (operands[1], SImode))"
3468   "@
3469         add.l   %1, r63, %0
3470         movi    %1, %0
3471         #
3472         ld%M1.l %m1, %0
3473         st%M0.l %m0, %1
3474         ptabs   %1, %0
3475         gettr   %1, %0
3476         pt      %1, %0"
3477   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3478    (set_attr "length" "4,4,8,4,4,4,4,12")])
3479
3480 (define_split
3481   [(set (match_operand:SI 0 "arith_reg_operand" "")
3482         (match_operand:SI 1 "immediate_operand" ""))]
3483   "TARGET_SHMEDIA && reload_completed
3484    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3485   [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3486   "
3487 {
3488   operands[2] = shallow_copy_rtx (operands[1]);
3489   PUT_MODE (operands[2], DImode);
3490 }")
3491
3492 (define_split
3493   [(set (match_operand:SI 0 "register_operand" "")
3494         (match_operand:SI 1 "immediate_operand" ""))]
3495   "TARGET_SHMEDIA && reload_completed
3496    && ((GET_CODE (operands[1]) == CONST_INT
3497         && ! CONST_OK_FOR_J (INTVAL (operands[1])))
3498        || GET_CODE (operands[1]) == CONST_DOUBLE)"
3499   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3500
3501 (define_expand "movsi"
3502   [(set (match_operand:SI 0 "general_movdst_operand" "")
3503         (match_operand:SI 1 "general_movsrc_operand" ""))]
3504   ""
3505   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
3506
3507 (define_expand "ic_invalidate_line"
3508   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
3509                                 (match_dup 1)] UNSPEC_ICACHE)
3510               (clobber (scratch:SI))])]
3511   "TARGET_HARD_SH4 || TARGET_SH5"
3512   "
3513 {
3514   if (TARGET_SHMEDIA)
3515     {
3516       emit_insn (gen_ic_invalidate_line_media (operands[0]));
3517       DONE;
3518     }
3519   else if (TARGET_SHCOMPACT)
3520     {
3521       operands[1] = gen_rtx_SYMBOL_REF (Pmode, \"__ic_invalidate\");
3522       operands[1] = force_reg (Pmode, operands[1]);
3523       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3524       DONE;
3525     }
3526   operands[0] = force_reg (Pmode, operands[0]);
3527   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3528                                                                Pmode)));
3529 }")
3530
3531 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
3532 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3533 ;; the requirement *1*00 for associative address writes.  The alignment of
3534 ;; %0 implies that its least significant bit is cleared,
3535 ;; thus we clear the V bit of a matching entry if there is one.
3536 (define_insn "ic_invalidate_line_i"
3537   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
3538                      (match_operand:SI 1 "register_operand" "r")]
3539                      UNSPEC_ICACHE)
3540    (clobber (match_scratch:SI 2 "=&r"))]
3541   "TARGET_HARD_SH4"
3542   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
3543   [(set_attr "length" "8")
3544    (set_attr "type" "cwb")])
3545
3546 ;; ??? could make arg 0 an offsettable memory operand to allow to save
3547 ;; an add in the code that calculates the address.
3548 (define_insn "ic_invalidate_line_media"
3549   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3550                     UNSPEC_ICACHE)]
3551   "TARGET_SHMEDIA"
3552   "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
3553   [(set_attr "length" "16")
3554    (set_attr "type" "invalidate_line_media")])
3555
3556 (define_insn "ic_invalidate_line_compact"
3557   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3558                      (match_operand:SI 1 "register_operand" "r")]
3559                     UNSPEC_ICACHE)
3560    (clobber (reg:SI PR_REG))]
3561   "TARGET_SHCOMPACT"
3562   "jsr @%1%#"
3563   [(set_attr "type" "sfunc")
3564    (set_attr "needs_delay_slot" "yes")])
3565
3566 (define_expand "initialize_trampoline"
3567   [(match_operand:SI 0 "" "")
3568    (match_operand:SI 1 "" "")
3569    (match_operand:SI 2 "" "")]
3570   "TARGET_SHCOMPACT"
3571   "
3572 {
3573   rtx sfun, tramp;
3574
3575   sfun = force_reg (Pmode, gen_rtx_SYMBOL_REF (Pmode, \"__init_trampoline\"));
3576   tramp = gen_rtx_REG (SImode, R0_REG);
3577   emit_move_insn (tramp, operands[0]);
3578   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3579   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3580
3581   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3582   DONE;
3583 }")
3584
3585 (define_insn "initialize_trampoline_compact"
3586   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3587                      (match_operand:SI 1 "register_operand" "r")
3588                      (reg:SI R2_REG) (reg:SI R3_REG)]
3589                     UNSPEC_INIT_TRAMP)
3590
3591    (clobber (reg:SI PR_REG))]
3592   "TARGET_SHCOMPACT"
3593   "jsr @%1%#"
3594   [(set_attr "type" "sfunc")
3595    (set_attr "needs_delay_slot" "yes")])
3596
3597 (define_insn "movqi_i"
3598   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3599         (match_operand:QI 1 "general_movsrc_operand"  "ri,m,r,t,l,r"))]
3600   "TARGET_SH1
3601    && (arith_reg_operand (operands[0], QImode)
3602        || arith_reg_operand (operands[1], QImode))"
3603   "@
3604         mov     %1,%0
3605         mov.b   %1,%0
3606         mov.b   %1,%0
3607         movt    %0
3608         sts     %1,%0
3609         lds     %1,%0"
3610  [(set_attr "type" "move,load,store,move,move,move")])
3611
3612 (define_insn "*movqi_media"
3613   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
3614         (match_operand:QI 1 "general_movsrc_operand" "r,JS,m,r"))]
3615   "TARGET_SHMEDIA
3616    && (arith_reg_operand (operands[0], QImode)
3617        || arith_reg_operand (operands[1], QImode))"
3618   "@
3619         add.l   %1, r63, %0
3620         movi    %1, %0
3621         ld%M1.ub        %m1, %0
3622         st%M0.b %m0, %1"
3623   [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
3624
3625 (define_expand "movqi"
3626   [(set (match_operand:QI 0 "general_operand" "")
3627         (match_operand:QI 1 "general_operand"  ""))]
3628   ""
3629   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
3630
3631 (define_expand "reload_inqi"
3632   [(set (match_operand:SI 2 "" "=&r")
3633         (match_operand:QI 1 "inqhi_operand" ""))
3634    (set (match_operand:QI 0 "arith_reg_operand" "=r")
3635         (truncate:HI (match_dup 3)))]
3636   "TARGET_SHMEDIA"
3637   "
3638 {
3639   rtx inner = XEXP (operands[1], 0);
3640   int regno = REGNO (inner);
3641
3642   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3643   operands[1] = gen_rtx_REG (SImode, regno);
3644   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3645 }")
3646
3647 (define_insn "movhi_i"
3648   [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
3649         (match_operand:HI 1 "general_movsrc_operand" "Q,rI,m,t,r,l,r,i"))]
3650   "TARGET_SH1
3651    && (arith_reg_operand (operands[0], HImode)
3652        || arith_reg_operand (operands[1], HImode))"
3653   "@
3654         mov.w   %1,%0
3655         mov     %1,%0
3656         mov.w   %1,%0
3657         movt    %0
3658         mov.w   %1,%0
3659         sts     %1,%0
3660         lds     %1,%0
3661         fake    %1,%0"
3662   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
3663
3664 (define_insn "*movhi_media"
3665   [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
3666         (match_operand:HI 1 "general_movsrc_operand" "r,JS,n,m,r"))]
3667   "TARGET_SHMEDIA
3668    && (arith_reg_operand (operands[0], HImode)
3669        || arith_reg_operand (operands[1], HImode))"
3670   "@
3671         add.l   %1, r63, %0
3672         movi    %1, %0
3673         #
3674         ld%M1.w %m1, %0
3675         st%M0.w %m0, %1"
3676   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
3677
3678 (define_split
3679   [(set (match_operand:HI 0 "register_operand" "")
3680         (match_operand:HI 1 "immediate_operand" ""))]
3681   "TARGET_SHMEDIA && reload_completed
3682    && ! CONST_OK_FOR_J (INTVAL (operands[1]))"
3683   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3684
3685 (define_expand "movhi"
3686   [(set (match_operand:HI 0 "general_movdst_operand" "")
3687         (match_operand:HI 1 "general_movsrc_operand"  ""))]
3688   ""
3689   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3690
3691 (define_expand "reload_inhi"
3692   [(set (match_operand:SI 2 "" "=&r")
3693         (match_operand:HI 1 "inqhi_operand" ""))
3694    (set (match_operand:HI 0 "arith_reg_operand" "=r")
3695         (truncate:HI (match_dup 3)))]
3696   "TARGET_SHMEDIA"
3697   "
3698 {
3699   rtx inner = XEXP (operands[1], 0);
3700   int regno = REGNO (inner);
3701
3702   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3703   operands[1] = gen_rtx_REG (SImode, regno);
3704   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3705 }")
3706
3707 ;; ??? This should be a define expand.
3708
3709 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3710 ;; compiled with -m2 -ml -O3 -funroll-loops
3711 (define_insn ""
3712   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3713         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I,i,x,r"))]
3714   "TARGET_SH1
3715    && (arith_reg_operand (operands[0], DImode)
3716        || arith_reg_operand (operands[1], DImode))"
3717   "* return output_movedouble (insn, operands, DImode);"
3718   [(set_attr "length" "4")
3719    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
3720
3721 ;; If the output is a register and the input is memory or a register, we have
3722 ;; to be careful and see which word needs to be loaded first.
3723
3724 (define_split
3725   [(set (match_operand:DI 0 "general_movdst_operand" "")
3726         (match_operand:DI 1 "general_movsrc_operand" ""))]
3727   "TARGET_SH1 && reload_completed"
3728   [(set (match_dup 2) (match_dup 3))
3729    (set (match_dup 4) (match_dup 5))]
3730   "
3731 {
3732   int regno;
3733
3734   if ((GET_CODE (operands[0]) == MEM
3735        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3736       || (GET_CODE (operands[1]) == MEM
3737           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3738     FAIL;
3739
3740   if (GET_CODE (operands[0]) == REG)
3741     regno = REGNO (operands[0]);
3742   else if (GET_CODE (operands[0]) == SUBREG)
3743     regno = subreg_regno (operands[0]);
3744   else if (GET_CODE (operands[0]) == MEM)
3745     regno = -1;
3746   else
3747     abort ();
3748
3749   if (regno == -1
3750       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
3751     {
3752       operands[2] = operand_subword (operands[0], 0, 0, DImode);
3753       operands[3] = operand_subword (operands[1], 0, 0, DImode);
3754       operands[4] = operand_subword (operands[0], 1, 0, DImode);
3755       operands[5] = operand_subword (operands[1], 1, 0, DImode);
3756     }
3757   else
3758     {
3759       operands[2] = operand_subword (operands[0], 1, 0, DImode);
3760       operands[3] = operand_subword (operands[1], 1, 0, DImode);
3761       operands[4] = operand_subword (operands[0], 0, 0, DImode);
3762       operands[5] = operand_subword (operands[1], 0, 0, DImode);
3763     }
3764
3765   if (operands[2] == 0 || operands[3] == 0
3766       || operands[4] == 0 || operands[5] == 0)
3767     FAIL;
3768 }")
3769
3770 (define_insn "*movdi_media"
3771   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
3772         (match_operand:DI 1 "general_movsrc_operand" "r,JS,iF,m,rl,m,f,rU,f,f,r,*b,T"))]
3773   "TARGET_SHMEDIA_FPU
3774    && (register_operand (operands[0], DImode)
3775        || register_operand (operands[1], DImode))"
3776   "@
3777         add     %1, r63, %0
3778         movi    %1, %0
3779         #
3780         ld%M1.q %m1, %0
3781         st%M0.q %m0, %1
3782         fld%M1.d        %m1, %0
3783         fst%M0.d        %m0, %1
3784         fmov.qd %N1, %0
3785         fmov.dq %1, %0
3786         fmov.d  %1, %0
3787         ptabs   %1, %0
3788         gettr   %1, %0
3789         pt      %1, %0"
3790   [(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")
3791    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3792
3793 (define_insn "*movdi_media_nofpu"
3794   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
3795         (match_operand:DI 1 "general_movsrc_operand" "r,JS,iF,m,rl,r,*b,T"))]
3796   "TARGET_SHMEDIA
3797    && (register_operand (operands[0], DImode)
3798        || register_operand (operands[1], DImode))"
3799   "@
3800         add     %1, r63, %0
3801         movi    %1, %0
3802         #
3803         ld%M1.q %m1, %0
3804         st%M0.q %m0, %1
3805         ptabs   %1, %0
3806         gettr   %1, %0
3807         pt      %1, %0"
3808   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3809    (set_attr "length" "4,4,16,4,4,4,4,*")])
3810
3811 (define_split
3812   [(set (match_operand:DI 0 "arith_reg_operand" "")
3813         (match_operand:DI 1 "immediate_operand" ""))]
3814   "TARGET_SHMEDIA && reload_completed
3815    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3816   [(set (match_dup 0) (match_dup 1))]
3817   "
3818 {
3819   rtx insn;
3820
3821   if (TARGET_SHMEDIA64)
3822     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3823   else
3824     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3825
3826   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3827                                         REG_NOTES (insn));
3828
3829   DONE;
3830 }")
3831
3832 (define_expand "movdi_const"
3833   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3834         (const:DI (sign_extend:DI
3835                    (truncate:HI
3836                     (ashiftrt:DI
3837                      (match_operand:DI 1 "immediate_operand" "s")
3838                      (const_int 48))))))
3839    (set (match_dup 0)
3840         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3841                 (zero_extend:DI
3842                  (truncate:HI
3843                   (const:DI
3844                    (sign_extend:DI
3845                     (truncate:HI
3846                      (ashiftrt:SI
3847                       (match_dup 1)
3848                       (const_int 32)))))))))
3849    (set (match_dup 0)
3850         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3851                 (zero_extend:DI
3852                  (truncate:HI
3853                   (const:DI
3854                    (sign_extend:DI
3855                     (truncate:HI
3856                      (ashiftrt:SI
3857                       (match_dup 1)
3858                       (const_int 16)))))))))
3859    (set (match_dup 0)
3860         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3861                 (zero_extend:DI
3862                  (truncate:HI
3863                   (const:DI
3864                    (sign_extend:DI
3865                     (truncate:HI
3866                      (match_dup 1))))))))]
3867   "TARGET_SHMEDIA64 && reload_completed
3868    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3869   "
3870 {
3871   if (GET_CODE (operands[1]) == LABEL_REF
3872       && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
3873     LABEL_NUSES (XEXP (operands[1], 0)) += 4;
3874   else if (GOTOFF_P (operands[1])
3875            && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == LABEL_REF
3876            && (GET_CODE (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0))
3877                == CODE_LABEL))
3878     LABEL_NUSES (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0)) += 4;
3879 }")
3880
3881 (define_expand "movdi_const_32bit"
3882   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3883         (const:DI (sign_extend:DI
3884                    (truncate:HI
3885                     (ashiftrt:DI
3886                      (match_operand:DI 1 "immediate_operand" "s")
3887                      (const_int 16))))))
3888    (set (match_dup 0)
3889         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3890                 (zero_extend:DI
3891                  (truncate:HI
3892                   (const:DI
3893                    (sign_extend:DI
3894                     (truncate:HI
3895                      (match_dup 1))))))))]
3896   "TARGET_SHMEDIA32 && reload_completed
3897    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3898   "
3899 {
3900   if (GET_CODE (operands[1]) == LABEL_REF
3901       && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
3902     LABEL_NUSES (XEXP (operands[1], 0)) += 2;
3903   else if (GOTOFF_P (operands[1])
3904            && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == LABEL_REF
3905            && (GET_CODE (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0))
3906                == CODE_LABEL))
3907     LABEL_NUSES (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0)) += 2;
3908 }")
3909
3910 (define_expand "movdi_const_16bit"
3911   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3912         (const:DI (sign_extend:DI
3913                    (truncate:HI
3914                     (match_operand:DI 1 "immediate_operand" "s")))))]
3915   "TARGET_SHMEDIA && flag_pic && reload_completed
3916    && GET_CODE (operands[1]) == SYMBOL_REF"
3917   "")
3918
3919 (define_split
3920   [(set (match_operand:DI 0 "arith_reg_operand" "")
3921         (match_operand:DI 1 "immediate_operand" ""))]
3922   "TARGET_SHMEDIA && reload_completed
3923    && GET_CODE (operands[1]) == CONST_INT
3924    && ! CONST_OK_FOR_J (INTVAL (operands[1]))"
3925   [(set (match_dup 0) (match_dup 2))
3926    (match_dup 1)]
3927   "
3928 {
3929   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
3930   unsigned HOST_WIDE_INT low = val;
3931   unsigned HOST_WIDE_INT high = val;
3932   unsigned HOST_WIDE_INT sign;
3933   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
3934
3935   /* Sign-extend the 16 least-significant bits.  */
3936   low &= 0xffff;
3937   low ^= 0x8000;
3938   low -= 0x8000;
3939
3940   /* Arithmetic shift right the word by 16 bits.  */
3941   high >>= 16;
3942   sign = 1;
3943   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
3944   high ^= sign;
3945   high -= sign;
3946   do
3947     {
3948       /* If we can't generate the constant with a two-insn movi / shori
3949          sequence, try some other strategies.  */
3950       if (! CONST_OK_FOR_J (high))
3951         {
3952           /* Try constant load / left shift.  We know VAL != 0.  */
3953           val2 = val ^ (val-1);
3954           if (val2 > 0x1ffff)
3955             {
3956               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
3957
3958               if (CONST_OK_FOR_J (val >> trailing_zeroes)
3959                   || (! CONST_OK_FOR_J (high >> 16)
3960                       && CONST_OK_FOR_J (val >> (trailing_zeroes + 16))))
3961                 {
3962                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
3963                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
3964                                                    GEN_INT (trailing_zeroes));
3965                   break;
3966                 }
3967             }
3968           /* Try constant load / right shift.  */
3969           val2 = (val >> 15) + 1;
3970           if (val2 == (val2 & -val2))
3971             {
3972               int shift = 49 - exact_log2 (val2);
3973
3974               val2 = trunc_int_for_mode (val << shift, DImode);
3975               if (CONST_OK_FOR_J (val2))
3976                 {
3977                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
3978                                                    GEN_INT (shift));
3979                   break;
3980                 }
3981             }
3982           /* Try mperm.w .  */
3983           val2 = val & 0xffff;
3984           if ((val >> 16 & 0xffff) == val2
3985               && (val >> 32 & 0xffff) == val2
3986               && (val >> 48 & 0xffff) == val2)
3987             {
3988               val2 = (HOST_WIDE_INT) val >> 48;
3989               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
3990               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
3991               break;
3992             }
3993           /* Try movi / mshflo.l  */
3994           val2 = (HOST_WIDE_INT) val >> 32;
3995           if (val2 == trunc_int_for_mode (val, SImode))
3996             {
3997               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
3998                                              operands[0]);
3999               break;
4000             }
4001           /* Try movi / mshflo.l w/ r63.  */
4002           val2 = val + ((HOST_WIDE_INT) -1 << 32);
4003           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_J (val2))
4004             {
4005               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4006                                              GEN_INT (0));
4007               break;
4008             }
4009         }
4010       val2 = high;
4011       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
4012     }
4013   while (0);
4014   operands[2] = GEN_INT (val2);
4015 }")
4016
4017 (define_split
4018   [(set (match_operand:DI 0 "arith_reg_operand" "")
4019         (match_operand:DI 1 "immediate_operand" ""))]
4020   "TARGET_SHMEDIA && reload_completed
4021    && GET_CODE (operands[1]) == CONST_DOUBLE"
4022   [(set (match_dup 0) (match_dup 2))
4023   (set (match_dup 0)
4024        (ior:DI (ashift:DI (match_dup 0) (const_int 16))
4025                (zero_extend:DI (truncate:HI (match_dup 1)))))]
4026   "
4027 {
4028   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4029   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
4030   unsigned HOST_WIDE_INT val = low;
4031   unsigned HOST_WIDE_INT sign;
4032
4033   /* Sign-extend the 16 least-significant bits.  */
4034   val &= 0xffff;
4035   val ^= 0x8000;
4036   val -= 0x8000;
4037   operands[1] = GEN_INT (val);
4038
4039   /* Arithmetic shift right the double-word by 16 bits.  */
4040   low >>= 16;
4041   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
4042   high >>= 16;
4043   sign = 1;
4044   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4045   high ^= sign;
4046   high -= sign;
4047
4048   /* This will only be true if high is a sign-extension of low, i.e.,
4049      it must be either 0 or (unsigned)-1, and be zero iff the
4050      most-significant bit of low is set.  */
4051   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
4052     operands[2] = GEN_INT (low);
4053   else
4054     operands[2] = immed_double_const (low, high, DImode);
4055 }")
4056
4057 (define_insn "shori_media"
4058   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
4059         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
4060                            (const_int 16))
4061                 (zero_extend:DI
4062                  (truncate:HI
4063                   (match_operand:DI 2 "immediate_operand" "JS,nF")))))]
4064   "TARGET_SHMEDIA"
4065   "@
4066         shori   %u2, %0
4067         #"
4068   [(set_attr "type" "arith_media,*")])
4069
4070 (define_expand "movdi"
4071   [(set (match_operand:DI 0 "general_movdst_operand" "")
4072         (match_operand:DI 1 "general_movsrc_operand" ""))]
4073   ""
4074   "{ if (prepare_move_operands (operands, DImode)) DONE; }")
4075
4076 (define_insn "movdf_media"
4077   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4078         (match_operand:DF 1 "general_movsrc_operand" "f,rU,f,r,F,m,f,m,r"))]
4079   "TARGET_SHMEDIA_FPU
4080    && (register_operand (operands[0], DFmode)
4081        || register_operand (operands[1], DFmode))"
4082   "@
4083         fmov.d  %1, %0
4084         fmov.qd %N1, %0
4085         fmov.dq %1, %0
4086         add     %1, r63, %0
4087         #
4088         fld%M1.d        %m1, %0
4089         fst%M0.d        %m0, %1
4090         ld%M1.q %m1, %0
4091         st%M0.q %m0, %1"
4092   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4093
4094 (define_insn "movdf_media_nofpu"
4095   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4096         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,r"))]
4097   "TARGET_SHMEDIA
4098    && (register_operand (operands[0], DFmode)
4099        || register_operand (operands[1], DFmode))"
4100   "@
4101         add     %1, r63, %0
4102         #
4103         ld%M1.q %m1, %0
4104         st%M0.q %m0, %1"
4105   [(set_attr "type" "arith_media,*,load_media,store_media")])
4106
4107 (define_split
4108   [(set (match_operand:DF 0 "arith_reg_operand" "")
4109         (match_operand:DF 1 "immediate_operand" ""))]
4110   "TARGET_SHMEDIA && reload_completed"
4111   [(set (match_dup 3) (match_dup 2))]
4112   "
4113 {
4114   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
4115   long values[2];
4116   REAL_VALUE_TYPE value;
4117
4118   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4119   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
4120
4121   if (HOST_BITS_PER_WIDE_INT >= 64)
4122     operands[2] = immed_double_const ((unsigned long) values[endian]
4123                                       | ((HOST_WIDE_INT) values[1 - endian]
4124                                          << 32), 0, DImode);
4125   else if (HOST_BITS_PER_WIDE_INT == 32)
4126     operands[2] = immed_double_const (values[endian], values[1 - endian],
4127                                       DImode);
4128   else
4129     abort ();
4130
4131   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4132 }")
4133
4134 ;; ??? This should be a define expand.
4135
4136 (define_insn "movdf_k"
4137   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4138         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
4139   "TARGET_SH1
4140    && (! TARGET_SH4 || reload_completed
4141        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
4142        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4143        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4144    && (arith_reg_operand (operands[0], DFmode)
4145        || arith_reg_operand (operands[1], DFmode))"
4146   "* return output_movedouble (insn, operands, DFmode);"
4147   [(set_attr "length" "4")
4148    (set_attr "type" "move,pcload,load,store")])
4149
4150 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
4151 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
4152 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
4153 ;; the d/m/c/X alternative, which is split later into single-precision
4154 ;; instructions.  And when not optimizing, no splits are done before fixing
4155 ;; up pcloads, so we need usable length information for that.
4156 (define_insn "movdf_i4"
4157   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
4158         (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
4159    (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
4160    (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
4161   "TARGET_SH4
4162    && (arith_reg_operand (operands[0], DFmode)
4163        || arith_reg_operand (operands[1], DFmode))"
4164   "@
4165         fmov    %1,%0
4166         #
4167         #
4168         fmov.d  %1,%0
4169         fmov.d  %1,%0
4170         #
4171         #
4172         #
4173         #
4174         #"
4175   [(set_attr_alternative "length"
4176      [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
4177       (const_int 4)
4178       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4179       (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4180       (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4181       (const_int 4)
4182       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
4183       ;; We can't use 4-byte push/pop on SHcompact, so we have to
4184       ;; increment or decrement r15 explicitly.
4185       (if_then_else
4186        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4187        (const_int 10) (const_int 8))
4188       (if_then_else
4189        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4190        (const_int 10) (const_int 8))])
4191    (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
4192    (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
4193    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4194                                            (const_string "double")
4195                                            (const_string "none")))])
4196
4197 ;; Moving DFmode between fp/general registers through memory
4198 ;; (the top of the stack) is faster than moving through fpul even for
4199 ;; little endian.  Because the type of an instruction is important for its
4200 ;; scheduling,  it is beneficial to split these operations, rather than
4201 ;; emitting them in one single chunk, even if this will expose a stack
4202 ;; use that will prevent scheduling of other stack accesses beyond this
4203 ;; instruction.
4204 (define_split
4205   [(set (match_operand:DF 0 "register_operand" "")
4206         (match_operand:DF 1 "register_operand" ""))
4207    (use (match_operand:PSI 2 "fpscr_operand" ""))
4208    (clobber (match_scratch:SI 3 "=X"))]
4209   "TARGET_SH4 && reload_completed
4210    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
4211   [(const_int 0)]
4212   "
4213 {
4214   rtx insn, tos;
4215
4216   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
4217     {
4218       emit_move_insn (stack_pointer_rtx,
4219                       plus_constant (stack_pointer_rtx, -8));
4220       tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4221     }
4222   else
4223     tos = gen_rtx (MEM, DFmode, gen_rtx (PRE_DEC, Pmode, stack_pointer_rtx));
4224   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
4225   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
4226     REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4227   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4228     tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4229   else
4230     tos = gen_rtx (MEM, DFmode, gen_rtx (POST_INC, Pmode, stack_pointer_rtx));
4231   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
4232   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4233     emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
4234   else
4235     REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4236   DONE;
4237 }")
4238
4239 ;; local-alloc sometimes allocates scratch registers even when not required,
4240 ;; so we must be prepared to handle these.
4241
4242 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
4243 (define_split
4244   [(set (match_operand:DF 0 "general_movdst_operand" "")
4245         (match_operand:DF 1 "general_movsrc_operand"  ""))
4246    (use (match_operand:PSI 2 "fpscr_operand" ""))
4247    (clobber (match_scratch:SI 3 ""))]
4248   "TARGET_SH4
4249    && reload_completed
4250    && true_regnum (operands[0]) < 16
4251    && true_regnum (operands[1]) < 16"
4252   [(set (match_dup 0) (match_dup 1))]
4253   "
4254 {
4255   /* If this was a reg <-> mem operation with base + index reg addressing,
4256      we have to handle this in a special way.  */
4257   rtx mem = operands[0];
4258   int store_p = 1;
4259   if (! memory_operand (mem, DFmode))
4260     {
4261       mem = operands[1];
4262       store_p = 0;
4263     }
4264   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
4265     mem = SUBREG_REG (mem);
4266   if (GET_CODE (mem) == MEM)
4267     {
4268       rtx addr = XEXP (mem, 0);
4269       if (GET_CODE (addr) == PLUS
4270           && GET_CODE (XEXP (addr, 0)) == REG
4271           && GET_CODE (XEXP (addr, 1)) == REG)
4272         {
4273           int offset;
4274           rtx reg0 = gen_rtx (REG, Pmode, 0);
4275           rtx regop = operands[store_p], word0 ,word1;
4276
4277           if (GET_CODE (regop) == SUBREG)
4278             alter_subreg (&regop);
4279           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4280             offset = 2;
4281           else
4282             offset = 4;
4283           mem = copy_rtx (mem);
4284           PUT_MODE (mem, SImode);
4285           word0 = gen_rtx (SUBREG, SImode, regop, 0);
4286           alter_subreg (&word0);
4287           word1 = gen_rtx (SUBREG, SImode, regop, 4);
4288           alter_subreg (&word1);
4289           if (store_p || ! refers_to_regno_p (REGNO (word0),
4290                                               REGNO (word0) + 1, addr, 0))
4291             {
4292               emit_insn (store_p
4293                          ? gen_movsi_ie (mem, word0)
4294                          : gen_movsi_ie (word0, mem));
4295               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4296               mem = copy_rtx (mem);
4297               emit_insn (store_p
4298                          ? gen_movsi_ie (mem, word1)
4299                          : gen_movsi_ie (word1, mem));
4300               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4301             }
4302           else
4303             {
4304               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4305               emit_insn (gen_movsi_ie (word1, mem));
4306               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4307               mem = copy_rtx (mem);
4308               emit_insn (gen_movsi_ie (word0, mem));
4309             }
4310           DONE;
4311         }
4312     }
4313 }")
4314
4315 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4316 (define_split
4317   [(set (match_operand:DF 0 "register_operand" "")
4318         (match_operand:DF 1 "memory_operand"  ""))
4319    (use (match_operand:PSI 2 "fpscr_operand" ""))
4320    (clobber (reg:SI R0_REG))]
4321   "TARGET_SH4 && reload_completed"
4322   [(parallel [(set (match_dup 0) (match_dup 1))
4323               (use (match_dup 2))
4324               (clobber (scratch:SI))])]
4325   "")
4326
4327 (define_expand "reload_indf"
4328   [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4329                    (match_operand:DF 1 "immediate_operand" "FQ"))
4330               (use (reg:PSI FPSCR_REG))
4331               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4332   "TARGET_SH1"
4333   "")
4334
4335 (define_expand "reload_outdf"
4336   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4337                    (match_operand:DF 1 "register_operand" "af,r"))
4338               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
4339   "TARGET_SH1"
4340   "")
4341
4342 ;; Simplify no-op moves.
4343 (define_split
4344   [(set (match_operand:SF 0 "register_operand" "")
4345         (match_operand:SF 1 "register_operand" ""))
4346    (use (match_operand:PSI 2 "fpscr_operand" ""))
4347    (clobber (match_scratch:SI 3 "X"))]
4348   "TARGET_SH3E && reload_completed
4349    && true_regnum (operands[0]) == true_regnum (operands[1])"
4350   [(set (match_dup 0) (match_dup 0))]
4351   "")
4352
4353 ;; fmovd substitute post-reload splits
4354 (define_split
4355   [(set (match_operand:DF 0 "register_operand" "")
4356         (match_operand:DF 1 "register_operand" ""))
4357    (use (match_operand:PSI 2 "fpscr_operand" ""))
4358    (clobber (match_scratch:SI 3 "X"))]
4359   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4360    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4361    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4362   [(const_int 0)]
4363   "
4364 {
4365   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4366   emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst),
4367                            gen_rtx (REG, SFmode, src), operands[2]));
4368   emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst + 1),
4369                            gen_rtx (REG, SFmode, src + 1), operands[2]));
4370   DONE;
4371 }")
4372
4373 (define_split
4374   [(set (match_operand:DF 0 "register_operand" "")
4375         (mem:DF (match_operand:SI 1 "register_operand" "")))
4376    (use (match_operand:PSI 2 "fpscr_operand" ""))
4377    (clobber (match_scratch:SI 3 ""))]
4378   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4379    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4380    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4381   [(const_int 0)]
4382   "
4383 {
4384   int regno = true_regnum (operands[0]);
4385   rtx insn;
4386   rtx mem2 = gen_rtx (MEM, SFmode, gen_rtx (POST_INC, Pmode, operands[1]));
4387
4388   insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4389                                            regno + !! TARGET_LITTLE_ENDIAN),
4390                                   mem2, operands[2]));
4391   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[1], NULL_RTX);
4392   insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4393                                            regno + ! TARGET_LITTLE_ENDIAN),
4394                                   gen_rtx (MEM, SFmode, operands[1]),
4395                                   operands[2]));
4396   DONE;
4397 }")
4398
4399 (define_split
4400   [(set (match_operand:DF 0 "register_operand" "")
4401         (match_operand:DF 1 "memory_operand" ""))
4402    (use (match_operand:PSI 2 "fpscr_operand" ""))
4403    (clobber (match_scratch:SI 3 ""))]
4404   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4405    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
4406   [(const_int 0)]
4407   "
4408 {
4409   int regno = true_regnum (operands[0]);
4410   rtx addr, insn, adjust = NULL_RTX;
4411   rtx mem2 = copy_rtx (operands[1]);
4412   rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4413   rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4414
4415   PUT_MODE (mem2, SFmode);
4416   operands[1] = copy_rtx (mem2);
4417   addr = XEXP (mem2, 0);
4418   if (GET_CODE (addr) != POST_INC)
4419     {
4420       /* If we have to modify the stack pointer, the value that we have
4421          read with post-increment might be modified by an interrupt,
4422          so write it back.  */
4423       if (REGNO (addr) == STACK_POINTER_REGNUM)
4424         adjust = gen_push_e (reg0);
4425       else
4426         adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4427       XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4428     }
4429   addr = XEXP (addr, 0);
4430   insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4431   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4432   insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4433   if (adjust)
4434     emit_insn (adjust);
4435   else
4436     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4437   DONE;
4438 }")
4439
4440 (define_split
4441   [(set (match_operand:DF 0 "memory_operand" "")
4442         (match_operand:DF 1 "register_operand" ""))
4443    (use (match_operand:PSI 2 "fpscr_operand" ""))
4444    (clobber (match_scratch:SI 3 ""))]
4445   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4446    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4447   [(const_int 0)]
4448   "
4449 {
4450   int regno = true_regnum (operands[1]);
4451   rtx insn, addr, adjust = NULL_RTX;
4452
4453   operands[0] = copy_rtx (operands[0]);
4454   PUT_MODE (operands[0], SFmode);
4455   insn = emit_insn (gen_movsf_ie (operands[0],
4456                                   gen_rtx (REG, SFmode,
4457                                            regno + ! TARGET_LITTLE_ENDIAN),
4458                                   operands[2]));
4459   operands[0] = copy_rtx (operands[0]);
4460   addr = XEXP (operands[0], 0);
4461   if (GET_CODE (addr) != PRE_DEC)
4462     {
4463       adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4464       emit_insn_before (adjust, insn);
4465       XEXP (operands[0], 0) = addr = gen_rtx (PRE_DEC, SImode, addr);
4466     }
4467   addr = XEXP (addr, 0);
4468   if (! adjust)
4469     REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4470   insn = emit_insn (gen_movsf_ie (operands[0],
4471                                   gen_rtx (REG, SFmode,
4472                                            regno + !! TARGET_LITTLE_ENDIAN),
4473                                   operands[2]));
4474   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4475   DONE;
4476 }")
4477
4478 ;; If the output is a register and the input is memory or a register, we have
4479 ;; to be careful and see which word needs to be loaded first.
4480
4481 (define_split
4482   [(set (match_operand:DF 0 "general_movdst_operand" "")
4483         (match_operand:DF 1 "general_movsrc_operand" ""))]
4484   "TARGET_SH1 && reload_completed"
4485   [(set (match_dup 2) (match_dup 3))
4486    (set (match_dup 4) (match_dup 5))]
4487   "
4488 {
4489   int regno;
4490
4491   if ((GET_CODE (operands[0]) == MEM
4492        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4493       || (GET_CODE (operands[1]) == MEM
4494           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4495     FAIL;
4496
4497   if (GET_CODE (operands[0]) == REG)
4498     regno = REGNO (operands[0]);
4499   else if (GET_CODE (operands[0]) == SUBREG)
4500     regno = subreg_regno (operands[0]);
4501   else if (GET_CODE (operands[0]) == MEM)
4502     regno = -1;
4503   else
4504     abort ();
4505
4506   if (regno == -1
4507       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
4508     {
4509       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4510       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4511       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4512       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4513     }
4514   else
4515     {
4516       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4517       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4518       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4519       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4520     }
4521
4522   if (operands[2] == 0 || operands[3] == 0
4523       || operands[4] == 0 || operands[5] == 0)
4524     FAIL;
4525 }")
4526
4527 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4528 ;; used only once, let combine add in the index again.
4529
4530 (define_split
4531   [(set (match_operand:SI 0 "register_operand" "")
4532         (match_operand:SI 1 "" ""))
4533    (clobber (match_operand 2 "register_operand" ""))]
4534   "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4535   [(use (reg:SI R0_REG))]
4536   "
4537 {
4538   rtx addr, reg, const_int;
4539
4540   if (GET_CODE (operands[1]) != MEM)
4541     FAIL;
4542   addr = XEXP (operands[1], 0);
4543   if (GET_CODE (addr) != PLUS)
4544     FAIL;
4545   reg = XEXP (addr, 0);
4546   const_int = XEXP (addr, 1);
4547   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4548          && GET_CODE (const_int) == CONST_INT))
4549     FAIL;
4550   emit_move_insn (operands[2], const_int);
4551   emit_move_insn (operands[0],
4552                   change_address (operands[1], VOIDmode,
4553                                   gen_rtx_PLUS (SImode, reg, operands[2])));
4554   DONE;
4555 }")
4556
4557 (define_split
4558   [(set (match_operand:SI 1 "" "")
4559         (match_operand:SI 0 "register_operand" ""))
4560    (clobber (match_operand 2 "register_operand" ""))]
4561   "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4562   [(use (reg:SI R0_REG))]
4563   "
4564 {
4565   rtx addr, reg, const_int;
4566
4567   if (GET_CODE (operands[1]) != MEM)
4568     FAIL;
4569   addr = XEXP (operands[1], 0);
4570   if (GET_CODE (addr) != PLUS)
4571     FAIL;
4572   reg = XEXP (addr, 0);
4573   const_int = XEXP (addr, 1);
4574   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4575          && GET_CODE (const_int) == CONST_INT))
4576     FAIL;
4577   emit_move_insn (operands[2], const_int);
4578   emit_move_insn (change_address (operands[1], VOIDmode,
4579                                   gen_rtx_PLUS (SImode, reg, operands[2])),
4580                   operands[0]);
4581   DONE;
4582 }")
4583
4584 (define_expand "movdf"
4585   [(set (match_operand:DF 0 "general_movdst_operand" "")
4586         (match_operand:DF 1 "general_movsrc_operand" ""))]
4587   ""
4588   "
4589 {
4590   if (prepare_move_operands (operands, DFmode)) DONE;
4591   if (TARGET_SHMEDIA)
4592     {
4593       if (TARGET_SHMEDIA_FPU)
4594         emit_insn (gen_movdf_media (operands[0], operands[1]));
4595       else
4596         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4597       DONE;
4598     }
4599   if (TARGET_SH4)
4600     {
4601       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4602       DONE;
4603     }
4604 }")
4605
4606 ;;This is incompatible with the way gcc uses subregs.
4607 ;;(define_insn "movv2sf_i"
4608 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4609 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4610 ;;  "TARGET_SHMEDIA_FPU
4611 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
4612 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
4613 ;;  "@
4614 ;;      #
4615 ;;      fld%M1.p        %m1, %0
4616 ;;      fst%M0.p        %m0, %1"
4617 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
4618
4619 (define_insn_and_split "movv2sf_i"
4620   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
4621         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfU?"))]
4622   "TARGET_SHMEDIA_FPU"
4623   "#"
4624   "TARGET_SHMEDIA_FPU && reload_completed"
4625   [(set (match_dup 0) (match_dup 1))]
4626   "
4627 {
4628   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
4629   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
4630 }")
4631
4632 (define_expand "movv2sf"
4633   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
4634         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
4635   "TARGET_SHMEDIA_FPU"
4636   "
4637 {
4638   if (prepare_move_operands (operands, V2SFmode))
4639     DONE;
4640 }")
4641
4642 (define_expand "addv2sf3"
4643   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4644    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4645    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4646   "TARGET_SHMEDIA_FPU"
4647   "
4648 {
4649   sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
4650   DONE;
4651 }")
4652
4653 (define_expand "subv2sf3"
4654   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4655    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4656    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4657   "TARGET_SHMEDIA_FPU"
4658   "
4659 {
4660   sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
4661   DONE;
4662 }")
4663
4664 (define_expand "mulv2sf3"
4665   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4666    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4667    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4668   "TARGET_SHMEDIA_FPU"
4669   "
4670 {
4671   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
4672   DONE;
4673 }")
4674
4675 (define_expand "divv2sf3"
4676   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4677    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4678    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4679   "TARGET_SHMEDIA_FPU"
4680   "
4681 {
4682   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
4683   DONE;
4684 }")
4685
4686 (define_insn_and_split "*movv4sf_i"
4687   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4688         (match_operand:V4SF 1 "general_operand" "fU,m,f"))]
4689   "TARGET_SHMEDIA_FPU"
4690   "#"
4691   "&& reload_completed"
4692   [(const_int 0)]
4693   "
4694 {
4695   int i;
4696
4697   for (i = 0; i < 4/2; i++)
4698     {
4699       rtx x, y;
4700
4701       if (GET_CODE (operands[0]) == MEM)
4702         x = gen_rtx_MEM (V2SFmode,
4703                          plus_constant (XEXP (operands[0], 0),
4704                                         i * GET_MODE_SIZE (V2SFmode)));
4705       else
4706         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
4707
4708       if (GET_CODE (operands[1]) == MEM)
4709         y = gen_rtx_MEM (V2SFmode,
4710                          plus_constant (XEXP (operands[1], 0),
4711                                         i * GET_MODE_SIZE (V2SFmode)));
4712       else
4713         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
4714
4715       emit_insn (gen_movv2sf_i (x, y));
4716     }
4717
4718   DONE;
4719 }"
4720   [(set_attr "length" "8")])
4721
4722 (define_expand "movv4sf"
4723   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
4724         (match_operand:V4SF 1 "general_operand" ""))]
4725   "TARGET_SHMEDIA_FPU"
4726   "
4727 {
4728   if (prepare_move_operands (operands, V4SFmode))
4729     DONE;
4730 }")
4731
4732 (define_insn_and_split "*movv16sf_i"
4733   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4734         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4735   "TARGET_SHMEDIA_FPU"
4736   "#"
4737   "&& reload_completed"
4738   [(const_int 0)]
4739   "
4740 {
4741   int i;
4742
4743   for (i = 0; i < 16/2; i++)
4744     {
4745       rtx x,y;
4746
4747       if (GET_CODE (operands[0]) == MEM)
4748         x = gen_rtx_MEM (V2SFmode,
4749                          plus_constant (XEXP (operands[0], 0),
4750                                         i * GET_MODE_SIZE (V2SFmode)));
4751       else
4752         {
4753           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 2);
4754           alter_subreg (&x);
4755         }
4756
4757       if (GET_CODE (operands[1]) == MEM)
4758         y = gen_rtx_MEM (V2SFmode,
4759                          plus_constant (XEXP (operands[1], 0),
4760                                         i * GET_MODE_SIZE (V2SFmode)));
4761       else
4762         {
4763           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 2);
4764           alter_subreg (&y);
4765         }
4766
4767       emit_insn (gen_movv2sf_i (x, y));
4768     }
4769
4770   DONE;
4771 }"
4772   [(set_attr "length" "32")])
4773
4774 (define_expand "movv16sf"
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 {
4780   if (prepare_move_operands (operands, V16SFmode))
4781     DONE;
4782 }")
4783
4784 (define_insn "movsf_media"
4785   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4786         (match_operand:SF 1 "general_movsrc_operand" "f,rU,f,r,F,m,f,m,r"))]
4787   "TARGET_SHMEDIA_FPU
4788    && (register_operand (operands[0], SFmode)
4789        || register_operand (operands[1], SFmode))"
4790   "@
4791         fmov.s  %1, %0
4792         fmov.ls %N1, %0
4793         fmov.sl %1, %0
4794         add.l   %1, r63, %0
4795         #
4796         fld%M1.s        %m1, %0
4797         fst%M0.s        %m0, %1
4798         ld%M1.l %m1, %0
4799         st%M0.l %m0, %1"
4800   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4801
4802 (define_insn "movsf_media_nofpu"
4803   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
4804         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,r"))]
4805   "TARGET_SHMEDIA
4806    && (register_operand (operands[0], SFmode)
4807        || register_operand (operands[1], SFmode))"
4808   "@
4809         add.l   %1, r63, %0
4810         #
4811         ld%M1.l %m1, %0
4812         st%M0.l %m0, %1"
4813   [(set_attr "type" "arith_media,*,load_media,store_media")])
4814
4815 (define_split
4816   [(set (match_operand:SF 0 "arith_reg_operand" "")
4817         (match_operand:SF 1 "immediate_operand" ""))]
4818   "TARGET_SHMEDIA && reload_completed
4819    && ! FP_REGISTER_P (true_regnum (operands[0]))"
4820   [(set (match_dup 3) (match_dup 2))]
4821   "
4822 {
4823   long values;
4824   REAL_VALUE_TYPE value;
4825
4826   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4827   REAL_VALUE_TO_TARGET_SINGLE (value, values);
4828   operands[2] = GEN_INT (values);
4829
4830   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4831 }")
4832
4833 (define_insn "movsf_i"
4834   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
4835         (match_operand:SF 1 "general_movsrc_operand"  "r,I,FQ,mr,r,r,l"))]
4836   "TARGET_SH1
4837    && (! TARGET_SH3E
4838        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4839        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4840        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4841    && (arith_reg_operand (operands[0], SFmode)
4842        || arith_reg_operand (operands[1], SFmode))"
4843   "@
4844         mov     %1,%0
4845         mov     %1,%0
4846         mov.l   %1,%0
4847         mov.l   %1,%0
4848         mov.l   %1,%0
4849         lds     %1,%0
4850         sts     %1,%0"
4851   [(set_attr "type" "move,move,pcload,load,store,move,move")])
4852
4853 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4854 ;; update_flow_info would not know where to put REG_EQUAL notes
4855 ;; when the destination changes mode.
4856 (define_insn "movsf_ie"
4857   [(set (match_operand:SF 0 "general_movdst_operand"
4858          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
4859         (match_operand:SF 1 "general_movsrc_operand"
4860           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4861    (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"))
4862    (clobber (match_scratch:SI 3 "=X,X,X,X,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
4863
4864   "TARGET_SH3E
4865    && (arith_reg_operand (operands[0], SFmode)
4866        || arith_reg_operand (operands[1], SFmode)
4867        || arith_reg_operand (operands[3], SImode)
4868        || (fpul_operand (operands[0], SFmode)
4869            && memory_operand (operands[1], SFmode)
4870            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4871        || (fpul_operand (operands[1], SFmode)
4872            && memory_operand (operands[0], SFmode)
4873            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
4874   "@
4875         fmov    %1,%0
4876         mov     %1,%0
4877         fldi0   %0
4878         fldi1   %0
4879         #
4880         fmov.s  %1,%0
4881         fmov.s  %1,%0
4882         mov.l   %1,%0
4883         mov.l   %1,%0
4884         mov.l   %1,%0
4885         fsts    fpul,%0
4886         flds    %1,fpul
4887         lds.l   %1,%0
4888         #
4889         sts     %1,%0
4890         lds     %1,%0
4891         sts.l   %1,%0
4892         lds.l   %1,%0
4893         ! move optimized away"
4894   [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
4895    (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
4896    (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,4,2,2,2,2,0")
4897    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4898                                            (const_string "single")
4899                                            (const_string "none")))])
4900
4901 (define_split
4902   [(set (match_operand:SF 0 "register_operand" "")
4903         (match_operand:SF 1 "register_operand" ""))
4904    (use (match_operand:PSI 2 "fpscr_operand" ""))
4905    (clobber (reg:SI FPUL_REG))]
4906   "TARGET_SH1"
4907   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
4908               (use (match_dup 2))
4909               (clobber (scratch:SI))])
4910    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
4911               (use (match_dup 2))
4912               (clobber (scratch:SI))])]
4913   "")
4914
4915 (define_expand "movsf"
4916   [(set (match_operand:SF 0 "general_movdst_operand" "")
4917         (match_operand:SF 1 "general_movsrc_operand" ""))]
4918   ""
4919   "
4920 {
4921   if (prepare_move_operands (operands, SFmode))
4922     DONE;
4923   if (TARGET_SHMEDIA)
4924     {
4925       if (TARGET_SHMEDIA_FPU)
4926         emit_insn (gen_movsf_media (operands[0], operands[1]));
4927       else
4928         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
4929       DONE;
4930     }
4931   if (TARGET_SH3E)
4932     {
4933       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
4934       DONE;
4935     }
4936 }")
4937
4938 (define_insn "mov_nop"
4939   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
4940   "TARGET_SH3E"
4941   ""
4942   [(set_attr "length" "0")
4943    (set_attr "type" "nil")])
4944
4945 (define_expand "reload_insf"
4946   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
4947                    (match_operand:SF 1 "immediate_operand" "FQ"))
4948               (use (reg:PSI FPSCR_REG))
4949               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4950   "TARGET_SH1"
4951   "")
4952
4953 (define_expand "reload_insi"
4954   [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
4955                    (match_operand:SF 1 "immediate_operand" "FQ"))
4956               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4957   "TARGET_SH1"
4958   "")
4959
4960 (define_insn "*movsi_y"
4961   [(set (match_operand:SI 0 "register_operand" "=y,y")
4962         (match_operand:SI 1 "immediate_operand" "Qi,I"))
4963    (clobber (match_scratch:SI 2 "=&z,r"))]
4964   "TARGET_SH3E
4965    && (reload_in_progress || reload_completed)"
4966   "#"
4967   [(set_attr "length" "4")
4968    (set_attr "type" "pcload,move")])
4969
4970 (define_split
4971   [(set (match_operand:SI 0 "register_operand" "")
4972         (match_operand:SI 1 "immediate_operand" ""))
4973    (clobber (match_operand:SI 2 "register_operand" ""))]
4974   "TARGET_SH1"
4975   [(set (match_dup 2) (match_dup 1))
4976    (set (match_dup 0) (match_dup 2))]
4977   "")
4978
4979 (define_split
4980   [(set (match_operand:SI 0 "register_operand" "")
4981         (match_operand:SI 1 "memory_operand" ""))
4982    (clobber (reg:SI R0_REG))]
4983   "TARGET_SH1"
4984   [(set (match_dup 0) (match_dup 1))]
4985   "")
4986 \f
4987 ;; ------------------------------------------------------------------------
4988 ;; Define the real conditional branch instructions.
4989 ;; ------------------------------------------------------------------------
4990
4991 (define_insn "branch_true"
4992   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
4993                            (label_ref (match_operand 0 "" ""))
4994                            (pc)))]
4995   "TARGET_SH1"
4996   "* return output_branch (1, insn, operands);"
4997   [(set_attr "type" "cbranch")])
4998
4999 (define_insn "branch_false"
5000   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
5001                            (label_ref (match_operand 0 "" ""))
5002                            (pc)))]
5003   "TARGET_SH1"
5004   "* return output_branch (0, insn, operands);"
5005   [(set_attr "type" "cbranch")])
5006
5007 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
5008 ;; which destination is too far away.
5009 ;; The const_int_operand is distinct for each branch target; it avoids
5010 ;; unwanted matches with redundant_insn.
5011 (define_insn "block_branch_redirect"
5012   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
5013   "TARGET_SH1"
5014   ""
5015   [(set_attr "length" "0")])
5016
5017 ;; This one has the additional purpose to record a possible scratch register
5018 ;; for the following branch.
5019 (define_insn "indirect_jump_scratch"
5020   [(set (match_operand:SI 0 "register_operand" "=r")
5021         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))]
5022   "TARGET_SH1"
5023   ""
5024   [(set_attr "length" "0")])
5025
5026 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
5027 ;; being pulled into the delay slot of a condbranch that has been made to
5028 ;; jump around the unconditional jump because it was out of range.
5029 (define_insn "stuff_delay_slot"
5030   [(set (pc)
5031         (unspec [(match_operand 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
5032    (set (reg:SI T_REG) (match_operand 1 "const_int_operand" ""))]
5033   "TARGET_SH1"
5034   ""
5035   [(set_attr "length" "0")
5036    (set_attr "cond_delay_slot" "yes")])
5037 \f
5038 ;; Conditional branch insns
5039
5040 (define_expand "beq_media"
5041   [(set (pc)
5042         (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
5043                           (match_operand:DI 2 "arith_operand" "r,O"))
5044                       (label_ref:DI (match_operand 0 "" ""))
5045                       (pc)))]
5046   "TARGET_SHMEDIA"
5047   "")
5048
5049 (define_insn "*beq_media_i"
5050   [(set (pc)
5051         (if_then_else (match_operator 3 "equality_comparison_operator"
5052                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
5053                          (match_operand:DI 2 "arith_operand" "r,O")])
5054                       (match_operand:DI 0 "target_operand" "b,b")
5055                       (pc)))]
5056   "TARGET_SHMEDIA"
5057   "@
5058         b%o3%'  %1, %2, %0
5059         b%o3i%' %1, %2, %0"
5060   [(set_attr "type" "cbranch_media")])
5061
5062 (define_expand "bne_media"
5063   [(set (pc)
5064         (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
5065                           (match_operand:DI 2 "arith_operand" "r,O"))
5066                       (label_ref:DI (match_operand 0 "" ""))
5067                       (pc)))]
5068   "TARGET_SHMEDIA"
5069   "")
5070
5071 (define_expand "bgt_media"
5072   [(set (pc)
5073         (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5074                           (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5075                       (label_ref:DI (match_operand 0 "" ""))
5076                       (pc)))]
5077   "TARGET_SHMEDIA"
5078   "")
5079
5080 (define_expand "bge_media"
5081   [(set (pc)
5082         (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5083                           (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5084                       (label_ref:DI (match_operand 0 "" ""))
5085                       (pc)))]
5086   "TARGET_SHMEDIA"
5087   "")
5088
5089 (define_expand "bgtu_media"
5090   [(set (pc)
5091         (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5092                            (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5093                       (label_ref:DI (match_operand 0 "" ""))
5094                       (pc)))]
5095   "TARGET_SHMEDIA"
5096   "")
5097
5098 (define_expand "bgeu_media"
5099   [(set (pc)
5100         (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5101                            (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5102                       (label_ref:DI (match_operand 0 "" ""))
5103                       (pc)))]
5104   "TARGET_SHMEDIA"
5105   "")
5106
5107 (define_insn "*bgt_media_i"
5108   [(set (pc)
5109         (if_then_else (match_operator 3 "greater_comparison_operator"
5110                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5111                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5112                       (match_operand:DI 0 "target_operand" "b")
5113                       (pc)))]
5114   "TARGET_SHMEDIA"
5115   "b%o3%'       %N1, %N2, %0"
5116   [(set_attr "type" "cbranch_media")])
5117
5118 ;; These are only needed to make invert_jump() happy.
5119 (define_insn "*blt_media_i"
5120   [(set (pc)
5121         (if_then_else (match_operator 3 "less_comparison_operator"
5122                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5123                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5124                       (match_operand:DI 0 "target_operand" "b")
5125                       (pc)))]
5126   "TARGET_SHMEDIA"
5127   "b%o3%'       %N2, %N1, %0"
5128   [(set_attr "type" "cbranch_media")])
5129
5130 (define_expand "beq"
5131   [(set (pc)
5132         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5133                       (label_ref (match_operand 0 "" ""))
5134                       (pc)))]
5135   ""
5136   "
5137 {
5138   if (TARGET_SHMEDIA)
5139     {
5140       if (GET_MODE (sh_compare_op0) != DImode)
5141         {
5142           rtx tmp = gen_reg_rtx (DImode);
5143
5144           emit_insn (gen_seq (tmp));
5145           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5146           DONE;
5147         }
5148
5149       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5150       emit_jump_insn (gen_beq_media (operands[0],
5151                                      sh_compare_op0, sh_compare_op1));
5152       DONE;
5153     }
5154
5155   from_compare (operands, EQ);
5156 }")
5157
5158 (define_expand "bne"
5159   [(set (pc)
5160         (if_then_else (eq (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_beq_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_bne_media (operands[0],
5179                                      sh_compare_op0, sh_compare_op1));
5180       DONE;
5181     }
5182
5183   from_compare (operands, EQ);
5184 }")
5185
5186 (define_expand "bgt"
5187   [(set (pc)
5188         (if_then_else (ne (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_sgt (tmp));
5201           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5202           DONE;
5203         }
5204
5205       if (sh_compare_op0 != const0_rtx)
5206         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5207       if (sh_compare_op1 != const0_rtx)
5208         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5209       emit_jump_insn (gen_bgt_media (operands[0],
5210                                      sh_compare_op0, sh_compare_op1));
5211       DONE;
5212     }
5213
5214   from_compare (operands, GT);
5215 }")
5216
5217 (define_expand "blt"
5218   [(set (pc)
5219         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5220                       (label_ref (match_operand 0 "" ""))
5221                       (pc)))]
5222   ""
5223   "
5224 {
5225   if (TARGET_SHMEDIA)
5226     {
5227       if (GET_MODE (sh_compare_op0) != DImode)
5228         {
5229           rtx tmp = gen_reg_rtx (DImode);
5230
5231           emit_insn (gen_slt (tmp));
5232           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5233           DONE;
5234         }
5235
5236       if (sh_compare_op0 != const0_rtx)
5237         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5238       if (sh_compare_op1 != const0_rtx)
5239         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5240       emit_jump_insn (gen_bgt_media (operands[0],
5241                                      sh_compare_op1, sh_compare_op0));
5242       DONE;
5243     }
5244
5245   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5246     {
5247       rtx tmp = sh_compare_op0;
5248       sh_compare_op0 = sh_compare_op1;
5249       sh_compare_op1 = tmp;
5250       emit_insn (gen_bgt (operands[0]));
5251       DONE;
5252     }
5253   from_compare (operands, GE);
5254 }")
5255
5256 (define_expand "ble"
5257   [(set (pc)
5258         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5259                       (label_ref (match_operand 0 "" ""))
5260                       (pc)))]
5261   ""
5262   "
5263 {
5264   if (TARGET_SHMEDIA)
5265     {
5266       if (GET_MODE (sh_compare_op0) != DImode)
5267         {
5268           rtx tmp = gen_reg_rtx (DImode);
5269
5270           emit_insn (gen_sle (tmp));
5271           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5272           DONE;
5273         }
5274
5275       if (sh_compare_op0 != const0_rtx)
5276         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5277       if (sh_compare_op1 != const0_rtx)
5278         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5279       emit_jump_insn (gen_bge_media (operands[0],
5280                                      sh_compare_op1, sh_compare_op0));
5281       DONE;
5282     }
5283
5284   if (TARGET_SH3E
5285       && TARGET_IEEE
5286       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5287     {
5288       rtx tmp = sh_compare_op0;
5289       sh_compare_op0 = sh_compare_op1;
5290       sh_compare_op1 = tmp;
5291       emit_insn (gen_bge (operands[0]));
5292       DONE;
5293     }
5294   from_compare (operands, GT);
5295 }")
5296
5297 (define_expand "bge"
5298   [(set (pc)
5299         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5300                       (label_ref (match_operand 0 "" ""))
5301                       (pc)))]
5302   ""
5303   "
5304 {
5305   if (TARGET_SHMEDIA)
5306     {
5307       if (GET_MODE (sh_compare_op0) != DImode)
5308         {
5309           rtx tmp = gen_reg_rtx (DImode);
5310
5311           emit_insn (gen_sge (tmp));
5312           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5313           DONE;
5314         }
5315
5316       if (sh_compare_op0 != const0_rtx)
5317         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5318       if (sh_compare_op1 != const0_rtx)
5319         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5320       emit_jump_insn (gen_bge_media (operands[0],
5321                                      sh_compare_op0, sh_compare_op1));
5322       DONE;
5323     }
5324
5325   if (TARGET_SH3E
5326       && ! TARGET_IEEE
5327       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5328     {
5329       rtx tmp = sh_compare_op0;
5330       sh_compare_op0 = sh_compare_op1;
5331       sh_compare_op1 = tmp;
5332       emit_insn (gen_ble (operands[0]));
5333       DONE;
5334     }
5335   from_compare (operands, GE);
5336 }")
5337
5338 (define_expand "bgtu"
5339   [(set (pc)
5340         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5341                       (label_ref (match_operand 0 "" ""))
5342                       (pc)))]
5343   ""
5344   "
5345 {
5346   if (TARGET_SHMEDIA)
5347     {
5348       if (sh_compare_op0 != const0_rtx)
5349         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5350       if (sh_compare_op1 != const0_rtx)
5351         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5352       emit_jump_insn (gen_bgtu_media (operands[0],
5353                                       sh_compare_op0, sh_compare_op1));
5354       DONE;
5355     }
5356
5357   from_compare (operands, GTU);
5358 }")
5359
5360 (define_expand "bltu"
5361   [(set (pc)
5362         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5363                       (label_ref (match_operand 0 "" ""))
5364                       (pc)))]
5365   ""
5366   "
5367 {
5368   if (TARGET_SHMEDIA)
5369     {
5370       if (sh_compare_op0 != const0_rtx)
5371         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5372       if (sh_compare_op1 != const0_rtx)
5373         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5374       emit_jump_insn (gen_bgtu_media (operands[0],
5375                                       sh_compare_op1, sh_compare_op0));
5376       DONE;
5377     }
5378
5379   from_compare (operands, GEU);
5380 }")
5381
5382 (define_expand "bgeu"
5383   [(set (pc)
5384         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5385                       (label_ref (match_operand 0 "" ""))
5386                       (pc)))]
5387   ""
5388   "
5389 {
5390   if (TARGET_SHMEDIA)
5391     {
5392       if (sh_compare_op0 != const0_rtx)
5393         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5394       if (sh_compare_op1 != const0_rtx)
5395         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5396       emit_jump_insn (gen_bgeu_media (operands[0],
5397                                       sh_compare_op0, sh_compare_op1));
5398       DONE;
5399     }
5400
5401   from_compare (operands, GEU);
5402 }")
5403
5404 (define_expand "bleu"
5405   [(set (pc)
5406         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5407                       (label_ref (match_operand 0 "" ""))
5408                       (pc)))]
5409   ""
5410   "
5411 {
5412   if (TARGET_SHMEDIA)
5413     {
5414       if (sh_compare_op0 != const0_rtx)
5415         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5416       if (sh_compare_op1 != const0_rtx)
5417         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5418       emit_jump_insn (gen_bgeu_media (operands[0],
5419                                       sh_compare_op1, sh_compare_op0));
5420       DONE;
5421     }
5422
5423   from_compare (operands, GTU);
5424 }")
5425
5426 (define_expand "bunordered"
5427   [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5428    (set (pc)
5429         (if_then_else (ne (match_dup 1) (const_int 0))
5430                       (label_ref:DI (match_operand 0 "" ""))
5431                       (pc)))]
5432   "TARGET_SHMEDIA"
5433   "
5434 {
5435   operands[1] = gen_reg_rtx (DImode);
5436   operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5437   operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5438 }")
5439 \f
5440 ;; ------------------------------------------------------------------------
5441 ;; Jump and linkage insns
5442 ;; ------------------------------------------------------------------------
5443
5444 (define_insn "jump_compact"
5445   [(set (pc)
5446         (label_ref (match_operand 0 "" "")))]
5447   "TARGET_SH1"
5448   "*
5449 {
5450   /* The length is 16 if the delay slot is unfilled.  */
5451   if (get_attr_length(insn) > 4)
5452     return output_far_jump(insn, operands[0]);
5453   else
5454     return   \"bra      %l0%#\";
5455 }"
5456   [(set_attr "type" "jump")
5457    (set_attr "needs_delay_slot" "yes")])
5458
5459 (define_insn "jump_media"
5460   [(set (pc)
5461         (match_operand:DI 0 "target_operand" "b"))]
5462   "TARGET_SHMEDIA"
5463   "blink        %0, r63"
5464   [(set_attr "type" "jump_media")])
5465
5466 (define_expand "jump"
5467   [(set (pc)
5468         (label_ref (match_operand 0 "" "")))]
5469   ""
5470   "
5471 {
5472   if (TARGET_SH1)
5473     emit_jump_insn (gen_jump_compact (operands[0]));
5474   else if (TARGET_SHMEDIA)
5475     {
5476       if (reload_in_progress || reload_completed)
5477         FAIL;
5478       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5479                                                          operands[0])));
5480     }
5481   DONE;
5482 }")
5483
5484 (define_insn "force_mode_for_call"
5485   [(use (reg:PSI FPSCR_REG))]
5486   "TARGET_SHCOMPACT"
5487   ""
5488   [(set_attr "length" "0")
5489    (set (attr "fp_mode")
5490         (if_then_else (eq_attr "fpu_single" "yes")
5491                       (const_string "single") (const_string "double")))])
5492
5493 (define_insn "calli"
5494   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5495          (match_operand 1 "" ""))
5496    (use (reg:PSI FPSCR_REG))
5497    (clobber (reg:SI PR_REG))]
5498   "TARGET_SH1"
5499   "jsr  @%0%#"
5500   [(set_attr "type" "call")
5501    (set (attr "fp_mode")
5502         (if_then_else (eq_attr "fpu_single" "yes")
5503                       (const_string "single") (const_string "double")))
5504    (set_attr "needs_delay_slot" "yes")])
5505
5506 ;; This is a pc-rel call, using bsrf, for use with PIC.
5507
5508 (define_insn "calli_pcrel"
5509   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5510          (match_operand 1 "" ""))
5511    (use (reg:PSI FPSCR_REG))
5512    (use (reg:SI PIC_REG))
5513    (use (match_operand 2 "" ""))
5514    (clobber (reg:SI PR_REG))]
5515   "TARGET_SH2"
5516   "bsrf %0\\n%O2:%#"
5517   [(set_attr "type" "call")
5518    (set (attr "fp_mode")
5519         (if_then_else (eq_attr "fpu_single" "yes")
5520                       (const_string "single") (const_string "double")))
5521    (set_attr "needs_delay_slot" "yes")])
5522
5523 (define_insn_and_split "call_pcrel"
5524   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5525          (match_operand 1 "" ""))
5526    (use (reg:PSI FPSCR_REG))
5527    (use (reg:SI PIC_REG))
5528    (clobber (reg:SI PR_REG))
5529    (clobber (match_scratch:SI 2 "=r"))]
5530   "TARGET_SH2"
5531   "#"
5532   "reload_completed"
5533   [(const_int 0)]
5534   "
5535 {
5536   rtx lab = PATTERN (gen_call_site ());
5537
5538   if (SYMBOL_REF_FLAG (operands[0]))
5539     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5540   else
5541     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5542   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5543   DONE;
5544 }"
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 "call_compact"
5552   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5553          (match_operand 1 "" ""))
5554    (match_operand 2 "immediate_operand" "n")
5555    (use (reg:SI R0_REG))
5556    (use (reg:SI R1_REG))
5557    (use (reg:PSI FPSCR_REG))
5558    (clobber (reg:SI PR_REG))]
5559   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5560   "jsr  @%0%#"
5561   [(set_attr "type" "call")
5562    (set (attr "fp_mode")
5563         (if_then_else (eq_attr "fpu_single" "yes")
5564                       (const_string "single") (const_string "double")))
5565    (set_attr "needs_delay_slot" "yes")])
5566
5567 (define_insn "call_compact_rettramp"
5568   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5569          (match_operand 1 "" ""))
5570    (match_operand 2 "immediate_operand" "n")
5571    (use (reg:SI R0_REG))
5572    (use (reg:SI R1_REG))
5573    (use (reg:PSI FPSCR_REG))
5574    (clobber (reg:SI R10_REG))
5575    (clobber (reg:SI PR_REG))]
5576   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5577   "jsr  @%0%#"
5578   [(set_attr "type" "call")
5579    (set (attr "fp_mode")
5580         (if_then_else (eq_attr "fpu_single" "yes")
5581                       (const_string "single") (const_string "double")))
5582    (set_attr "needs_delay_slot" "yes")])
5583
5584 (define_insn "call_media"
5585   [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5586          (match_operand 1 "" ""))
5587    (clobber (reg:DI PR_MEDIA_REG))]
5588   "TARGET_SHMEDIA"
5589   "blink        %0, r18"
5590   [(set_attr "type" "jump_media")])
5591
5592 (define_insn "call_valuei"
5593   [(set (match_operand 0 "" "=rf")
5594         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5595               (match_operand 2 "" "")))
5596    (use (reg:PSI FPSCR_REG))
5597    (clobber (reg:SI PR_REG))]
5598   "TARGET_SH1"
5599   "jsr  @%1%#"
5600   [(set_attr "type" "call")
5601    (set (attr "fp_mode")
5602         (if_then_else (eq_attr "fpu_single" "yes")
5603                       (const_string "single") (const_string "double")))
5604    (set_attr "needs_delay_slot" "yes")])
5605
5606 (define_insn "call_valuei_pcrel"
5607   [(set (match_operand 0 "" "=rf")
5608         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5609               (match_operand 2 "" "")))
5610    (use (reg:PSI FPSCR_REG))
5611    (use (reg:SI PIC_REG))
5612    (use (match_operand 3 "" ""))
5613    (clobber (reg:SI PR_REG))]
5614   "TARGET_SH2"
5615   "bsrf %1\\n%O3:%#"
5616   [(set_attr "type" "call")
5617    (set (attr "fp_mode")
5618         (if_then_else (eq_attr "fpu_single" "yes")
5619                       (const_string "single") (const_string "double")))
5620    (set_attr "needs_delay_slot" "yes")])
5621
5622 (define_insn_and_split "call_value_pcrel"
5623   [(set (match_operand 0 "" "=rf")
5624         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5625               (match_operand 2 "" "")))
5626    (use (reg:PSI FPSCR_REG))
5627    (use (reg:SI PIC_REG))
5628    (clobber (reg:SI PR_REG))
5629    (clobber (match_scratch:SI 3 "=r"))]
5630   "TARGET_SH2"
5631   "#"
5632   "reload_completed"
5633   [(const_int 0)]
5634   "
5635 {
5636   rtx lab = PATTERN (gen_call_site ());
5637
5638   if (SYMBOL_REF_FLAG (operands[1]))
5639     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5640   else
5641     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5642   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5643                                          operands[2], lab));
5644   DONE;
5645 }"
5646   [(set_attr "type" "call")
5647    (set (attr "fp_mode")
5648         (if_then_else (eq_attr "fpu_single" "yes")
5649                       (const_string "single") (const_string "double")))
5650    (set_attr "needs_delay_slot" "yes")])
5651
5652 (define_insn "call_value_compact"
5653   [(set (match_operand 0 "" "=rf")
5654         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5655               (match_operand 2 "" "")))
5656    (match_operand 3 "immediate_operand" "n")
5657    (use (reg:SI R0_REG))
5658    (use (reg:SI R1_REG))
5659    (use (reg:PSI FPSCR_REG))
5660    (clobber (reg:SI PR_REG))]
5661   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5662   "jsr  @%1%#"
5663   [(set_attr "type" "call")
5664    (set (attr "fp_mode")
5665         (if_then_else (eq_attr "fpu_single" "yes")
5666                       (const_string "single") (const_string "double")))
5667    (set_attr "needs_delay_slot" "yes")])
5668
5669 (define_insn "call_value_compact_rettramp"
5670   [(set (match_operand 0 "" "=rf")
5671         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5672               (match_operand 2 "" "")))
5673    (match_operand 3 "immediate_operand" "n")
5674    (use (reg:SI R0_REG))
5675    (use (reg:SI R1_REG))
5676    (use (reg:PSI FPSCR_REG))
5677    (clobber (reg:SI R10_REG))
5678    (clobber (reg:SI PR_REG))]
5679   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5680   "jsr  @%1%#"
5681   [(set_attr "type" "call")
5682    (set (attr "fp_mode")
5683         (if_then_else (eq_attr "fpu_single" "yes")
5684                       (const_string "single") (const_string "double")))
5685    (set_attr "needs_delay_slot" "yes")])
5686
5687 (define_insn "call_value_media"
5688   [(set (match_operand 0 "" "=rf")
5689         (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5690               (match_operand 2 "" "")))
5691    (clobber (reg:DI PR_MEDIA_REG))]
5692   "TARGET_SHMEDIA"
5693   "blink        %1, r18"
5694   [(set_attr "type" "jump_media")])
5695
5696 (define_expand "call"
5697   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5698                             (match_operand 1 "" ""))
5699               (match_operand 2 "" "")
5700               (use (reg:PSI FPSCR_REG))
5701               (clobber (reg:SI PR_REG))])]
5702   ""
5703   "
5704 {
5705   if (TARGET_SHMEDIA)
5706     {
5707       operands[0] = XEXP (operands[0], 0);
5708       if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5709         {
5710           if (! SYMBOL_REF_FLAG (operands[0]))
5711             {
5712               rtx reg = gen_reg_rtx (Pmode);
5713
5714               emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5715               operands[0] = reg;
5716             }
5717           else
5718             {
5719               operands[0] = gen_sym2PIC (operands[0]);
5720               PUT_MODE (operands[0], Pmode);
5721             }
5722         }
5723       if (GET_MODE (operands[0]) == SImode)
5724         {
5725           if (GET_CODE (operands[0]) == REG)
5726             operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5727           else if (GET_CODE (operands[0]) == SUBREG)
5728             {
5729               operands[0] = SUBREG_REG (operands[0]);
5730               if (GET_MODE (operands[0]) != DImode)
5731                 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5732             }
5733           else
5734             {
5735               operands[0] = shallow_copy_rtx (operands[0]);
5736               PUT_MODE (operands[0], DImode);
5737             }
5738         }
5739       if (! target_reg_operand (operands[0], DImode))
5740         operands[0] = copy_to_mode_reg (DImode, operands[0]);
5741       emit_call_insn (gen_call_media (operands[0], operands[1]));
5742       DONE;
5743     }
5744   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5745     {
5746       rtx cookie_rtx = operands[2];
5747       long cookie = INTVAL (cookie_rtx);
5748       rtx func = XEXP (operands[0], 0);
5749       rtx r0, r1;
5750
5751       if (flag_pic)
5752         {
5753           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5754             {
5755               rtx reg = gen_reg_rtx (Pmode);
5756
5757               emit_insn (gen_symGOTPLT2reg (reg, func));
5758               func = reg;
5759             }
5760           else
5761             func = legitimize_pic_address (func, Pmode, 0);
5762         }
5763
5764       r0 = gen_rtx_REG (SImode, R0_REG);
5765       r1 = gen_rtx_REG (SImode, R1_REG);
5766
5767       /* Since such a call function may use all call-clobbered
5768          registers, we force a mode switch earlier, so that we don't
5769          run out of registers when adjusting fpscr for the call.  */
5770       emit_insn (gen_force_mode_for_call ());
5771
5772       operands[0] = gen_rtx_SYMBOL_REF (SImode,
5773                                         \"__GCC_shcompact_call_trampoline\");
5774       if (flag_pic)
5775         {
5776           rtx reg = gen_reg_rtx (Pmode);
5777
5778           emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5779           operands[0] = reg;
5780         }
5781       operands[0] = force_reg (SImode, operands[0]);
5782
5783       emit_move_insn (r0, func);
5784       emit_move_insn (r1, cookie_rtx);
5785
5786       if (cookie & CALL_COOKIE_RET_TRAMP (1))
5787         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5788                                                    operands[2]));
5789       else
5790         emit_call_insn (gen_call_compact (operands[0], operands[1],
5791                                           operands[2]));
5792
5793       DONE;
5794     }
5795   else if (TARGET_SHCOMPACT && flag_pic
5796            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5797            && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
5798     {
5799       rtx reg = gen_reg_rtx (Pmode);
5800
5801       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5802       XEXP (operands[0], 0) = reg;
5803     }
5804   if (flag_pic && TARGET_SH2
5805       && GET_CODE (operands[0]) == MEM
5806       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5807     {
5808       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
5809       DONE;
5810     }
5811   else
5812     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5813
5814   emit_call_insn (gen_calli (operands[0], operands[1]));
5815   DONE;
5816 }")
5817
5818 (define_insn "call_pop_compact"
5819   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5820          (match_operand 1 "" ""))
5821    (match_operand 2 "immediate_operand" "n")
5822    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5823                                  (match_operand 3 "immediate_operand" "n")))
5824    (use (reg:SI R0_REG))
5825    (use (reg:SI R1_REG))
5826    (use (reg:PSI FPSCR_REG))
5827    (clobber (reg:SI PR_REG))]
5828   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5829   "jsr  @%0%#"
5830   [(set_attr "type" "call")
5831    (set (attr "fp_mode")
5832         (if_then_else (eq_attr "fpu_single" "yes")
5833                       (const_string "single") (const_string "double")))
5834    (set_attr "needs_delay_slot" "yes")])
5835
5836 (define_insn "call_pop_compact_rettramp"
5837   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5838          (match_operand 1 "" ""))
5839    (match_operand 2 "immediate_operand" "n")
5840    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5841                                  (match_operand 3 "immediate_operand" "n")))
5842    (use (reg:SI R0_REG))
5843    (use (reg:SI R1_REG))
5844    (use (reg:PSI FPSCR_REG))
5845    (clobber (reg:SI R10_REG))
5846    (clobber (reg:SI PR_REG))]
5847   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5848   "jsr  @%0%#"
5849   [(set_attr "type" "call")
5850    (set (attr "fp_mode")
5851         (if_then_else (eq_attr "fpu_single" "yes")
5852                       (const_string "single") (const_string "double")))
5853    (set_attr "needs_delay_slot" "yes")])
5854
5855 (define_expand "call_pop"
5856   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5857                     (match_operand 1 "" ""))
5858              (match_operand 2 "" "")
5859              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5860                                            (match_operand 3 "" "")))])]
5861   "TARGET_SHCOMPACT"
5862   "
5863 {
5864   if (operands[2] && INTVAL (operands[2]))
5865     {
5866       rtx cookie_rtx = operands[2];
5867       long cookie = INTVAL (cookie_rtx);
5868       rtx func = XEXP (operands[0], 0);
5869       rtx r0, r1;
5870
5871       if (flag_pic)
5872         {
5873           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5874             {
5875               rtx reg = gen_reg_rtx (Pmode);
5876
5877               emit_insn (gen_symGOTPLT2reg (reg, func));
5878               func = reg;
5879             }
5880           else
5881             func = legitimize_pic_address (func, Pmode, 0);
5882         }
5883
5884       r0 = gen_rtx_REG (SImode, R0_REG);
5885       r1 = gen_rtx_REG (SImode, R1_REG);
5886
5887       /* Since such a call function may use all call-clobbered
5888          registers, we force a mode switch earlier, so that we don't
5889          run out of registers when adjusting fpscr for the call.  */
5890       emit_insn (gen_force_mode_for_call ());
5891
5892       operands[0] = gen_rtx_SYMBOL_REF (SImode,
5893                                         \"__GCC_shcompact_call_trampoline\");
5894       if (flag_pic)
5895         {
5896           rtx reg = gen_reg_rtx (Pmode);
5897
5898           emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5899           operands[0] = reg;
5900         }
5901       operands[0] = force_reg (SImode, operands[0]);
5902
5903       emit_move_insn (r0, func);
5904       emit_move_insn (r1, cookie_rtx);
5905
5906       if (cookie & CALL_COOKIE_RET_TRAMP (1))
5907         emit_call_insn (gen_call_pop_compact_rettramp
5908                         (operands[0], operands[1], operands[2], operands[3]));
5909       else
5910         emit_call_insn (gen_call_pop_compact
5911                         (operands[0], operands[1], operands[2], operands[3]));
5912
5913       DONE;
5914     }
5915
5916   abort ();
5917 }")
5918
5919 (define_expand "call_value"
5920   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
5921                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
5922                                  (match_operand 2 "" "")))
5923               (match_operand 3 "" "")
5924               (use (reg:PSI FPSCR_REG))
5925               (clobber (reg:SI PR_REG))])]
5926   ""
5927   "
5928 {
5929   if (TARGET_SHMEDIA)
5930     {
5931       operands[1] = XEXP (operands[1], 0);
5932       if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
5933         {
5934           if (! SYMBOL_REF_FLAG (operands[1]))
5935             {
5936               rtx reg = gen_reg_rtx (Pmode);
5937
5938               emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
5939               operands[1] = reg;
5940             }
5941           else
5942             {
5943               operands[1] = gen_sym2PIC (operands[1]);
5944               PUT_MODE (operands[1], Pmode);
5945             }
5946         }
5947       if (GET_MODE (operands[1]) == SImode)
5948         {
5949           if (GET_CODE (operands[1]) == REG)
5950             operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5951           else if (GET_CODE (operands[1]) == SUBREG)
5952             {
5953               operands[1] = SUBREG_REG (operands[1]);
5954               if (GET_MODE (operands[1]) != DImode)
5955                 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5956             }
5957           else
5958             {
5959               operands[1] = shallow_copy_rtx (operands[1]);
5960               PUT_MODE (operands[1], DImode);
5961             }
5962         }
5963       if (! target_reg_operand (operands[1], DImode))
5964         operands[1] = copy_to_mode_reg (DImode, operands[1]);
5965       emit_call_insn (gen_call_value_media (operands[0], operands[1],
5966                                             operands[2]));
5967       DONE;
5968     }
5969   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
5970     {
5971       rtx cookie_rtx = operands[3];
5972       long cookie = INTVAL (cookie_rtx);
5973       rtx func = XEXP (operands[1], 0);
5974       rtx r0, r1;
5975
5976       if (flag_pic)
5977         {
5978           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5979             {
5980               rtx reg = gen_reg_rtx (Pmode);
5981
5982               emit_insn (gen_symGOTPLT2reg (reg, func));
5983               func = reg;
5984             }
5985           else
5986             func = legitimize_pic_address (func, Pmode, 0);
5987         }
5988
5989       r0 = gen_rtx_REG (SImode, R0_REG);
5990       r1 = gen_rtx_REG (SImode, R1_REG);
5991
5992       /* Since such a call function may use all call-clobbered
5993          registers, we force a mode switch earlier, so that we don't
5994          run out of registers when adjusting fpscr for the call.  */
5995       emit_insn (gen_force_mode_for_call ());
5996
5997       operands[1] = gen_rtx_SYMBOL_REF (SImode,
5998                                         \"__GCC_shcompact_call_trampoline\");
5999       if (flag_pic)
6000         {
6001           rtx reg = gen_reg_rtx (Pmode);
6002
6003           emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6004           operands[1] = reg;
6005         }
6006       operands[1] = force_reg (SImode, operands[1]);
6007
6008       emit_move_insn (r0, func);
6009       emit_move_insn (r1, cookie_rtx);
6010
6011       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6012         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
6013                                                          operands[1],
6014                                                          operands[2],
6015                                                          operands[3]));
6016       else
6017         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
6018                                                 operands[2], operands[3]));
6019
6020       DONE;
6021     }
6022   else if (TARGET_SHCOMPACT && flag_pic
6023            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6024            && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
6025     {
6026       rtx reg = gen_reg_rtx (Pmode);
6027
6028       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6029       XEXP (operands[1], 0) = reg;
6030     }
6031   if (flag_pic && TARGET_SH2
6032       && GET_CODE (operands[1]) == MEM
6033       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6034     {
6035       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6036                                             operands[2]));
6037       DONE;
6038     }
6039   else
6040     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
6041
6042   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6043   DONE;
6044 }")
6045
6046 (define_insn "sibcalli"
6047   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
6048          (match_operand 1 "" ""))
6049    (use (reg:PSI FPSCR_REG))
6050    (return)]
6051   "TARGET_SH1"
6052   "jmp  @%0%#"
6053   [(set_attr "needs_delay_slot" "yes")
6054    (set (attr "fp_mode")
6055         (if_then_else (eq_attr "fpu_single" "yes")
6056                       (const_string "single") (const_string "double")))
6057    (set_attr "type" "jump_ind")])
6058
6059 (define_insn "sibcalli_pcrel"
6060   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
6061          (match_operand 1 "" ""))
6062    (use (match_operand 2 "" ""))
6063    (use (reg:PSI FPSCR_REG))
6064    (return)]
6065   "TARGET_SH2"
6066   "braf %0\\n%O2:%#"
6067   [(set_attr "needs_delay_slot" "yes")
6068    (set (attr "fp_mode")
6069         (if_then_else (eq_attr "fpu_single" "yes")
6070                       (const_string "single") (const_string "double")))
6071    (set_attr "type" "jump_ind")])
6072
6073 (define_insn_and_split "sibcall_pcrel"
6074   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6075          (match_operand 1 "" ""))
6076    (use (reg:PSI FPSCR_REG))
6077    (clobber (match_scratch:SI 2 "=k"))
6078    (return)]
6079   "TARGET_SH2"
6080   "#"
6081   "reload_completed"
6082   [(const_int 0)]
6083   "
6084 {
6085   rtx lab = PATTERN (gen_call_site ());
6086   rtx call_insn;
6087
6088   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6089   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6090                                                   lab));
6091   SIBLING_CALL_P (call_insn) = 1;
6092   DONE;
6093 }"
6094   [(set_attr "needs_delay_slot" "yes")
6095    (set (attr "fp_mode")
6096         (if_then_else (eq_attr "fpu_single" "yes")
6097                       (const_string "single") (const_string "double")))
6098    (set_attr "type" "jump_ind")])
6099
6100 (define_insn "sibcall_compact"
6101   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6102          (match_operand 1 "" ""))
6103    (return)
6104    (use (match_operand:SI 2 "register_operand" "z,x"))
6105    (use (reg:SI R1_REG))
6106    (use (reg:PSI FPSCR_REG))
6107    ;; We want to make sure the `x' above will only match MACH_REG
6108    ;; because sibcall_epilogue may clobber MACL_REG.
6109    (clobber (reg:SI MACL_REG))]
6110   "TARGET_SHCOMPACT"
6111   "@
6112         jmp     @%0%#
6113         jmp     @%0\\n  sts     %2, r0"
6114   [(set_attr "needs_delay_slot" "yes,no")
6115    (set_attr "length" "2,4")
6116    (set (attr "fp_mode") (const_string "single"))
6117    (set_attr "type" "jump_ind")])
6118
6119 (define_insn "sibcall_media"
6120   [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6121          (match_operand 1 "" ""))
6122    (return)]
6123   "TARGET_SHMEDIA"
6124   "blink        %0, r63"
6125   [(set_attr "type" "jump_media")])
6126
6127 (define_expand "sibcall"
6128   [(parallel
6129     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6130            (match_operand 1 "" ""))
6131      (match_operand 2 "" "")
6132      (use (reg:PSI FPSCR_REG))
6133      (return)])]
6134   ""
6135   "
6136 {
6137   if (TARGET_SHMEDIA)
6138     {
6139       operands[0] = XEXP (operands[0], 0);
6140       if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6141         {
6142           if (! SYMBOL_REF_FLAG (operands[0]))
6143             {
6144               rtx reg = gen_reg_rtx (Pmode);
6145
6146               /* We must not use GOTPLT for sibcalls, because PIC_REG
6147                  must be restored before the PLT code gets to run.  */
6148               emit_insn (gen_symGOT2reg (reg, operands[0]));
6149               operands[0] = reg;
6150             }
6151           else
6152             {
6153               operands[0] = gen_sym2PIC (operands[0]);
6154               PUT_MODE (operands[0], Pmode);
6155             }
6156         }
6157       if (GET_MODE (operands[0]) == SImode)
6158         {
6159           if (GET_CODE (operands[0]) == REG)
6160             operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6161           else if (GET_CODE (operands[0]) == SUBREG)
6162             {
6163               operands[0] = SUBREG_REG (operands[0]);
6164               if (GET_MODE (operands[0]) != DImode)
6165                 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6166             }
6167           else
6168             {
6169               operands[0] = shallow_copy_rtx (operands[0]);
6170               PUT_MODE (operands[0], DImode);
6171             }
6172         }
6173       if (! target_reg_operand (operands[0], DImode))
6174         operands[0] = copy_to_mode_reg (DImode, operands[0]);
6175       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6176       DONE;
6177     }
6178   else if (TARGET_SHCOMPACT && operands[2]
6179            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6180     {
6181       rtx cookie_rtx = operands[2];
6182       long cookie = INTVAL (cookie_rtx);
6183       rtx func = XEXP (operands[0], 0);
6184       rtx mach, r1;
6185
6186       if (flag_pic)
6187         {
6188           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
6189             {
6190               rtx reg = gen_reg_rtx (Pmode);
6191
6192               emit_insn (gen_symGOT2reg (reg, func));
6193               func = reg;
6194             }
6195           else
6196             func = legitimize_pic_address (func, Pmode, 0);
6197         }
6198
6199       /* FIXME: if we could tell whether all argument registers are
6200          already taken, we could decide whether to force the use of
6201          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
6202          simple way to tell.  We could use the CALL_COOKIE, but we
6203          can't currently tell a register used for regular argument
6204          passing from one that is unused.  If we leave it up to reload
6205          to decide which register to use, it seems to always choose
6206          R0_REG, which leaves no available registers in SIBCALL_REGS
6207          to hold the address of the trampoline.  */
6208       mach = gen_rtx_REG (SImode, MACH_REG);
6209       r1 = gen_rtx_REG (SImode, R1_REG);
6210
6211       /* Since such a call function may use all call-clobbered
6212          registers, we force a mode switch earlier, so that we don't
6213          run out of registers when adjusting fpscr for the call.  */
6214       emit_insn (gen_force_mode_for_call ());
6215
6216       operands[0] = gen_rtx_SYMBOL_REF (SImode,
6217                                         \"__GCC_shcompact_call_trampoline\");
6218       if (flag_pic)
6219         {
6220           rtx reg = gen_reg_rtx (Pmode);
6221
6222           emit_insn (gen_symGOT2reg (reg, operands[0]));
6223           operands[0] = reg;
6224         }
6225       operands[0] = force_reg (SImode, operands[0]);
6226
6227       /* We don't need a return trampoline, since the callee will
6228          return directly to the upper caller.  */
6229       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6230         {
6231           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6232           cookie_rtx = GEN_INT (cookie);
6233         }
6234
6235       emit_move_insn (mach, func);
6236       emit_move_insn (r1, cookie_rtx);
6237
6238       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6239       DONE;
6240     }
6241   else if (TARGET_SHCOMPACT && flag_pic
6242            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6243            && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
6244     {
6245       rtx reg = gen_reg_rtx (Pmode);
6246
6247       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6248       XEXP (operands[0], 0) = reg;
6249     }
6250   if (flag_pic && TARGET_SH2
6251       && GET_CODE (operands[0]) == MEM
6252       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6253       /* The PLT needs the PIC register, but the epilogue would have
6254          to restore it, so we can only use PC-relative PIC calls for
6255          static functions.  */
6256       && SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
6257     {
6258       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6259       DONE;
6260     }
6261   else
6262     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
6263
6264   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6265   DONE;
6266 }")
6267
6268 (define_expand "sibcall_value"
6269   [(set (match_operand 0 "" "")
6270         (call (match_operand 1 "" "")
6271               (match_operand 2 "" "")))
6272    (match_operand 3 "" "")]
6273   ""
6274   "
6275 {
6276   emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
6277   DONE;
6278 }")
6279
6280 (define_insn "call_value_pop_compact"
6281   [(set (match_operand 0 "" "=rf")
6282         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6283               (match_operand 2 "" "")))
6284    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6285                                  (match_operand 4 "immediate_operand" "n")))
6286    (match_operand 3 "immediate_operand" "n")
6287    (use (reg:SI R0_REG))
6288    (use (reg:SI R1_REG))
6289    (use (reg:PSI FPSCR_REG))
6290    (clobber (reg:SI PR_REG))]
6291   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6292   "jsr  @%1%#"
6293   [(set_attr "type" "call")
6294    (set (attr "fp_mode")
6295         (if_then_else (eq_attr "fpu_single" "yes")
6296                       (const_string "single") (const_string "double")))
6297    (set_attr "needs_delay_slot" "yes")])
6298
6299 (define_insn "call_value_pop_compact_rettramp"
6300   [(set (match_operand 0 "" "=rf")
6301         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6302               (match_operand 2 "" "")))
6303    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6304                                  (match_operand 4 "immediate_operand" "n")))
6305    (match_operand 3 "immediate_operand" "n")
6306    (use (reg:SI R0_REG))
6307    (use (reg:SI R1_REG))
6308    (use (reg:PSI FPSCR_REG))
6309    (clobber (reg:SI R10_REG))
6310    (clobber (reg:SI PR_REG))]
6311   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6312   "jsr  @%1%#"
6313   [(set_attr "type" "call")
6314    (set (attr "fp_mode")
6315         (if_then_else (eq_attr "fpu_single" "yes")
6316                       (const_string "single") (const_string "double")))
6317    (set_attr "needs_delay_slot" "yes")])
6318
6319 (define_expand "call_value_pop"
6320   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6321                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6322                                  (match_operand 2 "" "")))
6323               (match_operand 3 "" "")
6324               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6325                                             (match_operand 4 "" "")))])]
6326   "TARGET_SHCOMPACT"
6327   "
6328 {
6329   if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6330     {
6331       rtx cookie_rtx = operands[3];
6332       long cookie = INTVAL (cookie_rtx);
6333       rtx func = XEXP (operands[1], 0);
6334       rtx r0, r1;
6335
6336       if (flag_pic)
6337         {
6338           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
6339             {
6340               rtx reg = gen_reg_rtx (Pmode);
6341
6342               emit_insn (gen_symGOTPLT2reg (reg, func));
6343               func = reg;
6344             }
6345           else
6346             func = legitimize_pic_address (func, Pmode, 0);
6347         }
6348
6349       r0 = gen_rtx_REG (SImode, R0_REG);
6350       r1 = gen_rtx_REG (SImode, R1_REG);
6351
6352       /* Since such a call function may use all call-clobbered
6353          registers, we force a mode switch earlier, so that we don't
6354          run out of registers when adjusting fpscr for the call.  */
6355       emit_insn (gen_force_mode_for_call ());
6356
6357       operands[1] = gen_rtx_SYMBOL_REF (SImode,
6358                                         \"__GCC_shcompact_call_trampoline\");
6359       if (flag_pic)
6360         {
6361           rtx reg = gen_reg_rtx (Pmode);
6362
6363           emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6364           operands[1] = reg;
6365         }
6366       operands[1] = force_reg (SImode, operands[1]);
6367
6368       emit_move_insn (r0, func);
6369       emit_move_insn (r1, cookie_rtx);
6370
6371       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6372         emit_call_insn (gen_call_value_pop_compact_rettramp
6373                         (operands[0], operands[1], operands[2],
6374                          operands[3], operands[4]));
6375       else
6376         emit_call_insn (gen_call_value_pop_compact
6377                         (operands[0], operands[1], operands[2],
6378                          operands[3], operands[4]));
6379
6380       DONE;
6381     }
6382
6383   abort ();
6384 }")
6385
6386 (define_expand "sibcall_epilogue"
6387   [(return)]
6388   ""
6389   "
6390 {
6391   sh_expand_epilogue ();
6392   if (TARGET_SHCOMPACT)
6393     {
6394       rtx insn, set;
6395
6396       /* If epilogue clobbers r0, preserve it in macl.  */
6397       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6398         if ((set = single_set (insn))
6399             && GET_CODE (SET_DEST (set)) == REG
6400             && REGNO (SET_DEST (set)) == R0_REG)
6401           {
6402             rtx r0 = gen_rtx_REG (SImode, R0_REG);
6403             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6404             rtx i;
6405
6406             /* We can't tell at this point whether the sibcall is a
6407                sibcall_compact and, if it is, whether it uses r0 or
6408                mach as operand 2, so let the instructions that
6409                preserve r0 be optimized away if r0 turns out to be
6410                dead.  */
6411             i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6412             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6413                                                REG_NOTES (i));
6414             i = emit_move_insn (r0, tmp);
6415             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6416                                                REG_NOTES (i));
6417             break;
6418           }
6419     }
6420   DONE;
6421 }")
6422
6423 (define_insn "indirect_jump_compact"
6424   [(set (pc)
6425         (match_operand:SI 0 "arith_reg_operand" "r"))]
6426   "TARGET_SH1"
6427   "jmp  @%0%#"
6428   [(set_attr "needs_delay_slot" "yes")
6429    (set_attr "type" "jump_ind")])
6430
6431 (define_expand "indirect_jump"
6432   [(set (pc)
6433         (match_operand 0 "register_operand" ""))]
6434   ""
6435   "
6436 {
6437   if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6438     operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6439 }")
6440
6441 ;; The use of operand 1 / 2 helps us distinguish case table jumps
6442 ;; which can be present in structured code from indirect jumps which can not
6443 ;; be present in structured code.  This allows -fprofile-arcs to work.
6444
6445 ;; For SH1 processors.
6446 (define_insn "casesi_jump_1"
6447   [(set (pc)
6448         (match_operand:SI 0 "register_operand" "r"))
6449    (use (label_ref (match_operand 1 "" "")))]
6450   "TARGET_SH1"
6451   "jmp  @%0%#"
6452   [(set_attr "needs_delay_slot" "yes")
6453    (set_attr "type" "jump_ind")])
6454
6455 ;; For all later processors.
6456 (define_insn "casesi_jump_2"
6457   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
6458                       (label_ref (match_operand 1 "" ""))))
6459    (use (label_ref (match_operand 2 "" "")))]
6460   "TARGET_SH2
6461    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
6462   "braf %0%#"
6463   [(set_attr "needs_delay_slot" "yes")
6464    (set_attr "type" "jump_ind")])
6465
6466 (define_insn "casesi_jump_media"
6467   [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6468    (use (label_ref (match_operand 1 "" "")))]
6469   "TARGET_SHMEDIA"
6470   "blink        %0, r63"
6471   [(set_attr "type" "jump_media")])
6472
6473 ;; Call subroutine returning any type.
6474 ;; ??? This probably doesn't work.
6475
6476 (define_expand "untyped_call"
6477   [(parallel [(call (match_operand 0 "" "")
6478                     (const_int 0))
6479               (match_operand 1 "" "")
6480               (match_operand 2 "" "")])]
6481   "TARGET_SH3E || TARGET_SHMEDIA"
6482   "
6483 {
6484   int i;
6485
6486   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
6487
6488   for (i = 0; i < XVECLEN (operands[2], 0); i++)
6489     {
6490       rtx set = XVECEXP (operands[2], 0, i);
6491       emit_move_insn (SET_DEST (set), SET_SRC (set));
6492     }
6493
6494   /* The optimizer does not know that the call sets the function value
6495      registers we stored in the result block.  We avoid problems by
6496      claiming that all hard registers are used and clobbered at this
6497      point.  */
6498   emit_insn (gen_blockage ());
6499
6500   DONE;
6501 }")
6502 \f
6503 ;; ------------------------------------------------------------------------
6504 ;; Misc insns
6505 ;; ------------------------------------------------------------------------
6506
6507 (define_insn "dect"
6508   [(set (reg:SI T_REG)
6509         (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6510    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
6511   "TARGET_SH2"
6512   "dt   %0"
6513   [(set_attr "type" "arith")])
6514
6515 (define_insn "nop"
6516   [(const_int 0)]
6517   ""
6518   "nop")
6519
6520 ;; Load address of a label. This is only generated by the casesi expand,
6521 ;; and by machine_dependent_reorg (fixing up fp moves).
6522 ;; This must use unspec, because this only works for labels that are
6523 ;; within range,
6524
6525 (define_insn "mova"
6526   [(set (reg:SI R0_REG)
6527         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
6528   "TARGET_SH1"
6529   "mova %O0,r0"
6530   [(set_attr "in_delay_slot" "no")
6531    (set_attr "type" "arith")])
6532
6533 ;; machine_dependent_reorg() will make this a `mova'.
6534 (define_insn "mova_const"
6535   [(set (reg:SI R0_REG)
6536         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
6537   "TARGET_SH1"
6538   "#"
6539   [(set_attr "in_delay_slot" "no")
6540    (set_attr "type" "arith")])
6541
6542 (define_expand "GOTaddr2picreg"
6543   [(set (reg:SI R0_REG)
6544         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6545                    UNSPEC_MOVA))
6546    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
6547    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6548   "" "
6549 {
6550   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
6551   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
6552
6553   if (TARGET_SH5)
6554     operands[1] = gen_datalabel_ref (operands[1]);
6555
6556   if (TARGET_SHMEDIA)
6557     {
6558       rtx tr = gen_rtx_REG (DImode, TR0_REG);
6559       rtx dipic = operands[0];
6560       rtx lab = PATTERN (gen_call_site ());
6561       rtx insn, equiv;
6562
6563       equiv = operands[1];
6564       operands[1] = gen_rtx_MINUS (DImode,
6565                                    operands[1],
6566                                    gen_rtx_CONST
6567                                    (DImode,
6568                                     gen_rtx_MINUS (DImode,
6569                                                    gen_rtx_CONST (DImode,
6570                                                                   lab),
6571                                                    pc_rtx)));
6572       operands[1] = gen_sym2PIC (operands[1]);
6573       PUT_MODE (operands[1], DImode);
6574
6575       if (GET_MODE (dipic) != DImode)
6576         dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6577
6578       if (TARGET_SHMEDIA64)
6579         emit_insn (gen_movdi_const (dipic, operands[1]));
6580       else
6581         emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6582
6583       emit_insn (gen_ptrel (tr, dipic, lab));
6584
6585       if (GET_MODE (operands[0]) != GET_MODE (tr))
6586         tr = gen_rtx_SUBREG (GET_MODE (operands[0]), tr, 0);
6587
6588       insn = emit_move_insn (operands[0], tr);
6589
6590       REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6591                                             REG_NOTES (insn));
6592
6593       DONE;
6594     }
6595 }
6596 ")
6597
6598 ;; When generating PIC, we must match label_refs especially, because
6599 ;; they do not satisfy LEGITIMATE_PIC_OPERAND_P(), and we don't want
6600 ;; them to do, because they can't be loaded directly into
6601 ;; non-branch-target registers.
6602 (define_insn "*pt"
6603   [(set (match_operand:DI 0 "target_reg_operand" "=b")
6604         (match_operand:DI 1 "" "T"))]
6605   "TARGET_SHMEDIA && flag_pic
6606    && EXTRA_CONSTRAINT_T (operands[1])"
6607   "pt   %1, %0"
6608   [(set_attr "type" "pt_media")
6609    (set_attr "length" "*")])
6610
6611 (define_insn "*ptb"
6612   [(set (match_operand:DI 0 "target_reg_operand" "=b")
6613         (const:DI (unspec:DI [(match_operand:DI 1 "" "T")]
6614                              UNSPEC_DATALABEL)))]
6615   "TARGET_SHMEDIA && flag_pic
6616    && EXTRA_CONSTRAINT_T (operands[1])"
6617   "ptb/u        datalabel %1, %0"
6618   [(set_attr "type" "pt_media")
6619    (set_attr "length" "*")])
6620
6621 (define_insn "ptrel"
6622   [(set (match_operand:DI 0 "target_reg_operand" "=b")
6623         (plus:DI (match_operand:DI 1 "register_operand" "r")
6624               (pc)))
6625    (match_operand:DI 2 "" "")]
6626   "TARGET_SHMEDIA"
6627   "%O2: ptrel/u %1, %0"
6628   [(set_attr "type" "ptabs_media")])
6629
6630 (define_expand "builtin_setjmp_receiver"
6631   [(match_operand 0 "" "")]
6632   "flag_pic"
6633   "
6634 {
6635   emit_insn (gen_GOTaddr2picreg ());
6636   DONE;
6637 }")
6638
6639 (define_expand "call_site"
6640   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
6641   "TARGET_SH1"
6642   "
6643 {
6644   static HOST_WIDE_INT i = 0;
6645   operands[0] = GEN_INT (i);
6646   i++;
6647 }")
6648
6649 (define_expand "sym_label2reg"
6650   [(set (match_operand:SI 0 "" "")
6651         (const:SI (minus:SI
6652                    (const:SI
6653                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6654                    (const:SI
6655                     (plus:SI
6656                      (match_operand:SI 2 "" "")
6657                      (const_int 2))))))]
6658   "TARGET_SH1" "")
6659
6660 (define_expand "symGOT_load"
6661   [(set (match_dup 2) (match_operand 1 "" ""))
6662    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6663    (set (match_operand 0 "" "") (mem (match_dup 3)))]
6664   ""
6665   "
6666 {
6667   rtx insn;
6668
6669   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6670   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6671
6672   if (TARGET_SHMEDIA)
6673     {
6674       rtx reg = operands[2];
6675
6676       if (GET_MODE (reg) != DImode)
6677         reg = gen_rtx_SUBREG (DImode, reg, 0);
6678
6679       if (flag_pic > 1)
6680         emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6681       else
6682         emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6683     }
6684   else
6685     emit_move_insn (operands[2], operands[1]);
6686
6687   emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6688                                              operands[2],
6689                                              gen_rtx_REG (Pmode, PIC_REG)));
6690
6691   insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6692
6693   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6694                                                                   0), 0, 0),
6695                                         REG_NOTES (insn));
6696
6697   DONE;
6698 }")
6699
6700 (define_expand "sym2GOT"
6701   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6702   ""
6703   "")
6704
6705 (define_expand "symGOT2reg"
6706   [(match_operand 0 "" "") (match_operand 1 "" "")]
6707   ""
6708   "
6709 {
6710   rtx gotsym, insn;
6711
6712   gotsym = gen_sym2GOT (operands[1]);
6713   PUT_MODE (gotsym, Pmode);
6714   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6715
6716   RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
6717
6718   DONE;
6719 }")
6720
6721 (define_expand "sym2GOTPLT"
6722   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6723   ""
6724   "")
6725
6726 (define_expand "symGOTPLT2reg"
6727   [(match_operand 0 "" "") (match_operand 1 "" "")]
6728   ""
6729   "
6730 {
6731   emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6732   DONE;
6733 }")
6734
6735 (define_expand "sym2GOTOFF"
6736   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6737   ""
6738   "")
6739
6740 (define_expand "symGOTOFF2reg"
6741   [(match_operand 0 "" "") (match_operand 1 "" "")]
6742   ""
6743   "
6744 {
6745   rtx gotoffsym, insn;
6746   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6747
6748   gotoffsym = gen_sym2GOTOFF (operands[1]);
6749   PUT_MODE (gotoffsym, Pmode);
6750   emit_move_insn (t, gotoffsym);
6751   insn = emit_move_insn (operands[0],
6752                          gen_rtx_PLUS (Pmode, t,
6753                                        gen_rtx_REG (Pmode, PIC_REG)));
6754
6755   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6756                                         REG_NOTES (insn));
6757
6758   DONE;
6759 }")
6760
6761 (define_expand "symPLT_label2reg"
6762   [(set (match_operand:SI 0 "" "")
6763         (const:SI (minus:SI
6764                    (const:SI
6765                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6766                    (const:SI
6767                     (minus:SI
6768                      (const:SI (plus:SI
6769                                 (match_operand:SI 2 "" "")
6770                                 (const_int 2)))
6771                      (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6772    ;; Even though the PIC register is not really used by the call
6773    ;; sequence in which this is expanded, the PLT code assumes the PIC
6774    ;; register is set, so we must not skip its initialization.  Since
6775    ;; we only use this expand as part of calling sequences, and never
6776    ;; to take the address of a function, this is the best point to
6777    ;; insert the (use).  Using the PLT to take the address of a
6778    ;; function would be wrong, not only because the PLT entry could
6779    ;; then be called from a function that doesn't initialize the PIC
6780    ;; register to the proper GOT, but also because pointers to the
6781    ;; same function might not compare equal, should they be set by
6782    ;; different shared libraries.
6783    (use (reg:SI PIC_REG))]
6784   "TARGET_SH1"
6785   "")
6786
6787 (define_expand "sym2PIC"
6788   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6789   ""
6790   "")
6791
6792 ;; case instruction for switch statements.
6793
6794 ;; Operand 0 is index
6795 ;; operand 1 is the minimum bound
6796 ;; operand 2 is the maximum bound - minimum bound + 1
6797 ;; operand 3 is CODE_LABEL for the table;
6798 ;; operand 4 is the CODE_LABEL to go to if index out of range.
6799
6800 (define_expand "casesi"
6801   [(match_operand:SI 0 "arith_reg_operand" "")
6802    (match_operand:SI 1 "arith_reg_operand" "")
6803    (match_operand:SI 2 "arith_reg_operand" "")
6804    (match_operand 3 "" "") (match_operand 4 "" "")]
6805   ""
6806   "
6807 {
6808   rtx reg = gen_reg_rtx (SImode);
6809   rtx reg2 = gen_reg_rtx (SImode);
6810   if (TARGET_SHMEDIA)
6811     {
6812       rtx reg = gen_reg_rtx (DImode);
6813       rtx reg2 = gen_reg_rtx (DImode);
6814       rtx reg3 = gen_reg_rtx (DImode);
6815       rtx reg4 = gen_reg_rtx (DImode);
6816       rtx reg5 = gen_reg_rtx (DImode);
6817
6818       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
6819       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
6820       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
6821
6822       emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
6823       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
6824       emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
6825       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
6826       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
6827                                                (DImode, operands[3])));
6828       emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
6829       emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
6830       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
6831       emit_barrier ();
6832       DONE;
6833     }
6834   operands[1] = copy_to_mode_reg (SImode, operands[1]);
6835   operands[2] = copy_to_mode_reg (SImode, operands[2]);
6836   /* If optimizing, casesi_worker depends on the mode of the instruction
6837      before label it 'uses' - operands[3].  */
6838   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
6839                            reg));
6840   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
6841   if (TARGET_SH2)
6842     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
6843   else
6844     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
6845   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
6846      operands[3], but to lab.  We will fix this up in
6847      machine_dependent_reorg.  */
6848   emit_barrier ();
6849   DONE;
6850 }")
6851
6852 (define_expand "casesi_0"
6853   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
6854    (set (match_dup 4) (minus:SI (match_dup 4)
6855                                 (match_operand:SI 1 "arith_operand" "")))
6856    (set (reg:SI T_REG)
6857         (gtu:SI (match_dup 4)
6858                 (match_operand:SI 2 "arith_reg_operand" "")))
6859    (set (pc)
6860         (if_then_else (ne (reg:SI T_REG)
6861                           (const_int 0))
6862                       (label_ref (match_operand 3 "" ""))
6863                       (pc)))]
6864   "TARGET_SH1"
6865   "")
6866
6867 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
6868 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
6869 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
6870
6871 (define_insn "casesi_worker_0"
6872   [(set (match_operand:SI 0 "register_operand" "=r,r")
6873         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
6874                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6875    (clobber (match_scratch:SI 3 "=X,1"))
6876    (clobber (match_scratch:SI 4 "=&z,z"))]
6877   "TARGET_SH1"
6878   "#")
6879
6880 (define_split
6881   [(set (match_operand:SI 0 "register_operand" "")
6882         (unspec:SI [(match_operand:SI 1 "register_operand" "")
6883                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6884    (clobber (match_scratch:SI 3 ""))
6885    (clobber (match_scratch:SI 4 ""))]
6886   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
6887   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
6888    (parallel [(set (match_dup 0)
6889               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
6890                           (label_ref (match_dup 2))] UNSPEC_CASESI))
6891               (clobber (match_dup 3))])
6892    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6893   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
6894
6895 (define_split
6896   [(set (match_operand:SI 0 "register_operand" "")
6897         (unspec:SI [(match_operand:SI 1 "register_operand" "")
6898                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6899    (clobber (match_scratch:SI 3 ""))
6900    (clobber (match_scratch:SI 4 ""))]
6901   "TARGET_SH2 && reload_completed"
6902   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
6903    (parallel [(set (match_dup 0)
6904               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
6905                           (label_ref (match_dup 2))] UNSPEC_CASESI))
6906               (clobber (match_dup 3))])]
6907   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
6908
6909 (define_insn "*casesi_worker"
6910   [(set (match_operand:SI 0 "register_operand" "=r,r")
6911         (unspec:SI [(reg:SI R0_REG)
6912                     (match_operand:SI 1 "register_operand" "0,r")
6913                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6914    (clobber (match_scratch:SI 3 "=X,1"))]
6915   "TARGET_SH1"
6916   "*
6917 {
6918   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
6919
6920   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6921     abort ();
6922
6923   switch (GET_MODE (diff_vec))
6924     {
6925     case SImode:
6926       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
6927     case HImode:
6928       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
6929     case QImode:
6930       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
6931         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
6932       return \"mov.b    @(r0,%1),%0\";
6933     default:
6934       abort ();
6935     }
6936 }"
6937   [(set_attr "length" "4")])
6938
6939 (define_insn "casesi_shift_media"
6940   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
6941         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
6942                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
6943                     UNSPEC_CASESI)))]
6944   "TARGET_SHMEDIA"
6945   "*
6946 {
6947   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
6948
6949   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6950     abort ();
6951
6952   switch (GET_MODE (diff_vec))
6953     {
6954     case SImode:
6955       return \"shlli    %1, 2, %0\";
6956     case HImode:
6957       return \"shlli    %1, 1, %0\";
6958     case QImode:
6959       if (rtx_equal_p (operands[0], operands[1]))
6960         return \"\";
6961       return \"add      %1, r63, %0\";
6962     default:
6963       abort ();
6964     }
6965 }"
6966   [(set_attr "type" "arith_media")])
6967
6968 (define_insn "casesi_load_media"
6969   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
6970         (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
6971                          (match_operand 2 "arith_reg_operand" "r")
6972                          (label_ref:DI (match_operand 3 "" ""))] 2)))]
6973   "TARGET_SHMEDIA"
6974   "*
6975 {
6976   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
6977
6978   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6979     abort ();
6980
6981   switch (GET_MODE (diff_vec))
6982     {
6983     case SImode:
6984       return \"ldx.l    %1, %2, %0\";
6985     case HImode:
6986 #if 0
6987       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
6988         return \"ldx.uw %1, %2, %0\";
6989 #endif
6990       return \"ldx.w    %1, %2, %0\";
6991     case QImode:
6992       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
6993         return \"ldx.ub %1, %2, %0\";
6994       return \"ldx.b    %1, %2, %0\";
6995     default:
6996       abort ();
6997     }
6998 }"
6999   [(set_attr "type" "load_media")])
7000
7001 (define_expand "return"
7002   [(return)]
7003   "reload_completed && ! sh_need_epilogue ()"
7004   "
7005 {
7006   if (TARGET_SHMEDIA)
7007     {
7008       emit_jump_insn (gen_return_media ());
7009       DONE;
7010     }
7011
7012   if (TARGET_SHCOMPACT
7013       && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
7014     {
7015       emit_jump_insn (gen_shcompact_return_tramp ());
7016       DONE;
7017     }
7018 }")
7019
7020 (define_insn "*return_i"
7021   [(return)]
7022   "TARGET_SH1 && ! (TARGET_SHCOMPACT
7023                     && (current_function_args_info.call_cookie
7024                         & CALL_COOKIE_RET_TRAMP (1)))
7025    && reload_completed"
7026   "%@   %#"
7027   [(set_attr "type" "return")
7028    (set_attr "needs_delay_slot" "yes")])
7029
7030 (define_expand "shcompact_return_tramp"
7031   [(return)]
7032   "TARGET_SHCOMPACT
7033    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7034   "
7035 {
7036   rtx reg = gen_rtx_REG (Pmode, R0_REG);
7037   rtx sym = gen_rtx_SYMBOL_REF (Pmode,
7038                                 \"__GCC_shcompact_return_trampoline\");
7039
7040   if (flag_pic)
7041     emit_insn (gen_symGOTPLT2reg (reg, sym));
7042   else
7043     emit_move_insn (reg, sym);
7044
7045   emit_jump_insn (gen_shcompact_return_tramp_i ());
7046   DONE;
7047 }")
7048
7049 (define_insn "shcompact_return_tramp_i"
7050   [(parallel [(return) (use (reg:SI R0_REG))])]
7051   "TARGET_SHCOMPACT
7052    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7053   "jmp  @r0%#"
7054   [(set_attr "type" "jump_ind")
7055    (set_attr "needs_delay_slot" "yes")])
7056
7057 (define_insn "return_media_i"
7058   [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7059   "TARGET_SHMEDIA && reload_completed"
7060   "blink        %0, r63"
7061   [(set_attr "type" "jump_media")])
7062
7063 (define_expand "return_media"
7064   [(return)]
7065   "TARGET_SHMEDIA && reload_completed"
7066   "
7067 {
7068   int tr_regno = sh_media_register_for_return ();
7069   rtx tr;
7070
7071   if (tr_regno < 0)
7072     {
7073       rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7074
7075       tr_regno = TR0_REG;
7076       tr = gen_rtx_REG (DImode, tr_regno);
7077       emit_move_insn (tr, r18);
7078     }
7079   else
7080     tr = gen_rtx_REG (DImode, tr_regno);
7081
7082   emit_jump_insn (gen_return_media_i (tr));
7083   DONE;
7084 }")
7085
7086 (define_insn "shcompact_preserve_incoming_args"
7087   [(set (match_operand:SI 0 "register_operand" "+r")
7088         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
7089   "TARGET_SHCOMPACT"
7090   ""
7091   [(set_attr "length" "0")])
7092
7093 (define_insn "shcompact_incoming_args"
7094   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7095    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7096    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7097    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7098    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7099    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7100    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7101    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
7102    (set (mem:BLK (reg:SI MACL_REG))
7103         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
7104    (use (reg:SI R0_REG))
7105    (clobber (reg:SI R0_REG))
7106    (clobber (reg:SI MACL_REG))
7107    (clobber (reg:SI MACH_REG))
7108    (clobber (reg:SI PR_REG))]
7109   "TARGET_SHCOMPACT"
7110   "jsr  @r0%#"
7111   [(set_attr "needs_delay_slot" "yes")])
7112
7113 (define_insn "shmedia_save_restore_regs_compact"
7114   [(set (reg:SI SP_REG)
7115         (plus:SI (reg:SI SP_REG)
7116                  (match_operand:SI 0 "immediate_operand" "i")))
7117    (use (reg:SI R0_REG))
7118    (clobber (reg:SI PR_REG))]
7119   "TARGET_SHCOMPACT
7120    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7121        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7122   "jsr @r0%#"
7123   [(set_attr "needs_delay_slot" "yes")])
7124
7125 (define_expand "prologue"
7126   [(const_int 0)]
7127   ""
7128   "sh_expand_prologue (); DONE;")
7129
7130 (define_expand "epilogue"
7131   [(return)]
7132   ""
7133   "
7134 {
7135   sh_expand_epilogue ();
7136   emit_jump_insn (gen_return ());
7137   DONE;
7138 }")
7139
7140 (define_insn "blockage"
7141   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7142   ""
7143   ""
7144   [(set_attr "length" "0")])
7145 \f
7146 ;; ------------------------------------------------------------------------
7147 ;; Scc instructions
7148 ;; ------------------------------------------------------------------------
7149
7150 (define_insn "movt"
7151   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7152         (eq:SI (reg:SI T_REG) (const_int 1)))]
7153   "TARGET_SH1"
7154   "movt %0"
7155   [(set_attr "type" "arith")])
7156
7157 (define_expand "seq"
7158   [(set (match_operand:SI 0 "arith_reg_operand" "")
7159         (match_dup 1))]
7160   ""
7161   "
7162 {
7163   if (TARGET_SHMEDIA)
7164     {
7165       if (GET_MODE (operands[0]) != DImode)
7166         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7167       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7168       if (sh_compare_op1 != const0_rtx)
7169         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7170                                     ? GET_MODE (sh_compare_op0)
7171                                     : GET_MODE (sh_compare_op1),
7172                                     sh_compare_op1);
7173
7174       switch (GET_MODE (sh_compare_op0))
7175         {
7176         case DImode:
7177           emit_insn (gen_cmpeqdi_media (operands[0],
7178                                         sh_compare_op0, sh_compare_op1));
7179           break;
7180
7181         case SFmode:
7182           if (! TARGET_SHMEDIA_FPU)
7183             FAIL;
7184           emit_insn (gen_cmpeqsf_media (operands[0],
7185                                         sh_compare_op0, sh_compare_op1));
7186           break;
7187
7188         case DFmode:
7189           if (! TARGET_SHMEDIA_FPU)
7190             FAIL;
7191           emit_insn (gen_cmpeqdf_media (operands[0],
7192                                         sh_compare_op0, sh_compare_op1));
7193           break;
7194
7195         default:
7196           FAIL;
7197         }
7198       DONE;
7199     }
7200   operands[1] = prepare_scc_operands (EQ);
7201 }")
7202
7203 (define_expand "slt"
7204   [(set (match_operand:SI 0 "arith_reg_operand" "")
7205         (match_dup 1))]
7206   ""
7207   "
7208 {
7209   if (TARGET_SHMEDIA)
7210     {
7211       if (GET_MODE (operands[0]) != DImode)
7212         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7213       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7214       if (sh_compare_op1 != const0_rtx)
7215         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7216                                     ? GET_MODE (sh_compare_op0)
7217                                     : GET_MODE (sh_compare_op1),
7218                                     sh_compare_op1);
7219
7220       switch (GET_MODE (sh_compare_op0))
7221         {
7222         case DImode:
7223           emit_insn (gen_cmpgtdi_media (operands[0],
7224                                         sh_compare_op1, sh_compare_op0));
7225           break;
7226
7227         case SFmode:
7228           if (! TARGET_SHMEDIA_FPU)
7229             FAIL;
7230           emit_insn (gen_cmpgtsf_media (operands[0],
7231                                         sh_compare_op1, sh_compare_op0));
7232           break;
7233
7234         case DFmode:
7235           if (! TARGET_SHMEDIA_FPU)
7236             FAIL;
7237           emit_insn (gen_cmpgtdf_media (operands[0],
7238                                         sh_compare_op1, sh_compare_op0));
7239           break;
7240
7241         default:
7242           FAIL;
7243         }
7244       DONE;
7245     }
7246   operands[1] = prepare_scc_operands (LT);
7247 }")
7248
7249 (define_expand "sle"
7250   [(match_operand:SI 0 "arith_reg_operand" "")]
7251   ""
7252   "
7253 {
7254   rtx tmp = sh_compare_op0;
7255
7256   if (TARGET_SHMEDIA)
7257     {
7258       if (GET_MODE (operands[0]) != DImode)
7259         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7260       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7261       if (sh_compare_op1 != const0_rtx)
7262         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7263                                     ? GET_MODE (sh_compare_op0)
7264                                     : GET_MODE (sh_compare_op1),
7265                                     sh_compare_op1);
7266
7267       switch (GET_MODE (sh_compare_op0))
7268         {
7269         case DImode:
7270           {
7271             tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7272
7273             emit_insn (gen_cmpgtdi_media (tmp,
7274                                           sh_compare_op0, sh_compare_op1));
7275             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7276             break;
7277           }
7278
7279         case SFmode:
7280           if (! TARGET_SHMEDIA_FPU)
7281             FAIL;
7282           emit_insn (gen_cmpgesf_media (operands[0],
7283                                         sh_compare_op1, sh_compare_op0));
7284           break;
7285
7286         case DFmode:
7287           if (! TARGET_SHMEDIA_FPU)
7288             FAIL;
7289           emit_insn (gen_cmpgedf_media (operands[0],
7290                                         sh_compare_op1, sh_compare_op0));
7291           break;
7292
7293         default:
7294           FAIL;
7295         }
7296       DONE;
7297     }
7298
7299   sh_compare_op0 = sh_compare_op1;
7300   sh_compare_op1 = tmp;
7301   emit_insn (gen_sge (operands[0]));
7302   DONE;
7303 }")
7304
7305 (define_expand "sgt"
7306   [(set (match_operand:SI 0 "arith_reg_operand" "")
7307         (match_dup 1))]
7308   ""
7309   "
7310 {
7311   if (TARGET_SHMEDIA)
7312     {
7313       if (GET_MODE (operands[0]) != DImode)
7314         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7315       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7316       if (sh_compare_op1 != const0_rtx)
7317         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7318                                     ? GET_MODE (sh_compare_op0)
7319                                     : GET_MODE (sh_compare_op1),
7320                                     sh_compare_op1);
7321
7322       switch (GET_MODE (sh_compare_op0))
7323         {
7324         case DImode:
7325           emit_insn (gen_cmpgtdi_media (operands[0],
7326                                         sh_compare_op0, sh_compare_op1));
7327           break;
7328
7329         case SFmode:
7330           if (! TARGET_SHMEDIA_FPU)
7331             FAIL;
7332           emit_insn (gen_cmpgtsf_media (operands[0],
7333                                         sh_compare_op0, sh_compare_op1));
7334           break;
7335
7336         case DFmode:
7337           if (! TARGET_SHMEDIA_FPU)
7338             FAIL;
7339           emit_insn (gen_cmpgtdf_media (operands[0],
7340                                         sh_compare_op0, sh_compare_op1));
7341           break;
7342
7343         default:
7344           FAIL;
7345         }
7346       DONE;
7347     }
7348   operands[1] = prepare_scc_operands (GT);
7349 }")
7350
7351 (define_expand "sge"
7352   [(set (match_operand:SI 0 "arith_reg_operand" "")
7353         (match_dup 1))]
7354   ""
7355   "
7356 {
7357   if (TARGET_SHMEDIA)
7358     {
7359       if (GET_MODE (operands[0]) != DImode)
7360         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7361       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7362       if (sh_compare_op1 != const0_rtx)
7363         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7364                                     ? GET_MODE (sh_compare_op0)
7365                                     : GET_MODE (sh_compare_op1),
7366                                     sh_compare_op1);
7367
7368       switch (GET_MODE (sh_compare_op0))
7369         {
7370         case DImode:
7371           {
7372             rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7373
7374             emit_insn (gen_cmpgtdi_media (tmp,
7375                                           sh_compare_op1, sh_compare_op0));
7376             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7377             break;
7378           }
7379
7380         case SFmode:
7381           if (! TARGET_SHMEDIA_FPU)
7382             FAIL;
7383           emit_insn (gen_cmpgesf_media (operands[0],
7384                                         sh_compare_op0, sh_compare_op1));
7385           break;
7386
7387         case DFmode:
7388           if (! TARGET_SHMEDIA_FPU)
7389             FAIL;
7390           emit_insn (gen_cmpgedf_media (operands[0],
7391                                         sh_compare_op0, sh_compare_op1));
7392           break;
7393
7394         default:
7395           FAIL;
7396         }
7397       DONE;
7398     }
7399
7400   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7401     {
7402       if (TARGET_IEEE)
7403         {
7404           rtx lab = gen_label_rtx ();
7405           prepare_scc_operands (EQ);
7406           emit_jump_insn (gen_branch_true (lab));
7407           prepare_scc_operands (GT);
7408           emit_label (lab);
7409           emit_insn (gen_movt (operands[0]));
7410         }
7411       else
7412         emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
7413       DONE;
7414     }
7415   operands[1] = prepare_scc_operands (GE);
7416 }")
7417
7418 (define_expand "sgtu"
7419   [(set (match_operand:SI 0 "arith_reg_operand" "")
7420         (match_dup 1))]
7421   ""
7422   "
7423 {
7424   if (TARGET_SHMEDIA)
7425     {
7426       if (GET_MODE (operands[0]) != DImode)
7427         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7428       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7429       if (sh_compare_op1 != const0_rtx)
7430         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7431                                     ? GET_MODE (sh_compare_op0)
7432                                     : GET_MODE (sh_compare_op1),
7433                                     sh_compare_op1);
7434
7435       emit_insn (gen_cmpgtudi_media (operands[0],
7436                                      sh_compare_op0, sh_compare_op1));
7437       DONE;
7438     }
7439   operands[1] = prepare_scc_operands (GTU);
7440 }")
7441
7442 (define_expand "sltu"
7443   [(set (match_operand:SI 0 "arith_reg_operand" "")
7444         (match_dup 1))]
7445   ""
7446   "
7447 {
7448   if (TARGET_SHMEDIA)
7449     {
7450       if (GET_MODE (operands[0]) != DImode)
7451         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7452       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7453       if (sh_compare_op1 != const0_rtx)
7454         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7455                                     ? GET_MODE (sh_compare_op0)
7456                                     : GET_MODE (sh_compare_op1),
7457                                     sh_compare_op1);
7458
7459       emit_insn (gen_cmpgtudi_media (operands[0],
7460                                      sh_compare_op1, sh_compare_op0));
7461       DONE;
7462     }
7463   operands[1] = prepare_scc_operands (LTU);
7464 }")
7465
7466 (define_expand "sleu"
7467   [(set (match_operand:SI 0 "arith_reg_operand" "")
7468         (match_dup 1))]
7469   ""
7470   "
7471 {
7472   if (TARGET_SHMEDIA)
7473     {
7474       rtx tmp;
7475
7476       if (GET_MODE (operands[0]) != DImode)
7477         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7478       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7479       if (sh_compare_op1 != const0_rtx)
7480         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7481                                     ? GET_MODE (sh_compare_op0)
7482                                     : GET_MODE (sh_compare_op1),
7483                                     sh_compare_op1);
7484
7485       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7486
7487       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7488       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7489
7490       DONE;
7491     }
7492   operands[1] = prepare_scc_operands (LEU);
7493 }")
7494
7495 (define_expand "sgeu"
7496   [(set (match_operand:SI 0 "arith_reg_operand" "")
7497         (match_dup 1))]
7498   ""
7499   "
7500 {
7501   if (TARGET_SHMEDIA)
7502     {
7503       rtx tmp;
7504
7505       if (GET_MODE (operands[0]) != DImode)
7506         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7507       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7508       if (sh_compare_op1 != const0_rtx)
7509         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7510                                     ? GET_MODE (sh_compare_op0)
7511                                     : GET_MODE (sh_compare_op1),
7512                                     sh_compare_op1);
7513
7514       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7515
7516       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7517       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7518
7519       DONE;
7520     }
7521
7522   operands[1] = prepare_scc_operands (GEU);
7523 }")
7524
7525 ;; sne moves the complement of the T reg to DEST like this:
7526 ;;      cmp/eq ...
7527 ;;      mov    #-1,temp
7528 ;;      negc   temp,dest
7529 ;;   This is better than xoring compare result with 1 because it does
7530 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
7531 ;;   loop.
7532
7533 (define_expand "sne"
7534   [(set (match_dup 2) (const_int -1))
7535    (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7536                    (neg:SI (plus:SI (match_dup 1)
7537                                     (match_dup 2))))
7538               (set (reg:SI T_REG)
7539                    (ne:SI (ior:SI (match_dup 1) (match_dup 2))
7540                           (const_int 0)))])]
7541   ""
7542   "
7543 {
7544   if (TARGET_SHMEDIA)
7545     {
7546       rtx tmp;
7547
7548       if (GET_MODE (operands[0]) != DImode)
7549         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7550
7551       if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7552         FAIL;
7553
7554       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7555       if (sh_compare_op1 != const0_rtx)
7556         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7557                                     ? GET_MODE (sh_compare_op0)
7558                                     : GET_MODE (sh_compare_op1),
7559                                     sh_compare_op1);
7560
7561       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7562
7563       emit_insn (gen_seq (tmp));
7564       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7565
7566       DONE;
7567     }
7568
7569    operands[1] = prepare_scc_operands (EQ);
7570    operands[2] = gen_reg_rtx (SImode);
7571 }")
7572
7573 (define_expand "sunordered"
7574   [(set (match_operand:DI 0 "arith_reg_operand" "")
7575         (unordered:DI (match_dup 1) (match_dup 2)))]
7576   "TARGET_SHMEDIA_FPU"
7577   "
7578 {
7579   operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7580   operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7581 }")
7582
7583 ;; Use the same trick for FP sle / sge
7584 (define_expand "movnegt"
7585   [(set (match_dup 2) (const_int -1))
7586    (parallel [(set (match_operand 0 "" "")
7587                    (neg:SI (plus:SI (match_dup 1)
7588                                     (match_dup 2))))
7589               (set (reg:SI T_REG)
7590                    (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
7591                           (const_int 0)))])]
7592   "TARGET_SH1"
7593   "operands[2] = gen_reg_rtx (SImode);")
7594
7595 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
7596 ;; This prevents a regression that occurred when we switched from xor to
7597 ;; mov/neg for sne.
7598
7599 (define_split
7600   [(set (match_operand:SI 0 "arith_reg_operand" "")
7601         (plus:SI (reg:SI T_REG)
7602                  (const_int -1)))]
7603   "TARGET_SH1"
7604   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
7605    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7606   "")
7607
7608 ;; -------------------------------------------------------------------------
7609 ;; Instructions to cope with inline literal tables
7610 ;; -------------------------------------------------------------------------
7611
7612 ; 2 byte integer in line
7613
7614 (define_insn "consttable_2"
7615  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7616                     (match_operand 1 "" "")]
7617                    UNSPECV_CONST2)]
7618  ""
7619  "*
7620 {
7621   if (operands[1] != const0_rtx)
7622     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
7623   return \"\";
7624 }"
7625  [(set_attr "length" "2")
7626  (set_attr "in_delay_slot" "no")])
7627
7628 ; 4 byte integer in line
7629
7630 (define_insn "consttable_4"
7631  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7632                     (match_operand 1 "" "")]
7633                    UNSPECV_CONST4)]
7634  ""
7635  "*
7636 {
7637   if (operands[1] != const0_rtx)
7638     assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
7639   return \"\";
7640 }"
7641  [(set_attr "length" "4")
7642   (set_attr "in_delay_slot" "no")])
7643
7644 ; 8 byte integer in line
7645
7646 (define_insn "consttable_8"
7647  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7648                     (match_operand 1 "" "")]
7649                    UNSPECV_CONST8)]
7650  ""
7651  "*
7652 {
7653   if (operands[1] != const0_rtx)
7654     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
7655   return \"\";
7656 }"
7657  [(set_attr "length" "8")
7658   (set_attr "in_delay_slot" "no")])
7659
7660 ; 4 byte floating point
7661
7662 (define_insn "consttable_sf"
7663  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7664                     (match_operand 1 "" "")]
7665                    UNSPECV_CONST4)]
7666  ""
7667  "*
7668 {
7669   if (operands[1] != const0_rtx)
7670     {
7671       REAL_VALUE_TYPE d;
7672       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7673       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
7674     }
7675   return \"\";
7676 }"
7677  [(set_attr "length" "4")
7678   (set_attr "in_delay_slot" "no")])
7679
7680 ; 8 byte floating point
7681
7682 (define_insn "consttable_df"
7683  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
7684                     (match_operand 1 "" "")]
7685                    UNSPECV_CONST8)]
7686  ""
7687  "*
7688 {
7689   if (operands[1] != const0_rtx)
7690     {
7691       REAL_VALUE_TYPE d;
7692       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7693       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
7694     }
7695   return \"\";
7696 }"
7697  [(set_attr "length" "8")
7698   (set_attr "in_delay_slot" "no")])
7699
7700 ;; Alignment is needed for some constant tables; it may also be added for
7701 ;; Instructions at the start of loops, or after unconditional branches.
7702 ;; ??? We would get more accurate lengths if we did instruction
7703 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
7704 ;; here is too conservative.
7705
7706 ; align to a two byte boundary
7707
7708 (define_expand "align_2"
7709  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
7710  ""
7711  "")
7712
7713 ; align to a four byte boundary
7714 ;; align_4 and align_log are instructions for the starts of loops, or
7715 ;; after unconditional branches, which may take up extra room.
7716
7717 (define_expand "align_4"
7718  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
7719  ""
7720  "")
7721
7722 ; align to a cache line boundary
7723
7724 (define_insn "align_log"
7725  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
7726  ""
7727  ""
7728  [(set_attr "length" "0")
7729   (set_attr "in_delay_slot" "no")])
7730
7731 ; emitted at the end of the literal table, used to emit the
7732 ; 32bit branch labels if needed.
7733
7734 (define_insn "consttable_end"
7735   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
7736   ""
7737   "* return output_jump_label_table ();"
7738   [(set_attr "in_delay_slot" "no")])
7739
7740 ; emitted at the end of the window in the literal table.
7741
7742 (define_insn "consttable_window_end"
7743   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
7744   ""
7745   ""
7746   [(set_attr "length" "0")
7747    (set_attr "in_delay_slot" "no")])
7748
7749 ;; -------------------------------------------------------------------------
7750 ;; Misc
7751 ;; -------------------------------------------------------------------------
7752
7753 ;; String/block move insn.
7754
7755 (define_expand "movstrsi"
7756   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
7757                    (mem:BLK (match_operand:BLK 1 "" "")))
7758               (use (match_operand:SI 2 "nonmemory_operand" ""))
7759               (use (match_operand:SI 3 "immediate_operand" ""))
7760               (clobber (reg:SI PR_REG))
7761               (clobber (reg:SI R4_REG))
7762               (clobber (reg:SI R5_REG))
7763               (clobber (reg:SI R0_REG))])]
7764   "TARGET_SH1 && ! TARGET_SH5"
7765   "
7766 {
7767   if(expand_block_move (operands))
7768      DONE;
7769   else FAIL;
7770 }")
7771
7772 (define_insn "block_move_real"
7773   [(parallel [(set (mem:BLK (reg:SI R4_REG))
7774                    (mem:BLK (reg:SI R5_REG)))
7775               (use (match_operand:SI 0 "arith_reg_operand" "r"))
7776               (clobber (reg:SI PR_REG))
7777               (clobber (reg:SI R0_REG))])]
7778   "TARGET_SH1 && ! TARGET_HARD_SH4"
7779   "jsr  @%0%#"
7780   [(set_attr "type" "sfunc")
7781    (set_attr "needs_delay_slot" "yes")])
7782
7783 (define_insn "block_lump_real"
7784   [(parallel [(set (mem:BLK (reg:SI R4_REG))
7785                    (mem:BLK (reg:SI R5_REG)))
7786               (use (match_operand:SI 0 "arith_reg_operand" "r"))
7787               (use (reg:SI R6_REG))
7788               (clobber (reg:SI PR_REG))
7789               (clobber (reg:SI T_REG))
7790               (clobber (reg:SI R4_REG))
7791               (clobber (reg:SI R5_REG))
7792               (clobber (reg:SI R6_REG))
7793               (clobber (reg:SI R0_REG))])]
7794   "TARGET_SH1 && ! TARGET_HARD_SH4"
7795   "jsr  @%0%#"
7796   [(set_attr "type" "sfunc")
7797    (set_attr "needs_delay_slot" "yes")])
7798
7799 (define_insn "block_move_real_i4"
7800   [(parallel [(set (mem:BLK (reg:SI R4_REG))
7801                    (mem:BLK (reg:SI R5_REG)))
7802               (use (match_operand:SI 0 "arith_reg_operand" "r"))
7803               (clobber (reg:SI PR_REG))
7804               (clobber (reg:SI R0_REG))
7805               (clobber (reg:SI R1_REG))
7806               (clobber (reg:SI R2_REG))])]
7807   "TARGET_HARD_SH4"
7808   "jsr  @%0%#"
7809   [(set_attr "type" "sfunc")
7810    (set_attr "needs_delay_slot" "yes")])
7811
7812 (define_insn "block_lump_real_i4"
7813   [(parallel [(set (mem:BLK (reg:SI R4_REG))
7814                    (mem:BLK (reg:SI R5_REG)))
7815               (use (match_operand:SI 0 "arith_reg_operand" "r"))
7816               (use (reg:SI R6_REG))
7817               (clobber (reg:SI PR_REG))
7818               (clobber (reg:SI T_REG))
7819               (clobber (reg:SI R4_REG))
7820               (clobber (reg:SI R5_REG))
7821               (clobber (reg:SI R6_REG))
7822               (clobber (reg:SI R0_REG))
7823               (clobber (reg:SI R1_REG))
7824               (clobber (reg:SI R2_REG))
7825               (clobber (reg:SI R3_REG))])]
7826   "TARGET_HARD_SH4"
7827   "jsr  @%0%#"
7828   [(set_attr "type" "sfunc")
7829    (set_attr "needs_delay_slot" "yes")])
7830 \f
7831 ;; -------------------------------------------------------------------------
7832 ;; Floating point instructions.
7833 ;; -------------------------------------------------------------------------
7834
7835 ;; ??? All patterns should have a type attribute.
7836
7837 (define_expand "fpu_switch0"
7838   [(set (match_operand:SI 0 "" "") (match_dup 2))
7839    (set (match_dup 1) (mem:PSI (match_dup 0)))]
7840   "TARGET_SH4"
7841   "
7842 {
7843   operands[1] = get_fpscr_rtx ();
7844   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
7845   if (flag_pic)
7846     operands[2] = legitimize_pic_address (operands[2], SImode,
7847                                           no_new_pseudos ? operands[0] : 0);
7848 }")
7849
7850 (define_expand "fpu_switch1"
7851   [(set (match_operand:SI 0 "" "") (match_dup 2))
7852    (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
7853    (set (match_dup 1) (mem:PSI (match_dup 3)))]
7854   "TARGET_SH4"
7855   "
7856 {
7857   operands[1] = get_fpscr_rtx ();
7858   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
7859   if (flag_pic)
7860     operands[2] = legitimize_pic_address (operands[2], SImode,
7861                                           no_new_pseudos ? operands[0] : 0);
7862   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
7863 }")
7864
7865 (define_expand "movpsi"
7866   [(set (match_operand:PSI 0 "register_operand" "")
7867         (match_operand:PSI 1 "general_movsrc_operand" ""))]
7868   "TARGET_SH4"
7869   "")
7870
7871 ;; The c / m alternative is a fake to guide reload to load directly into
7872 ;; fpscr, since reload doesn't know how to use post-increment.
7873 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
7874 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
7875 ;; predicate after reload.
7876 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
7877 ;; like a mac -> gpr move.
7878 (define_insn "fpu_switch"
7879   [(set (match_operand:PSI 0 "register_operand" "=c,c,r,c,c,r,m,r")
7880         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c"))]
7881   "TARGET_SH4
7882    && (! reload_completed
7883        || true_regnum (operands[0]) != FPSCR_REG
7884        || GET_CODE (operands[1]) != MEM
7885        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
7886   "@
7887         ! precision stays the same
7888         lds.l   %1,fpscr
7889         mov.l   %1,%0
7890         #
7891         lds     %1,fpscr
7892         mov     %1,%0
7893         mov.l   %1,%0
7894         sts     fpscr,%0"
7895   [(set_attr "length" "0,2,2,4,2,2,2,2")
7896    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp")])
7897
7898 (define_split
7899   [(set (reg:PSI FPSCR_REG)
7900         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
7901   "TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
7902   [(set (match_dup 0) (match_dup 0))]
7903   "
7904 {
7905   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
7906                                         gen_rtx (MEM, PSImode,
7907                                                  gen_rtx (POST_INC, Pmode,
7908                                                           operands[0]))));
7909   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
7910 }")
7911
7912 (define_split
7913   [(set (reg:PSI FPSCR_REG)
7914         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
7915   "TARGET_SH4"
7916   [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
7917   "
7918 {
7919   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
7920                                         gen_rtx (MEM, PSImode,
7921                                                  gen_rtx (POST_INC, Pmode,
7922                                                           operands[0]))));
7923   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
7924 }")
7925
7926 ;; ??? This uses the fp unit, but has no type indicating that.
7927 ;; If we did that, this would either give a bogus latency or introduce
7928 ;; a bogus FIFO constraint.
7929 ;; Since this insn is currently only used for prologues/epilogues,
7930 ;; it is probably best to claim no function unit, which matches the
7931 ;; current setting.
7932 (define_insn "toggle_sz"
7933   [(set (reg:PSI FPSCR_REG)
7934         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
7935   "TARGET_SH4"
7936   "fschg")
7937
7938 (define_expand "addsf3"
7939   [(set (match_operand:SF 0 "arith_reg_operand" "")
7940         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
7941                  (match_operand:SF 2 "arith_reg_operand" "")))]
7942   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7943   "
7944 {
7945   if (TARGET_SH3E)
7946     {
7947       expand_sf_binop (&gen_addsf3_i, operands);
7948       DONE;
7949     }
7950 }")
7951
7952 (define_insn "*addsf3_media"
7953   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7954         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
7955                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7956   "TARGET_SHMEDIA_FPU"
7957   "fadd.s       %1, %2, %0"
7958   [(set_attr "type" "fparith_media")])
7959
7960 (define_insn_and_split "unary_sf_op"
7961   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
7962         (vec_select:V2SF
7963          (vec_concat:V2SF
7964           (vec_select:SF
7965            (match_dup 0)
7966            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
7967           (match_operator:SF 2 "unary_float_operator"
7968             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
7969                             (parallel [(match_operand 4
7970                                         "const_int_operand" "n")]))]))
7971          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
7972   "TARGET_SHMEDIA_FPU"
7973   "#"
7974   "TARGET_SHMEDIA_FPU && reload_completed"
7975   [(set (match_dup 5) (match_dup 6))]
7976   "
7977 {
7978   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
7979   rtx op1 = gen_rtx_REG (SFmode,
7980                          (true_regnum (operands[1])
7981                           + (INTVAL (operands[4]) ^ endian)));
7982
7983   operands[7] = gen_rtx_REG (SFmode,
7984                              (true_regnum (operands[0])
7985                               + (INTVAL (operands[3]) ^ endian)));
7986   operands[6] = gen_rtx (GET_CODE (operands[2]), SFmode, op1);
7987 }"
7988   [(set_attr "type" "fparith_media")])
7989
7990 (define_insn_and_split "binary_sf_op"
7991   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
7992         (vec_select:V2SF
7993          (vec_concat:V2SF
7994           (vec_select:SF
7995            (match_dup 0)
7996            (parallel [(not:BI (match_operand 4 "const_int_operand" "n"))]))
7997           (match_operator:SF 3 "binary_float_operator"
7998             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
7999                             (parallel [(match_operand 5
8000                                         "const_int_operand" "n")]))
8001              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
8002                             (parallel [(match_operand 6
8003                                         "const_int_operand" "n")]))]))
8004          (parallel [(not:BI (match_dup 4)) (match_dup 4)])))]
8005   "TARGET_SHMEDIA_FPU"
8006   "#"
8007   "TARGET_SHMEDIA_FPU && reload_completed"
8008   [(set (match_dup 7) (match_dup 8))]
8009   "
8010 {
8011   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8012   rtx op1 = gen_rtx_REG (SFmode,
8013                          (true_regnum (operands[1])
8014                           + (INTVAL (operands[5]) ^ endian)));
8015   rtx op2 = gen_rtx_REG (SFmode,
8016                          (true_regnum (operands[2])
8017                           + (INTVAL (operands[6]) ^ endian)));
8018
8019   operands[7] = gen_rtx_REG (SFmode,
8020                              (true_regnum (operands[0])
8021                               + (INTVAL (operands[4]) ^ endian)));
8022   operands[8] = gen_rtx (GET_CODE (operands[3]), SFmode, op1, op2);
8023 }"
8024   [(set_attr "type" "fparith_media")])
8025
8026 (define_insn "addsf3_i"
8027   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8028         (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
8029                  (match_operand:SF 2 "arith_reg_operand" "f")))
8030    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8031   "TARGET_SH3E"
8032   "fadd %2,%0"
8033   [(set_attr "type" "fp")
8034    (set_attr "fp_mode" "single")])
8035
8036 (define_expand "subsf3"
8037   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8038         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8039                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8040   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8041   "
8042 {
8043   if (TARGET_SH3E)
8044     {
8045       expand_sf_binop (&gen_subsf3_i, operands);
8046       DONE;
8047     }
8048 }")
8049
8050 (define_insn "*subsf3_media"
8051   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8052         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8053                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8054   "TARGET_SHMEDIA_FPU"
8055   "fsub.s       %1, %2, %0"
8056   [(set_attr "type" "fparith_media")])
8057
8058 (define_insn "subsf3_i"
8059   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8060         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8061                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8062    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8063   "TARGET_SH3E"
8064   "fsub %2,%0"
8065   [(set_attr "type" "fp")
8066    (set_attr "fp_mode" "single")])
8067
8068 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8069 ;; register in feeding fp instructions.  Thus, we cannot generate fmac for
8070 ;; mixed-precision SH4 targets.  To allow it to be still generated for the
8071 ;; SH3E, we use a separate insn for SH3E mulsf3.
8072
8073 (define_expand "mulsf3"
8074   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8075         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8076                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8077   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8078   "
8079 {
8080   if (TARGET_SH4)
8081     expand_sf_binop (&gen_mulsf3_i4, operands);
8082   else if (TARGET_SH3E)
8083     emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
8084   if (! TARGET_SHMEDIA)
8085     DONE;
8086 }")
8087
8088 (define_insn "*mulsf3_media"
8089   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8090         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8091                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8092   "TARGET_SHMEDIA_FPU"
8093   "fmul.s       %1, %2, %0"
8094   [(set_attr "type" "fparith_media")])
8095
8096 (define_insn "mulsf3_i4"
8097   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8098         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8099                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8100    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8101   "TARGET_SH3E"
8102   "fmul %2,%0"
8103   [(set_attr "type" "fp")
8104    (set_attr "fp_mode" "single")])
8105
8106 (define_insn "mulsf3_ie"
8107   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8108         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8109                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8110   "TARGET_SH3E && ! TARGET_SH4"
8111   "fmul %2,%0"
8112   [(set_attr "type" "fp")])
8113
8114 (define_insn "*mac_media"
8115   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8116         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8117                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8118                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8119   "TARGET_SHMEDIA_FPU"
8120   "fmac.s %1, %2, %0"
8121   [(set_attr "type" "fparith_media")])
8122
8123 (define_insn "*macsf3"
8124   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8125         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8126                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8127                  (match_operand:SF 3 "arith_reg_operand" "0")))
8128    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
8129   "TARGET_SH3E && ! TARGET_SH4"
8130   "fmac fr0,%2,%0"
8131   [(set_attr "type" "fp")
8132    (set_attr "fp_mode" "single")])
8133
8134 (define_expand "divsf3"
8135   [(set (match_operand:SF 0 "arith_reg_operand" "")
8136         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8137                 (match_operand:SF 2 "arith_reg_operand" "")))]
8138   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8139   "
8140 {
8141   if (TARGET_SH3E)
8142     {
8143       expand_sf_binop (&gen_divsf3_i, operands);
8144       DONE;
8145     }
8146 }")
8147
8148 (define_insn "*divsf3_media"
8149   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8150         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8151                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8152   "TARGET_SHMEDIA_FPU"
8153   "fdiv.s       %1, %2, %0"
8154   [(set_attr "type" "fdiv_media")])
8155
8156 (define_insn "divsf3_i"
8157   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8158         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
8159                  (match_operand:SF 2 "arith_reg_operand" "f")))
8160    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8161   "TARGET_SH3E"
8162   "fdiv %2,%0"
8163   [(set_attr "type" "fdiv")
8164    (set_attr "fp_mode" "single")])
8165
8166 (define_insn "floatdisf2"
8167   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8168         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8169   "TARGET_SHMEDIA_FPU"
8170   "float.qs %1, %0"
8171   [(set_attr "type" "fpconv_media")])
8172
8173 (define_expand "floatsisf2"
8174   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8175         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
8176   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8177   "
8178 {
8179   if (TARGET_SH4)
8180     {
8181       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8182       DONE;
8183     }
8184 }")
8185
8186 (define_insn "*floatsisf2_media"
8187   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8188         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8189   "TARGET_SHMEDIA_FPU"
8190   "float.ls     %1, %0"
8191   [(set_attr "type" "fpconv_media")])
8192
8193 (define_insn "floatsisf2_i4"
8194   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8195         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
8196    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8197   "TARGET_SH4"
8198   "float        %1,%0"
8199   [(set_attr "type" "fp")
8200    (set_attr "fp_mode" "single")])
8201
8202 (define_insn "*floatsisf2_ie"
8203   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8204         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
8205   "TARGET_SH3E && ! TARGET_SH4"
8206   "float        %1,%0"
8207   [(set_attr "type" "fp")])
8208
8209 (define_insn "fix_truncsfdi2"
8210   [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8211         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8212   "TARGET_SHMEDIA_FPU"
8213   "ftrc.sq %1, %0"
8214   [(set_attr "type" "fpconv_media")])
8215
8216 (define_expand "fix_truncsfsi2"
8217   [(set (match_operand:SI 0 "fpul_operand" "=y")
8218         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8219   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8220   "
8221 {
8222   if (TARGET_SH4)
8223     {
8224       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8225       DONE;
8226     }
8227 }")
8228
8229 (define_insn "*fix_truncsfsi2_media"
8230   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8231         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8232   "TARGET_SHMEDIA_FPU"
8233   "ftrc.sl      %1, %0"
8234   [(set_attr "type" "fpconv_media")])
8235
8236 (define_insn "fix_truncsfsi2_i4"
8237   [(set (match_operand:SI 0 "fpul_operand" "=y")
8238         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8239    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8240   "TARGET_SH4"
8241   "ftrc %1,%0"
8242   [(set_attr "type" "ftrc_s")
8243    (set_attr "fp_mode" "single")])
8244
8245 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
8246 ;; fix_truncsfsi2_i4.
8247 ;; (define_insn "fix_truncsfsi2_i4_2"
8248 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8249 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8250 ;;   (use (reg:PSI FPSCR_REG))
8251 ;;   (clobber (reg:SI FPUL_REG))]
8252 ;;  "TARGET_SH4"
8253 ;;  "#"
8254 ;;  [(set_attr "length" "4")
8255 ;;   (set_attr "fp_mode" "single")])
8256
8257 ;;(define_split
8258 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8259 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8260 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
8261 ;;   (clobber (reg:SI FPUL_REG))]
8262 ;;  "TARGET_SH4"
8263 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8264 ;;            (use (match_dup 2))])
8265 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
8266
8267 (define_insn "*fixsfsi"
8268   [(set (match_operand:SI 0 "fpul_operand" "=y")
8269         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8270   "TARGET_SH3E && ! TARGET_SH4"
8271   "ftrc %1,%0"
8272   [(set_attr "type" "fp")])
8273
8274 (define_insn "cmpgtsf_t"
8275   [(set (reg:SI T_REG)
8276         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8277                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8278   "TARGET_SH3E && ! TARGET_SH4"
8279   "fcmp/gt      %1,%0"
8280   [(set_attr "type" "fp")
8281    (set_attr "fp_mode" "single")])
8282
8283 (define_insn "cmpeqsf_t"
8284   [(set (reg:SI T_REG)
8285         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8286                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8287   "TARGET_SH3E && ! TARGET_SH4"
8288   "fcmp/eq      %1,%0"
8289   [(set_attr "type" "fp")
8290    (set_attr "fp_mode" "single")])
8291
8292 (define_insn "ieee_ccmpeqsf_t"
8293   [(set (reg:SI T_REG)
8294         (ior:SI (reg:SI T_REG)
8295                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8296                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
8297   "TARGET_SH3E && TARGET_IEEE && ! TARGET_SH4"
8298   "* return output_ieee_ccmpeq (insn, operands);"
8299   [(set_attr "length" "4")])
8300
8301
8302 (define_insn "cmpgtsf_t_i4"
8303   [(set (reg:SI T_REG)
8304         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8305                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8306    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8307   "TARGET_SH4"
8308   "fcmp/gt      %1,%0"
8309   [(set_attr "type" "fp")
8310    (set_attr "fp_mode" "single")])
8311
8312 (define_insn "cmpeqsf_t_i4"
8313   [(set (reg:SI T_REG)
8314         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8315                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8316    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8317   "TARGET_SH4"
8318   "fcmp/eq      %1,%0"
8319   [(set_attr "type" "fp")
8320    (set_attr "fp_mode" "single")])
8321
8322 (define_insn "*ieee_ccmpeqsf_t_4"
8323   [(set (reg:SI T_REG)
8324         (ior:SI (reg:SI T_REG)
8325                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8326                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
8327    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8328   "TARGET_IEEE && TARGET_SH4"
8329   "* return output_ieee_ccmpeq (insn, operands);"
8330   [(set_attr "length" "4")
8331    (set_attr "fp_mode" "single")])
8332
8333 (define_insn "cmpeqsf_media"
8334   [(set (match_operand:DI 0 "register_operand" "=r")
8335         (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8336                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8337   "TARGET_SHMEDIA_FPU"
8338   "fcmpeq.s     %1, %2, %0"
8339   [(set_attr "type" "fcmp_media")])
8340
8341 (define_insn "cmpgtsf_media"
8342   [(set (match_operand:DI 0 "register_operand" "=r")
8343         (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8344                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8345   "TARGET_SHMEDIA_FPU"
8346   "fcmpgt.s     %1, %2, %0"
8347   [(set_attr "type" "fcmp_media")])
8348
8349 (define_insn "cmpgesf_media"
8350   [(set (match_operand:DI 0 "register_operand" "=r")
8351         (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8352                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8353   "TARGET_SHMEDIA_FPU"
8354   "fcmpge.s     %1, %2, %0"
8355   [(set_attr "type" "fcmp_media")])
8356
8357 (define_insn "cmpunsf_media"
8358   [(set (match_operand:DI 0 "register_operand" "=r")
8359         (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8360                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8361   "TARGET_SHMEDIA_FPU"
8362   "fcmpun.s     %1, %2, %0"
8363   [(set_attr "type" "fcmp_media")])
8364
8365 (define_expand "cmpsf"
8366   [(set (reg:SI T_REG)
8367         (compare (match_operand:SF 0 "arith_operand" "")
8368                  (match_operand:SF 1 "arith_operand" "")))]
8369   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8370   "
8371 {
8372   sh_compare_op0 = operands[0];
8373   sh_compare_op1 = operands[1];
8374   DONE;
8375 }")
8376
8377 (define_expand "negsf2"
8378   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8379         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8380   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8381   "
8382 {
8383   if (TARGET_SH3E)
8384     {
8385       expand_sf_unop (&gen_negsf2_i, operands);
8386       DONE;
8387     }
8388 }")
8389
8390 (define_insn "*negsf2_media"
8391   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8392         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8393   "TARGET_SHMEDIA_FPU"
8394   "fneg.s       %1, %0"
8395   [(set_attr "type" "fmove_media")])
8396
8397 (define_insn "negsf2_i"
8398   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8399         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8400    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8401   "TARGET_SH3E"
8402   "fneg %0"
8403   [(set_attr "type" "fmove")
8404    (set_attr "fp_mode" "single")])
8405
8406 (define_expand "sqrtsf2"
8407   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8408         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8409   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8410   "
8411 {
8412   if (TARGET_SH3E)
8413     {
8414       expand_sf_unop (&gen_sqrtsf2_i, operands);
8415       DONE;
8416     }
8417 }")
8418
8419 (define_insn "*sqrtsf2_media"
8420   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8421         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8422   "TARGET_SHMEDIA_FPU"
8423   "fsqrt.s      %1, %0"
8424   [(set_attr "type" "fdiv_media")])
8425
8426 (define_insn "sqrtsf2_i"
8427   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8428         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8429    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8430   "TARGET_SH3E"
8431   "fsqrt        %0"
8432   [(set_attr "type" "fdiv")
8433    (set_attr "fp_mode" "single")])
8434
8435 (define_expand "abssf2"
8436   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8437         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8438   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8439   "
8440 {
8441   if (TARGET_SH3E)
8442     {
8443       expand_sf_unop (&gen_abssf2_i, operands);
8444       DONE;
8445     }
8446 }")
8447
8448 (define_insn "*abssf2_media"
8449   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8450         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8451   "TARGET_SHMEDIA_FPU"
8452   "fabs.s       %1, %0"
8453   [(set_attr "type" "fmove_media")])
8454
8455 (define_insn "abssf2_i"
8456   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8457         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8458    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8459   "TARGET_SH3E"
8460   "fabs %0"
8461   [(set_attr "type" "fmove")
8462    (set_attr "fp_mode" "single")])
8463
8464 (define_expand "adddf3"
8465   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8466         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8467                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8468   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8469   "
8470 {
8471   if (TARGET_SH4)
8472     {
8473       expand_df_binop (&gen_adddf3_i, operands);
8474       DONE;
8475     }
8476 }")
8477
8478 (define_insn "*adddf3_media"
8479   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8480         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8481                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8482   "TARGET_SHMEDIA_FPU"
8483   "fadd.d       %1, %2, %0"
8484   [(set_attr "type" "dfparith_media")])
8485
8486 (define_insn "adddf3_i"
8487   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8488         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8489                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8490    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8491   "TARGET_SH4"
8492   "fadd %2,%0"
8493   [(set_attr "type" "dfp_arith")
8494    (set_attr "fp_mode" "double")])
8495
8496 (define_expand "subdf3"
8497   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8498         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8499                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8500   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8501   "
8502 {
8503   if (TARGET_SH4)
8504     {
8505       expand_df_binop (&gen_subdf3_i, operands);
8506       DONE;
8507     }
8508 }")
8509
8510 (define_insn "*subdf3_media"
8511   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8512         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8513                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8514   "TARGET_SHMEDIA_FPU"
8515   "fsub.d       %1, %2, %0"
8516   [(set_attr "type" "dfparith_media")])
8517
8518 (define_insn "subdf3_i"
8519   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8520         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8521                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8522    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8523   "TARGET_SH4"
8524   "fsub %2,%0"
8525   [(set_attr "type" "dfp_arith")
8526    (set_attr "fp_mode" "double")])
8527
8528 (define_expand "muldf3"
8529   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8530         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8531                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8532   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8533   "
8534 {
8535   if (TARGET_SH4)
8536     {
8537       expand_df_binop (&gen_muldf3_i, operands);
8538       DONE;
8539     }
8540 }")
8541
8542 (define_insn "*muldf3_media"
8543   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8544         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8545                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8546   "TARGET_SHMEDIA_FPU"
8547   "fmul.d       %1, %2, %0"
8548   [(set_attr "type" "dfmul_media")])
8549
8550 (define_insn "muldf3_i"
8551   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8552         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8553                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8554    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8555   "TARGET_SH4"
8556   "fmul %2,%0"
8557   [(set_attr "type" "dfp_arith")
8558    (set_attr "fp_mode" "double")])
8559
8560 (define_expand "divdf3"
8561   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8562         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8563                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8564   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8565   "
8566 {
8567   if (TARGET_SH4)
8568     {
8569       expand_df_binop (&gen_divdf3_i, operands);
8570       DONE;
8571     }
8572 }")
8573
8574 (define_insn "*divdf3_media"
8575   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8576         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8577                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8578   "TARGET_SHMEDIA_FPU"
8579   "fdiv.d       %1, %2, %0"
8580   [(set_attr "type" "dfdiv_media")])
8581
8582 (define_insn "divdf3_i"
8583   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8584         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8585                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8586    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8587   "TARGET_SH4"
8588   "fdiv %2,%0"
8589   [(set_attr "type" "dfdiv")
8590    (set_attr "fp_mode" "double")])
8591
8592 (define_insn "floatdidf2"
8593   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8594         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8595   "TARGET_SHMEDIA_FPU"
8596   "float.qd     %1, %0"
8597   [(set_attr "type" "dfpconv_media")])
8598
8599 (define_expand "floatsidf2"
8600   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8601         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
8602   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8603   "
8604 {
8605   if (TARGET_SH4)
8606     {
8607       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
8608                                       get_fpscr_rtx ()));
8609       DONE;
8610     }
8611 }")
8612
8613 (define_insn "*floatsidf2_media"
8614   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8615         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8616   "TARGET_SHMEDIA_FPU"
8617   "float.ld     %1, %0"
8618   [(set_attr "type" "dfpconv_media")])
8619
8620 (define_insn "floatsidf2_i"
8621   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8622         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
8623    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8624   "TARGET_SH4"
8625   "float        %1,%0"
8626   [(set_attr "type" "dfp_conv")
8627    (set_attr "fp_mode" "double")])
8628
8629 (define_insn "fix_truncdfdi2"
8630   [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8631         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8632   "TARGET_SHMEDIA_FPU"
8633   "ftrc.dq      %1, %0"
8634   [(set_attr "type" "dfpconv_media")])
8635
8636 (define_expand "fix_truncdfsi2"
8637   [(set (match_operand:SI 0 "fpul_operand" "")
8638         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8639   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8640   "
8641 {
8642   if (TARGET_SH4)
8643     {
8644       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
8645                                           get_fpscr_rtx ()));
8646       DONE;
8647     }
8648 }")
8649
8650 (define_insn "*fix_truncdfsi2_media"
8651   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8652         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8653   "TARGET_SHMEDIA_FPU"
8654   "ftrc.dl      %1, %0"
8655   [(set_attr "type" "dfpconv_media")])
8656
8657 (define_insn "fix_truncdfsi2_i"
8658   [(set (match_operand:SI 0 "fpul_operand" "=y")
8659         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8660    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8661   "TARGET_SH4"
8662   "ftrc %1,%0"
8663   [(set_attr "type" "dfp_conv")
8664    (set_attr "dfp_comp" "no")
8665    (set_attr "fp_mode" "double")])
8666
8667 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
8668 ;; fix_truncdfsi2_i.
8669 ;; (define_insn "fix_truncdfsi2_i4"
8670 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8671 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8672 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
8673 ;;    (clobber (reg:SI FPUL_REG))]
8674 ;;   "TARGET_SH4"
8675 ;;   "#"
8676 ;;   [(set_attr "length" "4")
8677 ;;    (set_attr "fp_mode" "double")])
8678 ;;
8679 ;; (define_split
8680 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8681 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8682 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
8683 ;;    (clobber (reg:SI FPUL_REG))]
8684 ;;   "TARGET_SH4"
8685 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8686 ;;            (use (match_dup 2))])
8687 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
8688
8689 (define_insn "cmpgtdf_t"
8690   [(set (reg:SI T_REG)
8691         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
8692                (match_operand:DF 1 "arith_reg_operand" "f")))
8693    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8694   "TARGET_SH4"
8695   "fcmp/gt      %1,%0"
8696   [(set_attr "type" "dfp_cmp")
8697    (set_attr "fp_mode" "double")])
8698
8699 (define_insn "cmpeqdf_t"
8700   [(set (reg:SI T_REG)
8701         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8702                (match_operand:DF 1 "arith_reg_operand" "f")))
8703    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8704   "TARGET_SH4"
8705   "fcmp/eq      %1,%0"
8706   [(set_attr "type" "dfp_cmp")
8707    (set_attr "fp_mode" "double")])
8708
8709 (define_insn "*ieee_ccmpeqdf_t"
8710   [(set (reg:SI T_REG)
8711         (ior:SI (reg:SI T_REG)
8712                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8713                        (match_operand:DF 1 "arith_reg_operand" "f"))))
8714    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8715   "TARGET_IEEE && TARGET_SH4"
8716   "* return output_ieee_ccmpeq (insn, operands);"
8717   [(set_attr "length" "4")
8718    (set_attr "fp_mode" "double")])
8719
8720 (define_insn "cmpeqdf_media"
8721   [(set (match_operand:DI 0 "register_operand" "=r")
8722         (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8723                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8724   "TARGET_SHMEDIA_FPU"
8725   "fcmpeq.d     %1,%2,%0"
8726   [(set_attr "type" "fcmp_media")])
8727
8728 (define_insn "cmpgtdf_media"
8729   [(set (match_operand:DI 0 "register_operand" "=r")
8730         (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8731                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8732   "TARGET_SHMEDIA_FPU"
8733   "fcmpgt.d     %1,%2,%0"
8734   [(set_attr "type" "fcmp_media")])
8735
8736 (define_insn "cmpgedf_media"
8737   [(set (match_operand:DI 0 "register_operand" "=r")
8738         (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8739                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8740   "TARGET_SHMEDIA_FPU"
8741   "fcmpge.d     %1,%2,%0"
8742   [(set_attr "type" "fcmp_media")])
8743
8744 (define_insn "cmpundf_media"
8745   [(set (match_operand:DI 0 "register_operand" "=r")
8746         (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8747                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8748   "TARGET_SHMEDIA_FPU"
8749   "fcmpun.d     %1,%2,%0"
8750   [(set_attr "type" "fcmp_media")])
8751
8752 (define_expand "cmpdf"
8753   [(set (reg:SI T_REG)
8754         (compare (match_operand:DF 0 "arith_operand" "")
8755                  (match_operand:DF 1 "arith_operand" "")))]
8756   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8757   "
8758 {
8759   sh_compare_op0 = operands[0];
8760   sh_compare_op1 = operands[1];
8761   DONE;
8762 }")
8763
8764 (define_expand "negdf2"
8765   [(set (match_operand:DF 0 "arith_reg_operand" "")
8766         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8767   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8768   "
8769 {
8770   if (TARGET_SH4)
8771     {
8772       expand_df_unop (&gen_negdf2_i, operands);
8773       DONE;
8774     }
8775 }")
8776
8777 (define_insn "*negdf2_media"
8778   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8779         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8780   "TARGET_SHMEDIA_FPU"
8781   "fneg.d       %1, %0"
8782   [(set_attr "type" "fmove_media")])
8783
8784 (define_insn "negdf2_i"
8785   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8786         (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8787    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8788   "TARGET_SH4"
8789   "fneg %0"
8790   [(set_attr "type" "fmove")
8791    (set_attr "fp_mode" "double")])
8792
8793 (define_expand "sqrtdf2"
8794   [(set (match_operand:DF 0 "arith_reg_operand" "")
8795         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8796   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8797   "
8798 {
8799   if (TARGET_SH4)
8800     {
8801       expand_df_unop (&gen_sqrtdf2_i, operands);
8802       DONE;
8803     }
8804 }")
8805
8806 (define_insn "*sqrtdf2_media"
8807   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8808         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8809   "TARGET_SHMEDIA_FPU"
8810   "fsqrt.d      %1, %0"
8811   [(set_attr "type" "dfdiv_media")])
8812
8813 (define_insn "sqrtdf2_i"
8814   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8815         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8816    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8817   "TARGET_SH4"
8818   "fsqrt        %0"
8819   [(set_attr "type" "dfdiv")
8820    (set_attr "fp_mode" "double")])
8821
8822 (define_expand "absdf2"
8823   [(set (match_operand:DF 0 "arith_reg_operand" "")
8824         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8825   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8826   "
8827 {
8828   if (TARGET_SH4)
8829     {
8830       expand_df_unop (&gen_absdf2_i, operands);
8831       DONE;
8832     }
8833 }")
8834
8835 (define_insn "*absdf2_media"
8836   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8837         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8838   "TARGET_SHMEDIA_FPU"
8839   "fabs.d       %1, %0"
8840   [(set_attr "type" "fmove_media")])
8841
8842 (define_insn "absdf2_i"
8843   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8844         (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8845    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8846   "TARGET_SH4"
8847   "fabs %0"
8848   [(set_attr "type" "fmove")
8849    (set_attr "fp_mode" "double")])
8850
8851 (define_expand "extendsfdf2"
8852   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8853         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
8854   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8855   "
8856 {
8857   if (TARGET_SH4)
8858     {
8859       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
8860                                         get_fpscr_rtx ()));
8861       DONE;
8862     }
8863 }")
8864
8865 (define_insn "*extendsfdf2_media"
8866   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8867         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8868   "TARGET_SHMEDIA_FPU"
8869   "fcnv.sd      %1, %0"
8870   [(set_attr "type" "dfpconv_media")])
8871
8872 (define_insn "extendsfdf2_i4"
8873   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8874         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
8875    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8876   "TARGET_SH4"
8877   "fcnvsd  %1,%0"
8878   [(set_attr "type" "fp")
8879    (set_attr "fp_mode" "double")])
8880
8881 (define_expand "truncdfsf2"
8882   [(set (match_operand:SF 0 "fpul_operand" "")
8883         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8884   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8885   "
8886 {
8887   if (TARGET_SH4)
8888     {
8889       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
8890                                        get_fpscr_rtx ()));
8891       DONE;
8892     }
8893 }")
8894
8895 (define_insn "*truncdfsf2_media"
8896   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8897         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8898   "TARGET_SHMEDIA_FPU"
8899   "fcnv.ds      %1, %0"
8900   [(set_attr "type" "dfpconv_media")])
8901
8902 (define_insn "truncdfsf2_i4"
8903   [(set (match_operand:SF 0 "fpul_operand" "=y")
8904         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8905    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8906   "TARGET_SH4"
8907   "fcnvds  %1,%0"
8908   [(set_attr "type" "fp")
8909    (set_attr "fp_mode" "double")])
8910 \f
8911 ;; Bit field extract patterns.  These give better code for packed bitfields,
8912 ;; because they allow auto-increment addresses to be generated.
8913
8914 (define_expand "insv"
8915   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
8916                          (match_operand:SI 1 "immediate_operand" "")
8917                          (match_operand:SI 2 "immediate_operand" ""))
8918         (match_operand:SI 3 "general_operand" ""))]
8919   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
8920   "
8921 {
8922   rtx addr_target, orig_address, shift_reg, qi_val;
8923   HOST_WIDE_INT bitsize, size, v;
8924   rtx x = operands[3];
8925
8926   /* ??? expmed doesn't care for non-register predicates.  */
8927   if (! memory_operand (operands[0], VOIDmode)
8928       || ! immediate_operand (operands[1], VOIDmode)
8929       || ! immediate_operand (operands[2], VOIDmode)
8930       || ! general_operand (x, VOIDmode))
8931     FAIL;
8932   /* If this isn't a 16 / 24 / 32 bit field, or if
8933      it doesn't start on a byte boundary, then fail.  */
8934   bitsize = INTVAL (operands[1]);
8935   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
8936       || (INTVAL (operands[2]) % 8) != 0)
8937     FAIL;
8938
8939   size = bitsize / 8;
8940   orig_address = XEXP (operands[0], 0);
8941   shift_reg = gen_reg_rtx (SImode);
8942   if (GET_CODE (x) == CONST_INT)
8943     {
8944       v = INTVAL (x);
8945       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
8946     }
8947   else
8948     {
8949       emit_insn (gen_movsi (shift_reg, operands[3]));
8950       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
8951     }
8952   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
8953
8954   operands[0] = replace_equiv_address (operands[0], addr_target);
8955   emit_insn (gen_movqi (operands[0], qi_val));
8956
8957   while (size -= 1)
8958     {
8959       if (GET_CODE (x) == CONST_INT)
8960         qi_val
8961           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
8962       else
8963         {
8964           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
8965           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
8966         }
8967       emit_insn (gen_addsi3 (addr_target, addr_target, GEN_INT (-1)));
8968       emit_insn (gen_movqi (operands[0], qi_val));
8969     }
8970
8971   DONE;
8972 }")
8973 \f
8974 ;; -------------------------------------------------------------------------
8975 ;; Peepholes
8976 ;; -------------------------------------------------------------------------
8977
8978 ;; This matches cases where a stack pointer increment at the start of the
8979 ;; epilogue combines with a stack slot read loading the return value.
8980
8981 (define_peephole
8982   [(set (match_operand:SI 0 "arith_reg_operand" "")
8983         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
8984    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
8985   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
8986   "mov.l        @%1+,%0")
8987
8988 ;; See the comment on the dt combiner pattern above.
8989
8990 (define_peephole
8991   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8992         (plus:SI (match_dup 0)
8993                  (const_int -1)))
8994    (set (reg:SI T_REG)
8995         (eq:SI (match_dup 0)
8996                (const_int 0)))]
8997   "TARGET_SH2"
8998   "dt   %0")
8999
9000 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
9001 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
9002 ;; reload when the constant is too large for a reg+offset address.
9003
9004 ;; ??? We would get much better code if this was done in reload.  This would
9005 ;; require modifying find_reloads_address to recognize that if the constant
9006 ;; is out-of-range for an immediate add, then we get better code by reloading
9007 ;; the constant into a register than by reloading the sum into a register,
9008 ;; since the former is one instruction shorter if the address does not need
9009 ;; to be offsettable.  Unfortunately this does not work, because there is
9010 ;; only one register, r0, that can be used as an index register.  This register
9011 ;; is also the function return value register.  So, if we try to force reload
9012 ;; to use double-reg addresses, then we end up with some instructions that
9013 ;; need to use r0 twice.  The only way to fix this is to change the calling
9014 ;; convention so that r0 is not used to return values.
9015
9016 (define_peephole
9017   [(set (match_operand:SI 0 "register_operand" "=r")
9018         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9019    (set (mem:SI (match_dup 0))
9020         (match_operand:SI 2 "general_movsrc_operand" ""))]
9021   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9022   "mov.l        %2,@(%0,%1)")
9023
9024 (define_peephole
9025   [(set (match_operand:SI 0 "register_operand" "=r")
9026         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9027    (set (match_operand:SI 2 "general_movdst_operand" "")
9028         (mem:SI (match_dup 0)))]
9029   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9030   "mov.l        @(%0,%1),%2")
9031
9032 (define_peephole
9033   [(set (match_operand:SI 0 "register_operand" "=r")
9034         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9035    (set (mem:HI (match_dup 0))
9036         (match_operand:HI 2 "general_movsrc_operand" ""))]
9037   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9038   "mov.w        %2,@(%0,%1)")
9039
9040 (define_peephole
9041   [(set (match_operand:SI 0 "register_operand" "=r")
9042         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9043    (set (match_operand:HI 2 "general_movdst_operand" "")
9044         (mem:HI (match_dup 0)))]
9045   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9046   "mov.w        @(%0,%1),%2")
9047
9048 (define_peephole
9049   [(set (match_operand:SI 0 "register_operand" "=r")
9050         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9051    (set (mem:QI (match_dup 0))
9052         (match_operand:QI 2 "general_movsrc_operand" ""))]
9053   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9054   "mov.b        %2,@(%0,%1)")
9055
9056 (define_peephole
9057   [(set (match_operand:SI 0 "register_operand" "=r")
9058         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9059    (set (match_operand:QI 2 "general_movdst_operand" "")
9060         (mem:QI (match_dup 0)))]
9061   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9062   "mov.b        @(%0,%1),%2")
9063
9064 (define_peephole
9065   [(set (match_operand:SI 0 "register_operand" "=r")
9066         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9067    (set (mem:SF (match_dup 0))
9068         (match_operand:SF 2 "general_movsrc_operand" ""))]
9069   "TARGET_SH1 && REGNO (operands[0]) == 0
9070    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9071        || (GET_CODE (operands[2]) == SUBREG
9072            && REGNO (SUBREG_REG (operands[2])) < 16))
9073    && reg_unused_after (operands[0], insn)"
9074   "mov.l        %2,@(%0,%1)")
9075
9076 (define_peephole
9077   [(set (match_operand:SI 0 "register_operand" "=r")
9078         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9079    (set (match_operand:SF 2 "general_movdst_operand" "")
9080
9081         (mem:SF (match_dup 0)))]
9082   "TARGET_SH1 && REGNO (operands[0]) == 0
9083    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9084        || (GET_CODE (operands[2]) == SUBREG
9085            && REGNO (SUBREG_REG (operands[2])) < 16))
9086    && reg_unused_after (operands[0], insn)"
9087   "mov.l        @(%0,%1),%2")
9088
9089 (define_peephole
9090   [(set (match_operand:SI 0 "register_operand" "=r")
9091         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9092    (set (mem:SF (match_dup 0))
9093         (match_operand:SF 2 "general_movsrc_operand" ""))]
9094   "TARGET_SH3E && REGNO (operands[0]) == 0
9095    && ((GET_CODE (operands[2]) == REG
9096         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9097        || (GET_CODE (operands[2]) == SUBREG
9098            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9099    && reg_unused_after (operands[0], insn)"
9100   "fmov{.s|}    %2,@(%0,%1)")
9101
9102 (define_peephole
9103   [(set (match_operand:SI 0 "register_operand" "=r")
9104         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9105    (set (match_operand:SF 2 "general_movdst_operand" "")
9106
9107         (mem:SF (match_dup 0)))]
9108   "TARGET_SH3E && REGNO (operands[0]) == 0
9109    && ((GET_CODE (operands[2]) == REG
9110         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9111        || (GET_CODE (operands[2]) == SUBREG
9112            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9113    && reg_unused_after (operands[0], insn)"
9114   "fmov{.s|}    @(%0,%1),%2")
9115
9116 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
9117 (define_insn "sp_switch_1"
9118   [(const_int 1)]
9119   "TARGET_SH1"
9120   "*
9121 {
9122   rtx xoperands[1];
9123
9124   xoperands[0] = sp_switch;
9125   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9126   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9127   return \"mov r0,r15\";
9128 }"
9129   [(set_attr "length" "10")])
9130
9131 ;; Switch back to the original stack for interrupt functions with the
9132 ;; sp_switch attribute.  */
9133 (define_insn "sp_switch_2"
9134   [(const_int 2)]
9135   "TARGET_SH1"
9136   "mov.l @r15+,r15\;mov.l @r15+,r0"
9137   [(set_attr "length" "4")])
9138
9139 ;; Integer vector moves
9140
9141 (define_expand "movv8qi"
9142   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9143         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9144   "TARGET_SHMEDIA"
9145   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9146
9147 (define_insn "movv8qi_i"
9148   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
9149         (match_operand:V8QI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
9150   "TARGET_SHMEDIA
9151    && (register_operand (operands[0], V8QImode)
9152        || register_operand (operands[1], V8QImode))"
9153   "@
9154         add     %1, r63, %0
9155         movi    %1, %0
9156         #
9157         ld%M1.q %m1, %0
9158         st%M0.q %m0, %1"
9159   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9160    (set_attr "length" "4,4,16,4,4")])
9161
9162 (define_split
9163   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9164         (subreg:V8QI (const_int 0) 0))]
9165   "TARGET_SHMEDIA"
9166   [(set (match_dup 0)
9167         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9168                             (const_int 0) (const_int 0) (const_int 0)
9169                             (const_int 0) (const_int 0)]))])
9170
9171 (define_split
9172   [(set (match_operand 0 "arith_reg_dest" "")
9173         (match_operand 1 "sh_rep_vec" ""))]
9174   "TARGET_SHMEDIA && reload_completed
9175    && GET_MODE (operands[0]) == GET_MODE (operands[1])
9176    && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9177    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9178    && (XVECEXP (operands[1], 0, 0) != const0_rtx
9179        || XVECEXP (operands[1], 0, 1) != const0_rtx)
9180    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
9181        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
9182   [(set (match_dup 0) (match_dup 1))
9183    (match_dup 2)]
9184   "
9185 {
9186   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9187   rtx elt1 = XVECEXP (operands[1], 0, 1);
9188
9189   if (unit_size > 2)
9190     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9191   else
9192     {
9193       if (unit_size < 2)
9194         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
9195       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9196     }
9197   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9198   operands[1] = XVECEXP (operands[1], 0, 0);
9199   if (unit_size < 2)
9200     {
9201       if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
9202         operands[1] = GEN_INT (TARGET_LITTLE_ENDIAN
9203                                ? INTVAL (operands[1]) + (INTVAL (elt1) << 8)
9204                                : (INTVAL (operands[1]) << 8) + INTVAL (elt1));
9205       else
9206         {
9207           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9208           operands[1]
9209             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9210         }
9211     }
9212 }")
9213
9214 (define_split
9215   [(set (match_operand 0 "arith_reg_dest" "")
9216         (match_operand 1 "sh_const_vec" ""))]
9217   "TARGET_SHMEDIA && reload_completed
9218    && GET_MODE (operands[0]) == GET_MODE (operands[1])
9219    && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9220    && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
9221   [(set (match_dup 0) (match_dup 1))]
9222   "
9223 {
9224   rtx v = operands[1];
9225   enum machine_mode new_mode
9226     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9227
9228   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9229   operands[1]
9230     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
9231 }")
9232
9233 (define_expand "movv2hi"
9234   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9235         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9236   "TARGET_SHMEDIA"
9237   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9238
9239 (define_insn "movv2hi_i"
9240   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9241         (match_operand:V2HI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
9242   "TARGET_SHMEDIA
9243    && (register_operand (operands[0], V2HImode)
9244        || register_operand (operands[1], V2HImode))"
9245   "@
9246         addz.l  %1, r63, %0
9247         movi    %1, %0
9248         #
9249         ld%M1.l %m1, %0
9250         st%M0.l %m0, %1"
9251   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9252    (set_attr "length" "4,4,16,4,4")])
9253
9254 (define_expand "movv4hi"
9255   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9256         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9257   "TARGET_SHMEDIA"
9258   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9259
9260 (define_insn "movv4hi_i"
9261   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9262         (match_operand:V4HI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
9263   "TARGET_SHMEDIA
9264    && (register_operand (operands[0], V4HImode)
9265        || register_operand (operands[1], V4HImode))"
9266   "@
9267         add     %1, r63, %0
9268         movi    %1, %0
9269         #
9270         ld%M1.q %m1, %0
9271         st%M0.q %m0, %1"
9272   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9273    (set_attr "length" "4,4,16,4,4")])
9274
9275 (define_expand "movv2si"
9276   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9277         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9278   "TARGET_SHMEDIA"
9279   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9280
9281 (define_insn "movv2si_i"
9282   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
9283         (match_operand:V2SI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
9284   "TARGET_SHMEDIA
9285    && (register_operand (operands[0], V2SImode)
9286        || register_operand (operands[1], V2SImode))"
9287   "@
9288         add     %1, r63, %0
9289         #
9290         #
9291         ld%M1.q %m1, %0
9292         st%M0.q %m0, %1"
9293   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9294    (set_attr "length" "4,4,16,4,4")])
9295
9296 ;; Multimedia Intrinsics
9297
9298 (define_insn "absv2si2"
9299   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9300         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9301   "TARGET_SHMEDIA"
9302   "mabs.l       %1, %0"
9303   [(set_attr "type" "mcmp_media")])
9304
9305 (define_insn "absv4hi2"
9306   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9307         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9308   "TARGET_SHMEDIA"
9309   "mabs.w       %1, %0"
9310   [(set_attr "type" "mcmp_media")])
9311
9312 (define_insn "addv2si3"
9313   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9314         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9315                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9316   "TARGET_SHMEDIA"
9317   "madd.l       %1, %2, %0"
9318   [(set_attr "type" "arith_media")])
9319
9320 (define_insn "addv4hi3"
9321   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9322         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9323                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9324   "TARGET_SHMEDIA"
9325   "madd.w       %1, %2, %0"
9326   [(set_attr "type" "arith_media")])
9327
9328 (define_insn "ssaddv2si3"
9329   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9330         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9331                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9332   "TARGET_SHMEDIA"
9333   "madds.l      %1, %2, %0"
9334   [(set_attr "type" "mcmp_media")])
9335
9336 (define_insn "usaddv8qi3"
9337   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9338         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9339                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9340   "TARGET_SHMEDIA"
9341   "madds.ub     %1, %2, %0"
9342   [(set_attr "type" "mcmp_media")])
9343
9344 (define_insn "ssaddv4hi3"
9345   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9346         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9347                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9348   "TARGET_SHMEDIA"
9349   "madds.w      %1, %2, %0"
9350   [(set_attr "type" "mcmp_media")])
9351
9352 (define_insn "negcmpeqv8qi"
9353   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9354         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rU")
9355                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))))]
9356   "TARGET_SHMEDIA"
9357   "mcmpeq.b     %N1, %N2, %0"
9358   [(set_attr "type" "mcmp_media")])
9359
9360 (define_insn "negcmpeqv2si"
9361   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9362         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rU")
9363                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9364   "TARGET_SHMEDIA"
9365   "mcmpeq.l     %N1, %N2, %0"
9366   [(set_attr "type" "mcmp_media")])
9367
9368 (define_insn "negcmpeqv4hi"
9369   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9370         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rU")
9371                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9372   "TARGET_SHMEDIA"
9373   "mcmpeq.w     %N1, %N2, %0"
9374   [(set_attr "type" "mcmp_media")])
9375
9376 (define_insn "negcmpgtuv8qi"
9377   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9378         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rU")
9379                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))))]
9380   "TARGET_SHMEDIA"
9381   "mcmpgt.ub    %N1, %N2, %0"
9382   [(set_attr "type" "mcmp_media")])
9383
9384 (define_insn "negcmpgtv2si"
9385   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9386         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rU")
9387                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9388   "TARGET_SHMEDIA"
9389   "mcmpgt.l     %N1, %N2, %0"
9390   [(set_attr "type" "mcmp_media")])
9391
9392 (define_insn "negcmpgtv4hi"
9393   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9394         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rU")
9395                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9396   "TARGET_SHMEDIA"
9397   "mcmpgt.w     %N1, %N2, %0"
9398   [(set_attr "type" "mcmp_media")])
9399
9400 (define_insn "mcmv"
9401   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9402         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9403                         (match_operand:DI 2 "arith_reg_operand" "r"))
9404                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9405                         (not:DI (match_dup 2)))))]
9406   "TARGET_SHMEDIA"
9407   "mcmv %N1, %2, %0"
9408   [(set_attr "type" "arith_media")])
9409
9410 (define_insn "mcnvs_lw"
9411   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9412         (vec_concat:V4HI
9413          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU"))
9414          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9415   "TARGET_SHMEDIA"
9416   "mcnvs.lw     %N1, %N2, %0"
9417   [(set_attr "type" "mcmp_media")])
9418
9419 (define_insn "mcnvs_wb"
9420   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9421         (vec_concat:V8QI
9422          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU"))
9423          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9424   "TARGET_SHMEDIA"
9425   "mcnvs.wb     %N1, %N2, %0"
9426   [(set_attr "type" "mcmp_media")])
9427
9428 (define_insn "mcnvs_wub"
9429   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9430         (vec_concat:V8QI
9431          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU"))
9432          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9433   "TARGET_SHMEDIA"
9434   "mcnvs.wub    %N1, %N2, %0"
9435   [(set_attr "type" "mcmp_media")])
9436
9437 (define_insn "mextr_rl"
9438   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9439         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9440                              (match_operand:HI 3 "mextr_bit_offset" "i"))
9441                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9442                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9443   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9444   "*
9445 {
9446   static char templ[16];
9447
9448   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9449            (int) INTVAL (operands[3]) >> 3);
9450   return templ;
9451 }"
9452   [(set_attr "type" "arith_media")])
9453
9454 (define_insn "*mextr_lr"
9455   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9456         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9457                            (match_operand:HI 3 "mextr_bit_offset" "i"))
9458                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9459                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9460   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9461   "*
9462 {
9463   static char templ[16];
9464
9465   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9466            (int) INTVAL (operands[4]) >> 3);
9467   return templ;
9468 }"
9469   [(set_attr "type" "arith_media")])
9470
9471 ; mextrN can be modelled with vec_select / vec_concat, but the selection
9472 ; vector then varies depending on endianness.
9473 (define_expand "mextr1"
9474   [(match_operand:DI 0 "arith_reg_dest" "")
9475    (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9476    (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9477   "TARGET_SHMEDIA"
9478   "
9479 {
9480   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9481                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
9482   DONE;
9483 }")
9484
9485 (define_expand "mextr2"
9486   [(match_operand:DI 0 "arith_reg_dest" "")
9487    (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9488    (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9489   "TARGET_SHMEDIA"
9490   "
9491 {
9492   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9493                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
9494   DONE;
9495 }")
9496
9497 (define_expand "mextr3"
9498   [(match_operand:DI 0 "arith_reg_dest" "")
9499    (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9500    (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9501   "TARGET_SHMEDIA"
9502   "
9503 {
9504   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9505                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
9506   DONE;
9507 }")
9508
9509 (define_expand "mextr4"
9510   [(match_operand:DI 0 "arith_reg_dest" "")
9511    (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9512    (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9513   "TARGET_SHMEDIA"
9514   "
9515 {
9516   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9517                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
9518   DONE;
9519 }")
9520
9521 (define_expand "mextr5"
9522   [(match_operand:DI 0 "arith_reg_dest" "")
9523    (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9524    (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9525   "TARGET_SHMEDIA"
9526   "
9527 {
9528   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9529                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
9530   DONE;
9531 }")
9532
9533 (define_expand "mextr6"
9534   [(match_operand:DI 0 "arith_reg_dest" "")
9535    (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9536    (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9537   "TARGET_SHMEDIA"
9538   "
9539 {
9540   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9541                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
9542   DONE;
9543 }")
9544
9545 (define_expand "mextr7"
9546   [(match_operand:DI 0 "arith_reg_dest" "")
9547    (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9548    (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9549   "TARGET_SHMEDIA"
9550   "
9551 {
9552   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9553                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
9554   DONE;
9555 }")
9556
9557 (define_expand "mmacfx_wl"
9558   [(match_operand:V2SI 0 "arith_reg_dest" "")
9559    (match_operand:V2HI 1 "extend_reg_operand" "")
9560    (match_operand:V2HI 2 "extend_reg_operand" "")
9561    (match_operand:V2SI 3 "arith_reg_operand" "")]
9562   "TARGET_SHMEDIA"
9563   "
9564 {
9565   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
9566                               operands[1], operands[2]));
9567   DONE;
9568 }")
9569
9570 (define_insn "mmacfx_wl_i"
9571   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9572         (ss_plus:V2SI
9573          (match_operand:V2SI 1 "arith_reg_operand" "0")
9574          (ss_truncate:V2SI
9575           (ashift:V2DI
9576            (sign_extend:V2DI
9577             (mult:V2SI
9578              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9579              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9580            (const_int 1)))))]
9581   "TARGET_SHMEDIA"
9582   "mmacfx.wl    %2, %3, %0"
9583   [(set_attr "type" "mac_media")])
9584
9585 (define_expand "mmacnfx_wl"
9586   [(match_operand:V2SI 0 "arith_reg_dest" "")
9587    (match_operand:V2HI 1 "extend_reg_operand" "")
9588    (match_operand:V2HI 2 "extend_reg_operand" "")
9589    (match_operand:V2SI 3 "arith_reg_operand" "")]
9590   "TARGET_SHMEDIA"
9591   "
9592 {
9593   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
9594                                operands[1], operands[2]));
9595   DONE;
9596 }")
9597
9598 (define_insn "mmacnfx_wl_i"
9599   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9600         (ss_minus:V2SI
9601          (match_operand:V2SI 1 "arith_reg_operand" "0")
9602          (ss_truncate:V2SI
9603           (ashift:V2DI
9604            (sign_extend:V2DI
9605             (mult:V2SI
9606              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9607              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9608            (const_int 1)))))]
9609   "TARGET_SHMEDIA"
9610   "mmacnfx.wl   %2, %3, %0"
9611   [(set_attr "type" "mac_media")])
9612
9613 (define_insn "mulv2si3"
9614   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9615         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9616                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9617   "TARGET_SHMEDIA"
9618   "mmul.l       %1, %2, %0"
9619   [(set_attr "type" "d2mpy_media")])
9620
9621 (define_insn "mulv4hi3"
9622   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9623         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9624                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9625   "TARGET_SHMEDIA"
9626   "mmul.w       %1, %2, %0"
9627   [(set_attr "type" "dmpy_media")])
9628
9629 (define_insn "mmulfx_l"
9630   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9631         (ss_truncate:V2SI
9632          (ashiftrt:V2DI
9633           (mult:V2DI
9634            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9635            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
9636           (const_int 31))))]
9637   "TARGET_SHMEDIA"
9638   "mmulfx.l     %1, %2, %0"
9639   [(set_attr "type" "d2mpy_media")])
9640
9641 (define_insn "mmulfx_w"
9642   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9643         (ss_truncate:V4HI
9644          (ashiftrt:V4SI
9645           (mult:V4SI
9646            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9647            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9648           (const_int 15))))]
9649   "TARGET_SHMEDIA"
9650   "mmulfx.w     %1, %2, %0"
9651   [(set_attr "type" "dmpy_media")])
9652
9653 (define_insn "mmulfxrp_w"
9654   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9655         (ss_truncate:V4HI
9656          (ashiftrt:V4SI
9657           (plus:V4SI
9658            (mult:V4SI
9659             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9660             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9661            (const_int 16384))
9662           (const_int 15))))]
9663   "TARGET_SHMEDIA"
9664   "mmulfxrp.w   %1, %2, %0"
9665   [(set_attr "type" "dmpy_media")])
9666
9667 (define_expand "mmulhi_wl"
9668   [(match_operand:V2SI 0 "arith_reg_dest" "")
9669    (match_operand:V4HI 1 "arith_reg_operand" "")
9670    (match_operand:V4HI 2 "arith_reg_operand" "")]
9671   "TARGET_SHMEDIA"
9672   "
9673 {
9674   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
9675              (operands[0], operands[1], operands[2]));
9676   DONE;
9677 }")
9678
9679 (define_expand "mmullo_wl"
9680   [(match_operand:V2SI 0 "arith_reg_dest" "")
9681    (match_operand:V4HI 1 "arith_reg_operand" "")
9682    (match_operand:V4HI 2 "arith_reg_operand" "")]
9683   "TARGET_SHMEDIA"
9684   "
9685 {
9686   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
9687              (operands[0], operands[1], operands[2]));
9688   DONE;
9689 }")
9690
9691 (define_insn "mmul23_wl"
9692   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9693         (vec_select:V2SI
9694          (mult:V4SI
9695           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9696           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9697          (parallel [(const_int 2) (const_int 3)])))]
9698   "TARGET_SHMEDIA"
9699   "* return (TARGET_LITTLE_ENDIAN
9700              ? \"mmulhi.wl      %1, %2, %0\"
9701              : \"mmullo.wl      %1, %2, %0\");"
9702   [(set_attr "type" "dmpy_media")])
9703
9704 (define_insn "mmul01_wl"
9705   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9706         (vec_select:V2SI
9707          (mult:V4SI
9708           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9709           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9710          (parallel [(const_int 0) (const_int 1)])))]
9711   "TARGET_SHMEDIA"
9712   "* return (TARGET_LITTLE_ENDIAN
9713              ? \"mmullo.wl      %1, %2, %0\"
9714              : \"mmulhi.wl      %1, %2, %0\");"
9715   [(set_attr "type" "dmpy_media")])
9716
9717 (define_expand "mmulsum_wq"
9718   [(match_operand:DI 0 "arith_reg_dest" "")
9719    (match_operand:V4HI 1 "arith_reg_operand" "")
9720    (match_operand:V4HI 2 "arith_reg_operand" "")
9721    (match_operand:DI 3 "arith_reg_operand" "")]
9722   "TARGET_SHMEDIA"
9723   "
9724 {
9725   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
9726                                operands[1], operands[2]));
9727   DONE;
9728 }")
9729
9730 (define_insn "mmulsum_wq_i"
9731   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9732         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
9733          (plus:DI
9734           (plus:DI
9735            (vec_select:DI
9736             (mult:V4DI
9737              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
9738              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
9739             (parallel [(const_int 0)]))
9740            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9741                                      (sign_extend:V4DI (match_dup 3)))
9742                           (parallel [(const_int 1)])))
9743           (plus:DI
9744            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9745                                      (sign_extend:V4DI (match_dup 3)))
9746                           (parallel [(const_int 2)]))
9747            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9748                                      (sign_extend:V4DI (match_dup 3)))
9749                           (parallel [(const_int 3)]))))))]
9750   "TARGET_SHMEDIA"
9751   "mmulsum.wq   %2, %3, %0"
9752   [(set_attr "type" "mac_media")])
9753
9754 (define_expand "mperm_w"
9755   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
9756    (match_operand:V4HI 1 "arith_reg_operand" "r")
9757    (match_operand:QI 2 "extend_reg_or_0_operand" "rU")]
9758   "TARGET_SHMEDIA"
9759   "
9760 {
9761   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
9762              (operands[0], operands[1], operands[2]));
9763   DONE;
9764 }")
9765
9766 ; This use of vec_select isn't exactly correct according to rtl.texi
9767 ; (because not constant), but it seems a straightforward extension.
9768 (define_insn "mperm_w_little"
9769   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9770         (vec_select:V4HI
9771          (match_operand:V4HI 1 "arith_reg_operand" "r")
9772          (parallel
9773           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rU")
9774                             (const_int 2) (const_int 0))
9775            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
9776            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
9777            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
9778   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
9779   "mperm.w      %1, %N2, %0"
9780   [(set_attr "type" "arith_media")])
9781
9782 (define_insn "mperm_w_big"
9783   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9784         (vec_select:V4HI
9785          (match_operand:V4HI 1 "arith_reg_operand" "r")
9786          (parallel
9787           [(zero_extract:QI (not:QI (match_operand:QI 2
9788                                      "extend_reg_or_0_operand" "rU"))
9789                             (const_int 2) (const_int 0))
9790            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
9791            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
9792            (zero_extract:QI (not:QI (match_dup 2))
9793                             (const_int 2) (const_int 6))])))]
9794   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
9795   "mperm.w      %1, %N2, %0"
9796   [(set_attr "type" "arith_media")])
9797
9798 (define_insn "mperm_w0"
9799   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9800         (vec_duplicate:V4HI (truncate:HI (match_operand 1
9801                                           "trunc_hi_operand" "r"))))]
9802   "TARGET_SHMEDIA"
9803   "mperm.w      %1, r63, %0"
9804   [(set_attr "type" "arith_media")])
9805
9806 (define_expand "msad_ubq"
9807   [(match_operand:DI 0 "arith_reg_dest" "")
9808    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
9809    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
9810    (match_operand:DI 3 "arith_reg_operand" "")]
9811   "TARGET_SHMEDIA"
9812   "
9813 {
9814   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
9815                              operands[1], operands[2]));
9816   DONE;
9817 }")
9818
9819 (define_insn "msad_ubq_i"
9820   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9821         (plus:DI
9822          (plus:DI
9823           (plus:DI
9824            (plus:DI
9825             (match_operand:DI 1 "arith_reg_operand" "0")
9826             (abs:DI (vec_select:DI
9827                      (minus:V8DI
9828                       (zero_extend:V8DI
9829                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "r"))
9830                       (zero_extend:V8DI
9831                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "r")))
9832                      (parallel [(const_int 0)]))))
9833            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9834                                               (zero_extend:V8DI (match_dup 3)))
9835                                   (parallel [(const_int 1)]))))
9836           (plus:DI
9837            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9838                                               (zero_extend:V8DI (match_dup 3)))
9839                                   (parallel [(const_int 2)])))
9840            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9841                                               (zero_extend:V8DI (match_dup 3)))
9842                                   (parallel [(const_int 3)])))))
9843          (plus:DI
9844           (plus:DI
9845            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9846                                               (zero_extend:V8DI (match_dup 3)))
9847                                   (parallel [(const_int 4)])))
9848            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9849                                               (zero_extend:V8DI (match_dup 3)))
9850                                   (parallel [(const_int 5)]))))
9851           (plus:DI
9852            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9853                                               (zero_extend:V8DI (match_dup 3)))
9854                                   (parallel [(const_int 6)])))
9855            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9856                                               (zero_extend:V8DI (match_dup 3)))
9857                                   (parallel [(const_int 7)])))))))]
9858   "TARGET_SHMEDIA"
9859   "msad.ubq     %N2, %N3, %0"
9860   [(set_attr "type" "mac_media")])
9861
9862 (define_insn "mshalds_l"
9863   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9864         (ss_truncate:V2SI
9865          (ashift:V2DI
9866           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9867           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
9868                   (const_int 31)))))]
9869   "TARGET_SHMEDIA"
9870   "mshalds.l    %1, %2, %0"
9871   [(set_attr "type" "mcmp_media")])
9872
9873 (define_insn "mshalds_w"
9874   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9875         (ss_truncate:V4HI
9876          (ashift:V4SI
9877           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9878           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
9879                   (const_int 15)))))]
9880   "TARGET_SHMEDIA"
9881   "mshalds.w    %1, %2, %0"
9882   [(set_attr "type" "mcmp_media")])
9883
9884 (define_insn "ashrv2si3"
9885   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9886         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9887                        (match_operand:DI 2 "arith_reg_operand" "r")))]
9888   "TARGET_SHMEDIA"
9889   "mshard.l     %1, %2, %0"
9890   [(set_attr "type" "arith_media")])
9891
9892 (define_insn "ashrv4hi3"
9893   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9894         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9895                        (match_operand:DI 2 "arith_reg_operand" "r")))]
9896   "TARGET_SHMEDIA"
9897   "mshard.w     %1, %2, %0"
9898   [(set_attr "type" "arith_media")])
9899
9900 (define_insn "mshards_q"
9901   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
9902         (ss_truncate:HI
9903          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
9904                       (match_operand:DI 2 "arith_reg_or_0_operand" "rU"))))]
9905   "TARGET_SHMEDIA"
9906   "mshards.q    %1, %N2, %0"
9907   [(set_attr "type" "mcmp_media")])
9908
9909 (define_expand "mshfhi_b"
9910   [(match_operand:V8QI 0 "arith_reg_dest" "")
9911    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9912    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9913   "TARGET_SHMEDIA"
9914   "
9915 {
9916   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
9917              (operands[0], operands[1], operands[2]));
9918   DONE;
9919 }")
9920
9921 (define_expand "mshflo_b"
9922   [(match_operand:V8QI 0 "arith_reg_dest" "")
9923    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9924    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9925   "TARGET_SHMEDIA"
9926   "
9927 {
9928   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
9929              (operands[0], operands[1], operands[2]));
9930   DONE;
9931 }")
9932
9933 (define_insn "mshf4_b"
9934   [(set
9935     (match_operand:V8QI 0 "arith_reg_dest" "=r")
9936     (vec_select:V8QI
9937      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9938                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))
9939      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
9940                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
9941   "TARGET_SHMEDIA"
9942   "* return (TARGET_LITTLE_ENDIAN
9943              ? \"mshfhi.b       %N1, %N2, %0\"
9944              : \"mshflo.b       %N1, %N2, %0\");"
9945   [(set_attr "type" "arith_media")])
9946
9947 (define_insn "mshf0_b"
9948   [(set
9949     (match_operand:V8QI 0 "arith_reg_dest" "=r")
9950     (vec_select:V8QI
9951      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9952                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))
9953      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
9954                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
9955   "TARGET_SHMEDIA"
9956   "* return (TARGET_LITTLE_ENDIAN
9957              ? \"mshflo.b       %N1, %N2, %0\"
9958              : \"mshfhi.b       %N1, %N2, %0\");"
9959   [(set_attr "type" "arith_media")])
9960
9961 (define_expand "mshfhi_l"
9962   [(match_operand:V2SI 0 "arith_reg_dest" "")
9963    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
9964    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU")]
9965   "TARGET_SHMEDIA"
9966   "
9967 {
9968   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
9969              (operands[0], operands[1], operands[2]));
9970   DONE;
9971 }")
9972
9973 (define_expand "mshflo_l"
9974   [(match_operand:V2SI 0 "arith_reg_dest" "")
9975    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
9976    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU")]
9977   "TARGET_SHMEDIA"
9978   "
9979 {
9980   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
9981              (operands[0], operands[1], operands[2]));
9982   DONE;
9983 }")
9984
9985 (define_insn "mshf4_l"
9986   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9987         (vec_select:V2SI
9988          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
9989                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))
9990          (parallel [(const_int 1) (const_int 3)])))]
9991   "TARGET_SHMEDIA"
9992   "* return (TARGET_LITTLE_ENDIAN
9993              ? \"mshfhi.l       %N1, %N2, %0\"
9994              : \"mshflo.l       %N1, %N2, %0\");"
9995   [(set_attr "type" "arith_media")])
9996
9997 (define_insn "mshf0_l"
9998   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9999         (vec_select:V2SI
10000          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10001                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))
10002          (parallel [(const_int 0) (const_int 2)])))]
10003   "TARGET_SHMEDIA"
10004   "* return (TARGET_LITTLE_ENDIAN
10005              ? \"mshflo.l       %N1, %N2, %0\"
10006              : \"mshfhi.l       %N1, %N2, %0\");"
10007   [(set_attr "type" "arith_media")])
10008
10009 (define_expand "mshfhi_w"
10010   [(match_operand:V4HI 0 "arith_reg_dest" "")
10011    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10012    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU")]
10013   "TARGET_SHMEDIA"
10014   "
10015 {
10016   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
10017              (operands[0], operands[1], operands[2]));
10018   DONE;
10019 }")
10020
10021 (define_expand "mshflo_w"
10022   [(match_operand:V4HI 0 "arith_reg_dest" "")
10023    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10024    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU")]
10025   "TARGET_SHMEDIA"
10026   "
10027 {
10028   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
10029              (operands[0], operands[1], operands[2]));
10030   DONE;
10031 }")
10032
10033 (define_insn "mshf4_w"
10034   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10035         (vec_select:V4HI
10036          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10037                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))
10038          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
10039   "TARGET_SHMEDIA"
10040   "* return (TARGET_LITTLE_ENDIAN
10041              ? \"mshfhi.w       %N1, %N2, %0\"
10042              : \"mshflo.w       %N1, %N2, %0\");"
10043   [(set_attr "type" "arith_media")])
10044
10045 (define_insn "mshf0_w"
10046   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10047         (vec_select:V4HI
10048          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10049                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))
10050          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
10051   "TARGET_SHMEDIA"
10052   "* return (TARGET_LITTLE_ENDIAN
10053              ? \"mshflo.w       %N1, %N2, %0\"
10054              : \"mshfhi.w       %N1, %N2, %0\");"
10055   [(set_attr "type" "arith_media")])
10056
10057 (define_insn "mshflo_w_x"
10058   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10059         (vec_select:V4HI
10060          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rU")
10061                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rU"))
10062          (parallel [(const_int 0) (const_int 2) (const_int 1) (const_int 3)])))]
10063   "TARGET_SHMEDIA"
10064   "mshflo.w     %N1, %N2, %0"
10065   [(set_attr "type" "arith_media")])
10066
10067 /* These are useful to expand ANDs and as combiner patterns.  */
10068 (define_insn_and_split "mshfhi_l_di"
10069   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
10070         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU,f")
10071                              (const_int 32))
10072                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU,?f")
10073                         (const_int -4294967296))))]
10074   "TARGET_SHMEDIA"
10075   "@
10076         mshfhi.l        %N1, %N2, %0
10077         #"
10078   "TARGET_SHMEDIA && reload_completed
10079    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10080   [(set (match_dup 3) (match_dup 4))
10081    (set (match_dup 5) (match_dup 6))]
10082   "
10083 {
10084   operands[3] = gen_lowpart (SImode, operands[0]);
10085   operands[4] = gen_highpart (SImode, operands[1]);
10086   operands[5] = gen_highpart (SImode, operands[0]);
10087   operands[6] = gen_highpart (SImode, operands[2]);
10088 }"
10089   [(set_attr "type" "arith_media")])
10090
10091 (define_insn "*mshfhi_l_di_rev"
10092   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10093         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10094                         (const_int -4294967296))
10095                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10096                              (const_int 32))))]
10097   "TARGET_SHMEDIA"
10098   "mshfhi.l     %N2, %N1, %0"
10099   [(set_attr "type" "arith_media")])
10100
10101 (define_split
10102   [(set (match_operand:DI 0 "arith_reg_dest" "")
10103         (ior:DI (zero_extend:DI (match_operand:SI 1
10104                                               "extend_reg_or_0_operand" ""))
10105                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10106                         (const_int -4294967296))))
10107    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10108   "TARGET_SHMEDIA"
10109   [(const_int 0)]
10110   "
10111 {
10112   emit_insn (gen_ashldi3_media (operands[3],
10113                                 simplify_gen_subreg (DImode, operands[1],
10114                                                      SImode, 0),
10115                                 GEN_INT (32)));
10116   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10117   DONE;
10118 }")
10119
10120 (define_insn "mshflo_l_di"
10121   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10122         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10123                         (const_int 4294967295))
10124                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10125                            (const_int 32))))]
10126                                 
10127   "TARGET_SHMEDIA"
10128   "mshflo.l     %N1, %N2, %0"
10129   [(set_attr "type" "arith_media")])
10130
10131 (define_insn "*mshflo_l_di_rev"
10132   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10133         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10134                            (const_int 32))
10135                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10136                         (const_int 4294967295))))]
10137                                 
10138   "TARGET_SHMEDIA"
10139   "mshflo.l     %N2, %N1, %0"
10140   [(set_attr "type" "arith_media")])
10141
10142 ;; Combiner pattern for trampoline initialization.
10143 (define_insn_and_split "*double_shori"
10144   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10145         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10146                            (const_int 32))
10147                 (match_operand:DI 2 "const_int_operand" "n")))]
10148   "TARGET_SHMEDIA
10149    && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10150   "#"
10151   "rtx_equal_p (operands[0], operands[1])"
10152   [(const_int 0)]
10153   "
10154 {
10155   HOST_WIDE_INT v = INTVAL (operands[2]);
10156
10157   emit_insn (gen_shori_media (operands[0], operands[0],
10158              gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10159   emit_insn (gen_shori_media (operands[0], operands[0],
10160                               gen_int_mode (v, HImode)));
10161   DONE;
10162 }")
10163
10164
10165 (define_insn "*mshflo_l_di_x"
10166   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10167         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
10168                                  "rU"))
10169                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10170                            (const_int 32))))]
10171                                 
10172   "TARGET_SHMEDIA"
10173   "mshflo.l     %N1, %N2, %0"
10174   [(set_attr "type" "arith_media")])
10175
10176 (define_insn_and_split "concat_v2sf"
10177   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
10178 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rU,0,f")
10179         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rU,f,f")
10180                          (match_operand:SF 2 "register_operand" "rU,f,f")))]
10181                                 
10182   "TARGET_SHMEDIA"
10183   "@
10184         mshflo.l        %N1, %N2, %0
10185         #
10186         #"
10187   "TARGET_SHMEDIA && reload_completed
10188    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10189   [(set (match_dup 3) (match_dup 1))
10190    (set (match_dup 4) (match_dup 2))]
10191   "
10192 {
10193   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10194   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10195 }"
10196   [(set_attr "type" "arith_media")])
10197
10198 (define_insn "*mshflo_l_di_x_rev"
10199   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10200         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10201                            (const_int 32))
10202                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rU"))))]
10203                                 
10204   "TARGET_SHMEDIA"
10205   "mshflo.l     %N2, %N1, %0"
10206   [(set_attr "type" "arith_media")])
10207
10208 (define_insn "ashlv2si3"
10209   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10210         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10211                      (match_operand:DI 2 "arith_reg_operand" "r")))]
10212   "TARGET_SHMEDIA"
10213   "mshlld.l     %1, %2, %0"
10214   [(set_attr "type" "arith_media")])
10215
10216 (define_insn "ashlv4hi3"
10217   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10218         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10219                      (match_operand:DI 2 "arith_reg_operand" "r")))]
10220   "TARGET_SHMEDIA"
10221   "mshlld.w     %1, %2, %0"
10222   [(set_attr "type" "arith_media")])
10223
10224 (define_insn "lshrv2si3"
10225   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10226         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10227                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10228   "TARGET_SHMEDIA"
10229   "mshlrd.l     %1, %2, %0"
10230   [(set_attr "type" "arith_media")])
10231
10232 (define_insn "lshrv4hi3"
10233   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10234         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10235                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10236   "TARGET_SHMEDIA"
10237   "mshlrd.w     %1, %2, %0"
10238   [(set_attr "type" "arith_media")])
10239
10240 (define_insn "subv2si3"
10241   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10242         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10243                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10244   "TARGET_SHMEDIA"
10245   "msub.l       %N1, %2, %0"
10246   [(set_attr "type" "arith_media")])
10247
10248 (define_insn "subv4hi3"
10249   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10250         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10251                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10252   "TARGET_SHMEDIA"
10253   "msub.w       %N1, %2, %0"
10254   [(set_attr "type" "arith_media")])
10255
10256 (define_insn "sssubv2si3"
10257   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10258         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10259                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10260   "TARGET_SHMEDIA"
10261   "msubs.l      %N1, %2, %0"
10262   [(set_attr "type" "mcmp_media")])
10263
10264 (define_insn "ussubv8qi3"
10265   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10266         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10267                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10268   "TARGET_SHMEDIA"
10269   "msubs.ub     %1, %2, %0"
10270   [(set_attr "type" "mcmp_media")])
10271
10272 (define_insn "sssubv4hi3"
10273   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10274         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10275                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10276   "TARGET_SHMEDIA"
10277   "msubs.w      %N1, %2, %0"
10278   [(set_attr "type" "mcmp_media")])
10279
10280 ;; Floating Point Intrinsics
10281
10282 (define_insn "fcosa_s"
10283   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10284         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10285                    UNSPEC_FCOSA))]
10286   "TARGET_SHMEDIA"
10287   "fcosa.s      %1, %0"
10288   [(set_attr "type" "atrans_media")])
10289
10290 (define_insn "fsina_s"
10291   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10292         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10293                    UNSPEC_FSINA))]
10294   "TARGET_SHMEDIA"
10295   "fsina.s      %1, %0"
10296   [(set_attr "type" "atrans_media")])
10297
10298 (define_insn "fipr"
10299   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10300         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10301                                                     "fp_arith_reg_operand" "f")
10302                                                    (match_operand:V4SF 2
10303                                                     "fp_arith_reg_operand" "f"))
10304                                          (parallel [(const_int 0)]))
10305                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10306                                          (parallel [(const_int 1)])))
10307                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10308                                          (parallel [(const_int 2)]))
10309                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10310                                          (parallel [(const_int 3)])))))]
10311   "TARGET_SHMEDIA"
10312   "fipr %1, %2, %0"
10313   [(set_attr "type" "fparith_media")])
10314
10315 (define_insn "fsrra_s"
10316   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10317         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10318                    UNSPEC_FSRRA))]
10319   "TARGET_SHMEDIA"
10320   "fsrra.s      %1, %0"
10321   [(set_attr "type" "atrans_media")])
10322
10323 (define_insn "ftrv"
10324   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10325         (plus:V4SF
10326          (plus:V4SF
10327           (mult:V4SF
10328            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
10329                             (parallel [(const_int 0) (const_int 5)
10330                                        (const_int 10) (const_int 15)]))
10331            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10332           (mult:V4SF
10333            (vec_select:V4SF (match_dup 1)
10334                             (parallel [(const_int 4) (const_int 9)
10335                                        (const_int 14) (const_int 3)]))
10336            (vec_select:V4SF (match_dup 2)
10337                             (parallel [(const_int 1) (const_int 2)
10338                                       (const_int 3) (const_int 0)]))))
10339          (plus:V4SF
10340           (mult:V4SF
10341            (vec_select:V4SF (match_dup 1)
10342                             (parallel [(const_int 8) (const_int 13)
10343                                        (const_int 2) (const_int 7)]))
10344            (vec_select:V4SF (match_dup 2)
10345                             (parallel [(const_int 2) (const_int 3)
10346                                        (const_int 0) (const_int 1)])))
10347           (mult:V4SF
10348            (vec_select:V4SF (match_dup 1)
10349                             (parallel [(const_int 12) (const_int 1)
10350                                        (const_int 6) (const_int 11)]))
10351            (vec_select:V4SF (match_dup 2)
10352                             (parallel [(const_int 3) (const_int 0)
10353                                        (const_int 1) (const_int 2)]))))))]
10354   "TARGET_SHMEDIA"
10355   "ftrv %1, %2, %0"
10356   [(set_attr "type" "fparith_media")])
10357
10358 (define_insn "nsb"
10359   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10360         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10361                    UNSPEC_NSB))]
10362   "TARGET_SHMEDIA"
10363   "nsb  %1, %0"
10364   [(set_attr "type" "arith_media")])
10365
10366 (define_insn "nsbsi"
10367   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10368         (zero_extend:SI
10369          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10370                     UNSPEC_NSB)))]
10371   "TARGET_SHMEDIA"
10372   "nsb  %1, %0"
10373   [(set_attr "type" "arith_media")])
10374
10375 (define_insn "nsbdi"
10376   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10377         (zero_extend:DI
10378          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10379                     UNSPEC_NSB)))]
10380   "TARGET_SHMEDIA"
10381   "nsb  %1, %0"
10382   [(set_attr "type" "arith_media")])
10383
10384 (define_expand "ffsdi2"
10385   [(set (match_operand:DI 0 "arith_reg_dest" "")
10386         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10387   "TARGET_SHMEDIA"
10388   "
10389 {
10390   rtx scratch = gen_reg_rtx (DImode);
10391   rtx last;
10392
10393   emit_insn (gen_adddi3 (scratch, operands[1], GEN_INT (-1)));
10394   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10395   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10396   emit_insn (gen_nsbdi (scratch, scratch));
10397   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10398   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10399   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10400   REG_NOTES (last)
10401     = gen_rtx_EXPR_LIST (REG_EQUAL,
10402                          gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10403   DONE;
10404 }")
10405
10406 (define_expand "ffssi2"
10407   [(set (match_operand:SI 0 "arith_reg_dest" "")
10408         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10409   "TARGET_SHMEDIA"
10410   "
10411 {
10412   rtx scratch = gen_reg_rtx (SImode);
10413   rtx discratch = gen_reg_rtx (DImode);
10414   rtx last;
10415
10416   emit_insn (gen_adddi3 (discratch,
10417                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
10418                          GEN_INT (-1)));
10419   emit_insn (gen_andcdi3 (discratch,
10420                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
10421                           discratch));
10422   emit_insn (gen_nsbsi (scratch, discratch));
10423   last = emit_insn (gen_subsi3 (operands[0],
10424                                 force_reg (SImode, GEN_INT (63)), scratch));
10425   REG_NOTES (last)
10426     = gen_rtx_EXPR_LIST (REG_EQUAL,
10427                          gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10428   DONE;
10429 }")
10430
10431 (define_insn "byterev"
10432   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10433         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10434                          (parallel [(const_int 7) (const_int 6) (const_int 5)
10435                                     (const_int 4) (const_int 3) (const_int 2)
10436                                     (const_int 1) (const_int 0)])))]
10437   "TARGET_SHMEDIA"
10438   "byterev      %1, %0"
10439   [(set_attr "type" "arith_media")])
10440
10441 ;; The following description  models the
10442 ;; SH4 pipeline using the DFA based scheduler. 
10443 ;; The DFA based description is better way to model 
10444 ;; a superscalar pipeline as compared to function unit
10445 ;; reservation model.   
10446 ;; 1. The function unit based model is oriented to describe at most one 
10447 ;;    unit reservation by each insn. It is difficult to model unit reservations in multiple 
10448 ;;    pipeline units by same insn. This can be done using DFA based description.
10449 ;; 2. The execution performance of DFA based scheduler does not depend on processor complexity.
10450 ;; 3. Writing all unit reservations for an instruction class is more natural description 
10451 ;;    of the pipeline and makes interface of the hazard recognizer simpler than the 
10452 ;;    old function unit based model.
10453 ;; 4. The DFA model is richer and is a part of greater overall framework of RCSP.
10454
10455
10456 ;; Two automata are defined to reduce number of states
10457 ;; which a single large automaton will have.(Factoring)
10458
10459 (define_automaton "inst_pipeline,fpu_pipe")
10460
10461 ;; This unit is basically the decode unit of the processor.
10462 ;; Since SH4 is a dual issue machine,it is as if there are two 
10463 ;; units so that any insn can be processed by either one
10464 ;; of the decoding unit.
10465
10466 (define_cpu_unit "pipe_01,pipe_02" "inst_pipeline")
10467
10468
10469 ;; The fixed point arithmetic calculator(?? EX Unit).
10470
10471 (define_cpu_unit  "int" "inst_pipeline")
10472
10473 ;; f1_1 and f1_2 are floating point units.Actually there is
10474 ;; a f1 unit which can overlap with other f1 unit but
10475 ;; not another F1 unit.It is as though there were two
10476 ;; f1 units.
10477
10478 (define_cpu_unit "f1_1,f1_2" "fpu_pipe")
10479
10480 ;; The floating point units (except FS - F2 always precedes it.)
10481
10482 (define_cpu_unit "F0,F1,F2,F3" "fpu_pipe")
10483
10484 ;; This is basically the MA unit of SH4
10485 ;; used in LOAD/STORE pipeline.
10486
10487 (define_cpu_unit "memory" "inst_pipeline")
10488
10489 ;; However, there are LS group insns that don't use it, even ones that
10490 ;; complete in 0 cycles.  So we use an extra unit for the issue of LS insns.
10491 (define_cpu_unit "load_store" "inst_pipeline")
10492
10493 ;; The address calculator used for branch instructions.
10494 ;; This will be reserved after "issue" of branch instructions
10495 ;; and this is to make sure that no two branch instructions 
10496 ;; can be issued in parallel. 
10497
10498 (define_cpu_unit "pcr_addrcalc" "inst_pipeline")
10499
10500 ;; ----------------------------------------------------
10501 ;; This reservation is to simplify the dual issue description.
10502
10503 (define_reservation  "issue"  "pipe_01|pipe_02")
10504
10505 ;; This is to express the locking of D stage.
10506 ;; Note that the issue of a CO group insn also effectively locks the D stage.
10507
10508 (define_reservation  "d_lock" "pipe_01+pipe_02")
10509
10510 ;; Every FE instruction but fipr / ftrv starts with issue and this.
10511 (define_reservation "F01" "F0+F1")
10512
10513 ;; This is to simplify description where F1,F2,FS
10514 ;; are used simultaneously.
10515
10516 (define_reservation "fpu" "F1+F2")
10517
10518 ;; This is to highlight the fact that f1 
10519 ;; cannot overlap with F1.
10520
10521 (exclusion_set  "f1_1,f1_2" "F1")
10522
10523 (define_insn_reservation "nil" 0 (eq_attr "type" "nil") "nothing")
10524
10525 ;; Although reg moves have a latency of zero 
10526 ;; we need to highlight that they use D stage
10527 ;; for one cycle.
10528
10529 ;; Group:       MT
10530
10531 (define_insn_reservation "reg_mov" 0
10532   (and (eq_attr "pipe_model" "sh4")
10533        (eq_attr "type" "move"))
10534   "issue")
10535
10536 ;; Group:       LS
10537
10538 (define_insn_reservation "freg_mov" 0
10539   (and (eq_attr "pipe_model" "sh4")
10540        (eq_attr "type" "fmove"))
10541   "issue+load_store")
10542
10543 ;; We don't model all pipeline stages; we model the issue ('D') stage
10544 ;; inasmuch as we allow only two instructions to issue simultanously,
10545 ;; and CO instructions prevent any simultanous issue of another instruction.
10546 ;; (This uses pipe_01 and pipe_02).
10547 ;; Double issue of EX insns is prevented by using the int unit in the EX stage.
10548 ;; Double issue of EX / BR insns is prevented by using the int unit /
10549 ;; pcr_addrcalc unit in the EX stage.
10550 ;; Double issue of BR / LS instructions is prevented by using the
10551 ;; pcr_addrcalc / load_store unit in the issue cycle.
10552 ;; Double issue of FE instructions is prevented by using F0 in the first
10553 ;; pipeline stage after the first D stage.
10554 ;; There is no need to describe the [ES]X / [MN]A / S stages after a D stage
10555 ;; (except in the cases outlined above), nor to describe the FS stage after
10556 ;; the F2 stage.
10557
10558 ;; Other MT  group intructions(1 step operations)
10559 ;; Group:       MT
10560 ;; Latency:     1
10561 ;; Issue Rate:  1
10562
10563 (define_insn_reservation "mt" 1
10564   (and (eq_attr "pipe_model" "sh4")
10565        (eq_attr "type" "mt_group"))
10566   "issue")
10567
10568 ;; Fixed Point Arithmetic Instructions(1 step operations)
10569 ;; Group:       EX
10570 ;; Latency:     1
10571 ;; Issue Rate:  1
10572
10573 (define_insn_reservation "sh4_simple_arith" 1 
10574   (and (eq_attr "pipe_model" "sh4")
10575        (eq_attr "insn_class" "ex_group"))
10576   "issue,int")
10577
10578 ;; Load and store instructions have no alignment peculiarities for the SH4,
10579 ;; but they use the load-store unit, which they share with the fmove type
10580 ;; insns (fldi[01]; fmov frn,frm; flds; fsts; fabs; fneg) .
10581 ;; Loads have a latency of two.
10582 ;; However, call insns can only paired with a preceding insn, and have
10583 ;; a delay slot, so that we want two more insns to be scheduled between the
10584 ;; load of the function address and the call.  This is equivalent to a
10585 ;; latency of three.
10586 ;; ADJUST_COST can only properly handle reductions of the cost, so we
10587 ;; use a latency of three here, which gets multiplied by 10 to yield 30.
10588 ;; We only do this for SImode loads of general registers, to make the work
10589 ;; for ADJUST_COST easier.
10590
10591 ;; Load Store instructions. (MOV.[BWL]@(d,GBR)
10592 ;; Group:       LS
10593 ;; Latency:     2
10594 ;; Issue Rate:  1
10595
10596 (define_insn_reservation "sh4_load" 2
10597   (and (eq_attr "pipe_model" "sh4")
10598        (eq_attr "type" "load,pcload"))
10599   "issue+load_store,nothing,memory")
10600
10601 ;; calls / sfuncs need an extra instruction for their delay slot.
10602 ;; Moreover, estimating the latency for SImode loads as 3 will also allow
10603 ;; adjust_cost to meaningfully bump it back up to 3 if they load the shift
10604 ;; count of a dynamic shift.
10605 (define_insn_reservation "sh4_load_si" 3
10606   (and (eq_attr "pipe_model" "sh4")
10607        (eq_attr "type" "load_si,pcload_si"))
10608   "issue+load_store,nothing,memory")
10609
10610 ;; (define_bypass 2 "sh4_load_si" "!sh4_call")
10611
10612 ;; The load latency is upped to three higher if the dependent insn does
10613 ;; double precision computation.  We want the 'default' latency to reflect
10614 ;; that increased latency because otherwise the insn priorities won't
10615 ;; allow proper scheduling.
10616 (define_insn_reservation "sh4_fload" 3
10617   (and (eq_attr "pipe_model" "sh4")
10618        (eq_attr "type" "fload,pcfload"))
10619   "issue+load_store,nothing,memory")
10620
10621 ;; (define_bypass 2 "sh4_fload" "!")
10622
10623 (define_insn_reservation "sh4_store" 1
10624   (and (eq_attr "pipe_model" "sh4")
10625        (eq_attr "type" "store"))
10626   "issue+load_store,nothing,memory")
10627
10628 ;; Load Store instructions.
10629 ;; Group:       LS
10630 ;; Latency:     1
10631 ;; Issue Rate:  1
10632
10633 (define_insn_reservation "sh4_gp_fpul" 1
10634   (and (eq_attr "pipe_model" "sh4")
10635        (eq_attr "type" "gp_fpul"))
10636   "issue+load_store")
10637
10638 ;; Load Store instructions.
10639 ;; Group:       LS
10640 ;; Latency:     3
10641 ;; Issue Rate:  1
10642
10643 (define_insn_reservation "sh4_fpul_gp" 3
10644   (and (eq_attr "pipe_model" "sh4")
10645        (eq_attr "type" "fpul_gp"))
10646   "issue+load_store")
10647
10648 ;; Branch (BF,BF/S,BT,BT/S,BRA)
10649 ;; Group:       BR
10650 ;; Latency when taken:  2 (or 1)
10651 ;; Issue Rate:  1
10652 ;; The latency is 1 when displacement is 0.
10653 ;; We can't really do much with the latency, even if we could express it,
10654 ;; but the pairing restrictions are useful to take into account.
10655 ;; ??? If the branch is likely, we might want to fill the delay slot;
10656 ;; if the branch is likely, but not very likely, should we pretend to use
10657 ;; a resource that CO instructions use, to get a pairable delay slot insn?
10658
10659 (define_insn_reservation "sh4_branch"  1
10660   (and (eq_attr "pipe_model" "sh4")
10661        (eq_attr "type" "cbranch,jump"))
10662   "issue+pcr_addrcalc")
10663
10664 ;; Branch Far (JMP,RTS,BRAF)
10665 ;; Group:       CO
10666 ;; Latency:     3
10667 ;; Issue Rate:  2
10668 ;; ??? Scheduling happens before branch shortening, and hence jmp and braf
10669 ;; can't be distinguished from bra for the "jump" pattern.
10670
10671 (define_insn_reservation "sh4_return" 3
10672   (and (eq_attr "pipe_model" "sh4")
10673        (eq_attr "type" "return,jump_ind"))
10674          "d_lock*2")
10675
10676 ;; RTE
10677 ;; Group:       CO
10678 ;; Latency:     5
10679 ;; Issue Rate:  5
10680 ;; this instruction can be executed in any of the pipelines 
10681 ;; and blocks the pipeline for next 4 stages.
10682
10683 (define_insn_reservation "sh4_return_from_exp" 5
10684   (and (eq_attr "pipe_model" "sh4")
10685        (eq_attr "type" "rte"))
10686   "d_lock*5")
10687
10688 ;; OCBP, OCBWB
10689 ;; Group:       CO
10690 ;; Latency:     1-5
10691 ;; Issue Rate:  1
10692
10693 ;; cwb is used for the sequence ocbwb @%0; extu.w %0,%2; or %1,%2; mov.l %0,@%2
10694 ;; ocbwb on its own would be "d_lock,nothing,memory*5"
10695 (define_insn_reservation "ocbwb"  6
10696   (and (eq_attr "pipe_model" "sh4")
10697        (eq_attr "type" "cwb"))
10698   "d_lock*2,(d_lock+memory)*3,issue+load_store+memory,memory*2")
10699                 
10700 ;; LDS to PR,JSR
10701 ;; Group:       CO
10702 ;; Latency:     3
10703 ;; Issue Rate:  2
10704 ;; The SX stage is blocked for last 2 cycles.
10705 ;; OTOH, the only time that has an effect for insns generated by the compiler
10706 ;; is when lds to PR is followed by sts from PR - and that is highly unlikely -
10707 ;; or when we are doing a function call - and we don't do inter-function
10708 ;; scheduling.  For the function call case, it's really best that we end with
10709 ;; something that models an rts.
10710
10711 (define_insn_reservation "sh4_lds_to_pr" 3 
10712   (and (eq_attr "pipe_model" "sh4")
10713        (eq_attr "type" "prset") )
10714   "d_lock*2")
10715
10716 ;; calls introduce a longisch delay that is likely to flush the pipelines
10717 ;; of the caller's instructions.  Ordinary functions tend to end with a
10718 ;; load to restore a register (in the delay slot of rts), while sfuncs
10719 ;; tend to end with an EX or MT insn.  But that is not actually relevant,
10720 ;; since there are no instructions that contend for memory access early.
10721 ;; We could, of course, provide exact scheduling information for specific
10722 ;; sfuncs, if that should prove useful.
10723
10724 (define_insn_reservation "sh4_call" 16 
10725   (and (eq_attr "pipe_model" "sh4")
10726        (eq_attr "type" "call,sfunc"))
10727   "d_lock*16")
10728
10729 ;; LDS.L to PR 
10730 ;; Group:       CO
10731 ;; Latency:     3
10732 ;; Issue Rate:  2
10733 ;; The SX unit is blocked for last 2 cycles.
10734  
10735 (define_insn_reservation "ldsmem_to_pr"  3
10736   (and (eq_attr "pipe_model" "sh4")
10737        (eq_attr "type" "pload"))
10738   "d_lock*2")
10739
10740 ;; STS from PR
10741 ;; Group:       CO
10742 ;; Latency:     2
10743 ;; Issue Rate:  2
10744 ;; The SX unit in second and third cycles.
10745
10746 (define_insn_reservation "sts_from_pr" 2
10747   (and (eq_attr "pipe_model" "sh4")
10748        (eq_attr "type" "prget"))
10749   "d_lock*2")
10750
10751 ;; STS.L from PR
10752 ;; Group:       CO
10753 ;; Latency:     2
10754 ;; Issue Rate:  2
10755
10756 (define_insn_reservation "sh4_prstore_mem" 2 
10757   (and (eq_attr "pipe_model" "sh4")
10758        (eq_attr "type" "pstore"))
10759   "d_lock*2,nothing,memory")
10760
10761 ;; LDS to FPSCR
10762 ;; Group:       CO
10763 ;; Latency:     4
10764 ;; Issue Rate:  1
10765 ;; F1 is blocked for last three cycles. 
10766
10767 (define_insn_reservation "fpscr_load" 4
10768   (and (eq_attr "pipe_model" "sh4")
10769        (eq_attr "type" "gp_fpscr"))
10770   "d_lock,nothing,F1*3")
10771
10772 ;; LDS.L to FPSCR
10773 ;; Group:       CO
10774 ;; Latency:     1 / 4
10775 ;; Latency to update Rn is 1 and latency to update FPSCR is 4
10776 ;; Issue Rate:  1
10777 ;; F1 is blocked for last three cycles.
10778
10779 (define_insn_reservation "fpscr_load_mem" 4
10780   (and (eq_attr "pipe_model" "sh4")
10781        (eq_attr "type"  "mem_fpscr"))
10782   "d_lock,nothing,(F1+memory),F1*2")
10783
10784 \f
10785 ;; Fixed point multiplication (DMULS.L DMULU.L MUL.L MULS.W,MULU.W)
10786 ;; Group:       CO
10787 ;; Latency:     4 / 4
10788 ;; Issue Rate:  1
10789
10790 (define_insn_reservation "multi" 4
10791   (and (eq_attr "pipe_model" "sh4")
10792        (eq_attr "type" "smpy,dmpy"))
10793   "d_lock,(d_lock+f1_1),(f1_1|f1_2)*3,F2")
10794
10795 ;; Fixed STS from MACL / MACH
10796 ;; Group:       CO
10797 ;; Latency:     3
10798 ;; Issue Rate:  1
10799
10800 (define_insn_reservation "sh4_mac_gp" 3
10801   (and (eq_attr "pipe_model" "sh4")
10802        (eq_attr "type" "mac_gp"))
10803   "d_lock")
10804
10805
10806 ;; Single precision floating point computation FCMP/EQ,
10807 ;; FCMP/GT, FADD, FLOAT, FMAC, FMUL, FSUB, FTRC, FRVHG, FSCHG
10808 ;; Group:       FE
10809 ;; Latency:     3/4
10810 ;; Issue Rate:  1
10811
10812 (define_insn_reservation "fp_arith"  3
10813   (and (eq_attr "pipe_model" "sh4")
10814        (eq_attr "type" "fp"))
10815   "issue,F01,F2")
10816
10817 (define_insn_reservation "fp_arith_ftrc"  3
10818   (and (eq_attr "pipe_model" "sh4")
10819        (eq_attr "type" "ftrc_s"))
10820   "issue,F01,F2")
10821
10822 (define_bypass 1 "fp_arith_ftrc" "sh4_fpul_gp")
10823
10824 ;; Single Precision FDIV/SQRT
10825 ;; Group:       FE
10826 ;; Latency:     12/13 (FDIV); 11/12 (FSQRT)
10827 ;; Issue Rate:  1
10828 ;; We describe fdiv here; fsqrt is actually one cycle faster.
10829
10830 (define_insn_reservation "fp_div" 12
10831   (and (eq_attr "pipe_model" "sh4")
10832        (eq_attr "type" "fdiv"))
10833   "issue,F01+F3,F2+F3,F3*7,F1+F3,F2")
10834
10835 ;; Double Precision floating point computation
10836 ;; (FCNVDS, FCNVSD, FLOAT, FTRC)
10837 ;; Group:       FE
10838 ;; Latency:     (3,4)/5
10839 ;; Issue Rate:  1
10840
10841 (define_insn_reservation "dp_float" 4
10842   (and (eq_attr "pipe_model" "sh4")
10843        (eq_attr "type" "dfp_conv"))
10844   "issue,F01,F1+F2,F2")
10845
10846 ;; Double-precision floating-point (FADD,FMUL,FSUB) 
10847 ;; Group:       FE
10848 ;; Latency:     (7,8)/9
10849 ;; Issue Rate:  1
10850
10851 (define_insn_reservation "fp_double_arith" 8
10852   (and (eq_attr "pipe_model" "sh4")
10853        (eq_attr "type" "dfp_arith"))
10854   "issue,F01,F1+F2,fpu*4,F2")
10855
10856 ;; Double-precision FCMP (FCMP/EQ,FCMP/GT) 
10857 ;; Group:       CO
10858 ;; Latency:     3/5
10859 ;; Issue Rate:  2
10860
10861 (define_insn_reservation "fp_double_cmp" 3 
10862   (and (eq_attr "pipe_model" "sh4")
10863        (eq_attr "type" "dfp_cmp"))
10864   "d_lock,(d_lock+F01),F1+F2,F2")
10865
10866 ;; Double precision FDIV/SQRT
10867 ;; Group:       FE
10868 ;; Latency:     (24,25)/26
10869 ;; Issue Rate:  1
10870
10871 (define_insn_reservation "dp_div" 25
10872   (and (eq_attr "pipe_model" "sh4")
10873        (eq_attr "type" "dfdiv"))
10874   "issue,F01+F3,F1+F2+F3,F2+F3,F3*16,F1+F3,(fpu+F3)*2,F2")
10875
10876
10877 ;; Use the branch-not-taken case to model arith3 insns.  For the branch taken
10878 ;; case, we'd get a d_lock instead of issue at the end.
10879 (define_insn_reservation "arith3" 3
10880   (and (eq_attr "pipe_model" "sh4")
10881        (eq_attr "type" "arith3"))
10882   "issue,d_lock+pcr_addrcalc,issue")
10883
10884 ;; arith3b insns schedule the same no matter if the branch is taken or not.
10885 (define_insn_reservation "arith3b" 2
10886   (and (eq_attr "pipe_model" "sh4")
10887        (eq_attr "type" "arith3"))
10888   "issue,d_lock+pcr_addrcalc")