OSDN Git Service

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