OSDN Git Service

* config/arm/arm.h (ARM_EABI_CTORS_SECTION_OP): Do not define if a
[pf3gnuchains/gcc-fork.git] / gcc / config / sh / sh.md
1 ;;- Machine description for Renesas / SuperH SH.
2 ;;  Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 ;;  2003, 2004, 2005 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 GCC.
8
9 ;; GCC 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 ;; GCC 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 GCC; 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   (UNSPEC_EH_RETURN     19)
139   (UNSPEC_TLSGD         20)
140   (UNSPEC_TLSLDM        21)
141   (UNSPEC_TLSIE         22)
142   (UNSPEC_DTPOFF        23)
143   (UNSPEC_GOTTPOFF      24)
144   (UNSPEC_TPOFF         25)
145   (UNSPEC_RA            26)
146
147   ;; These are used with unspec_volatile.
148   (UNSPECV_BLOCKAGE     0)
149   (UNSPECV_ALIGN        1)
150   (UNSPECV_CONST2       2)
151   (UNSPECV_CONST4       4)
152   (UNSPECV_CONST8       6)
153   (UNSPECV_WINDOW_END   10)
154   (UNSPECV_CONST_END    11)
155 ])
156
157 ;; -------------------------------------------------------------------------
158 ;; Attributes
159 ;; -------------------------------------------------------------------------
160
161 ;; Target CPU.
162
163 (define_attr "cpu"
164  "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
165   (const (symbol_ref "sh_cpu_attr")))
166
167 (define_attr "endian" "big,little"
168  (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
169                       (const_string "little") (const_string "big"))))
170
171 ;; Indicate if the default fpu mode is single precision.
172 (define_attr "fpu_single" "yes,no"
173   (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
174                          (const_string "yes") (const_string "no"))))
175
176 (define_attr "fmovd" "yes,no"
177   (const (if_then_else (symbol_ref "TARGET_FMOVD")
178                        (const_string "yes") (const_string "no"))))
179 ;; pipeline model
180 (define_attr "pipe_model" "sh1,sh4,sh5media"
181   (const
182    (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
183           (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
184          (const_string "sh1"))))
185
186 ;; cbranch      conditional branch instructions
187 ;; jump         unconditional jumps
188 ;; arith        ordinary arithmetic
189 ;; arith3       a compound insn that behaves similarly to a sequence of
190 ;;              three insns of type arith
191 ;; arith3b      like above, but might end with a redirected branch
192 ;; load         from memory
193 ;; load_si      Likewise, SImode variant for general register.
194 ;; fload        Likewise, but load to fp register.
195 ;; store        to memory
196 ;; move         general purpose register to register
197 ;; mt_group     other sh4 mt instructions
198 ;; fmove        register to register, floating point
199 ;; smpy         word precision integer multiply
200 ;; dmpy         longword or doublelongword precision integer multiply
201 ;; return       rts
202 ;; pload        load of pr reg, which can't be put into delay slot of rts
203 ;; prset        copy register to pr reg, ditto
204 ;; pstore       store of pr reg, which can't be put into delay slot of jsr
205 ;; prget        copy pr to register, ditto
206 ;; pcload       pc relative load of constant value
207 ;; pcfload      Likewise, but load to fp register.
208 ;; pcload_si    Likewise, SImode variant for general register.
209 ;; rte          return from exception
210 ;; sfunc        special function call with known used registers
211 ;; call         function call
212 ;; fp           floating point
213 ;; fdiv         floating point divide (or square root)
214 ;; gp_fpul      move from general purpose register to fpul
215 ;; fpul_gp      move from fpul to general purpose register
216 ;; mac_gp       move from mac[lh] to general purpose register
217 ;; dfp_arith, dfp_cmp,dfp_conv
218 ;; ftrc_s       fix_truncsfsi2_i4
219 ;; dfdiv        double precision floating point divide (or square root)
220 ;; cwb          ic_invalidate_line_i
221 ;; movua        SH4a unaligned load
222 ;; fsrra        square root reciprocal approximate
223 ;; fsca         sine and cosine approximate
224 ;; tls_load     load TLS related address
225 ;; arith_media  SHmedia arithmetic, logical, and shift instructions
226 ;; cbranch_media SHmedia conditional branch instructions
227 ;; cmp_media    SHmedia compare instructions
228 ;; dfdiv_media  SHmedia double precision divide and square root
229 ;; dfmul_media  SHmedia double precision multiply instruction
230 ;; dfparith_media SHmedia double precision floating point arithmetic
231 ;; dfpconv_media SHmedia double precision floating point conversions
232 ;; dmpy_media   SHmedia longword multiply
233 ;; fcmp_media   SHmedia floating point compare instructions
234 ;; fdiv_media   SHmedia single precision divide and square root
235 ;; fload_media  SHmedia floating point register load instructions
236 ;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
237 ;; fparith_media SHmedia single precision floating point arithmetic
238 ;; fpconv_media SHmedia single precision floating point conversions
239 ;; fstore_media SHmedia floating point register store instructions
240 ;; gettr_media  SHmedia gettr instruction
241 ;; invalidate_line_media SHmedia invalidate_line sequence
242 ;; jump_media   SHmedia unconditional branch instructions
243 ;; load_media   SHmedia general register load instructions
244 ;; pt_media     SHmedia pt instruction (expanded by assembler)
245 ;; ptabs_media  SHmedia ptabs instruction
246 ;; store_media  SHmedia general register store instructions
247 ;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
248 ;; mac_media    SHmedia mac-style fixed point operations
249 ;; d2mpy_media  SHmedia: two 32 bit integer multiplies
250 ;; atrans       SHmedia approximate transcendental functions
251 ;; ustore_media SHmedia unaligned stores
252 ;; nil          no-op move, will be deleted.
253
254 (define_attr "type"
255  "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,movua,fsrra,fsca,tls_load,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"
256   (const_string "other"))
257
258 ;; We define a new attribute namely "insn_class".We use
259 ;; this for the DFA based pipeline description.
260 ;;
261 ;; mt_group      SH4 "mt" group instructions.
262 ;;
263 ;; ex_group      SH4 "ex" group instructions.
264 ;;
265 ;; ls_group      SH4 "ls" group instructions.
266 ;;
267
268 (define_attr "insn_class"
269   "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
270   (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
271          (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
272          (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
273          (eq_attr "type" "cbranch,jump") (const_string "br_group")
274          (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
275            (const_string "fe_group")
276          (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")]
277         (const_string "none")))
278 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
279 ;; so these do not belong in an insn group, although they are modeled
280 ;; with their own define_insn_reservations.
281
282 ;; Indicate what precision must be selected in fpscr for this insn, if any.
283
284 (define_attr "fp_mode" "single,double,none" (const_string "none"))
285
286 ;; Indicate if the fpu mode is set by this instruction
287 ;; "unknown" must have the value as "none" in fp_mode, and means
288 ;; that the instruction/abi has left the processor in an unknown
289 ;; state.
290 ;; "none" means that nothing has changed and no mode is set.
291 ;; This attribute is only used for the Renesas ABI.
292 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
293
294 ; If a conditional branch destination is within -252..258 bytes away
295 ; from the instruction it can be 2 bytes long.  Something in the
296 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
297 ; branches are initially assumed to be 16 bytes long.
298 ; In machine_dependent_reorg, we split all branches that are longer than
299 ; 2 bytes.
300
301 ;; The maximum range used for SImode constant pool entries is 1018.  A final
302 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
303 ;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
304 ;; instruction around the pool table, 2 bytes of alignment before the table,
305 ;; and 30 bytes of alignment after the table.  That gives a maximum total
306 ;; pool size of 1058 bytes.
307 ;; Worst case code/pool content size ratio is 1:2 (using asms).
308 ;; Thus, in the worst case, there is one instruction in front of a maximum
309 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
310 ;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
311 ;; If we have a forward branch, the initial table will be put after the
312 ;; unconditional branch.
313 ;;
314 ;; ??? We could do much better by keeping track of the actual pcloads within
315 ;; the branch range and in the pcload range in front of the branch range.
316
317 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
318 ;; inside an le.
319 (define_attr "short_cbranch_p" "no,yes"
320   (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
321          (const_string "no")
322          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
323          (const_string "yes")
324          (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
325          (const_string "no")
326          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
327          (const_string "yes")
328          ] (const_string "no")))
329
330 (define_attr "med_branch_p" "no,yes"
331   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
332               (const_int 1988))
333          (const_string "yes")
334          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
335          (const_string "no")
336          (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
337               (const_int 8186))
338          (const_string "yes")
339          ] (const_string "no")))
340
341 (define_attr "med_cbranch_p" "no,yes"
342   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
343               (const_int 1986))
344          (const_string "yes")
345          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
346          (const_string "no")
347          (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
348                (const_int 8184))
349          (const_string "yes")
350          ] (const_string "no")))
351
352 (define_attr "braf_branch_p" "no,yes"
353   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
354          (const_string "no")
355          (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
356               (const_int 20660))
357          (const_string "yes")
358          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
359          (const_string "no")
360          (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
361               (const_int 65530))
362          (const_string "yes")
363          ] (const_string "no")))
364
365 (define_attr "braf_cbranch_p" "no,yes"
366   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
367          (const_string "no")
368          (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
369               (const_int 20658))
370          (const_string "yes")
371          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
372          (const_string "no")
373          (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
374               (const_int 65528))
375          (const_string "yes")
376          ] (const_string "no")))
377
378 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
379 ; For wider ranges, we need a combination of a code and a data part.
380 ; If we can get a scratch register for a long range jump, the code
381 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
382 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
383 ; long; otherwise, it must be 6 bytes long.
384
385 ; All other instructions are two bytes long by default.
386
387 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
388 ;; but getattrtab doesn't understand this.
389 (define_attr "length" ""
390   (cond [(eq_attr "type" "cbranch")
391          (cond [(eq_attr "short_cbranch_p" "yes")
392                 (const_int 2)
393                 (eq_attr "med_cbranch_p" "yes")
394                 (const_int 6)
395                 (eq_attr "braf_cbranch_p" "yes")
396                 (const_int 12)
397 ;; ??? using pc is not computed transitively.
398                 (ne (match_dup 0) (match_dup 0))
399                 (const_int 14)
400                 (ne (symbol_ref ("flag_pic")) (const_int 0))
401                 (const_int 24)
402                 ] (const_int 16))
403          (eq_attr "type" "jump")
404          (cond [(eq_attr "med_branch_p" "yes")
405                 (const_int 2)
406                 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
407                          (symbol_ref "INSN"))
408                      (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
409                          (symbol_ref "code_for_indirect_jump_scratch")))
410                 (cond [(eq_attr "braf_branch_p" "yes")
411                        (const_int 6)
412                        (eq (symbol_ref "flag_pic") (const_int 0))
413                        (const_int 10)
414                        (ne (symbol_ref "TARGET_SH2") (const_int 0))
415                        (const_int 10)] (const_int 18))
416                 (eq_attr "braf_branch_p" "yes")
417                 (const_int 10)
418 ;; ??? using pc is not computed transitively.
419                 (ne (match_dup 0) (match_dup 0))
420                 (const_int 12)
421                 (ne (symbol_ref ("flag_pic")) (const_int 0))
422                 (const_int 22)
423                 ] (const_int 14))
424          (eq_attr "type" "pt_media")
425          (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
426                        (const_int 20) (const_int 12))
427          ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
428                          (const_int 4)
429                          (const_int 2))))
430
431 ;; DFA descriptions for the pipelines
432
433 (include "sh1.md")
434 (include "shmedia.md")
435 (include "sh4.md")
436
437 ;; Definitions for filling delay slots
438
439 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
440
441 ;; ??? This should be (nil) instead of (const_int 0)
442 (define_attr "hit_stack" "yes,no"
443         (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
444                    (const_int 0))
445                (const_string "no")]
446               (const_string "yes")))
447
448 (define_attr "interrupt_function" "no,yes"
449   (const (symbol_ref "current_function_interrupt")))
450
451 (define_attr "in_delay_slot" "yes,no"
452   (cond [(eq_attr "type" "cbranch") (const_string "no")
453          (eq_attr "type" "pcload,pcload_si") (const_string "no")
454          (eq_attr "needs_delay_slot" "yes") (const_string "no")
455          (eq_attr "length" "2") (const_string "yes")
456          ] (const_string "no")))
457
458 (define_attr "cond_delay_slot" "yes,no"
459   (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
460          ] (const_string "no")))
461
462 (define_attr "is_sfunc" ""
463   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
464
465 (define_attr "is_mac_media" ""
466   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
467
468 (define_attr "branch_zero" "yes,no"
469   (cond [(eq_attr "type" "!cbranch") (const_string "no")
470          (ne (symbol_ref "(next_active_insn (insn)\
471                            == (prev_active_insn\
472                                (XEXP (SET_SRC (PATTERN (insn)), 1))))\
473                           && get_attr_length (next_active_insn (insn)) == 2")
474              (const_int 0))
475          (const_string "yes")]
476         (const_string "no")))
477
478 ;; SH4 Double-precision computation with double-precision result -
479 ;; the two halves are ready at different times.
480 (define_attr "dfp_comp" "yes,no"
481   (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
482         (const_string "no")))
483
484 ;; Insns for which the latency of a preceding fp insn is decreased by one.
485 (define_attr "late_fp_use" "yes,no" (const_string "no"))
486 ;; And feeding insns for which this relevant.
487 (define_attr "any_fp_comp" "yes,no"
488   (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
489          (const_string "yes")]
490         (const_string "no")))
491
492 (define_attr "any_int_load" "yes,no"
493   (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
494          (const_string "yes")]
495         (const_string "no")))
496
497 (define_delay
498   (eq_attr "needs_delay_slot" "yes")
499   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
500
501 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
502 ;; and thus we can't put a pop instruction in its delay slot.
503 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
504 ;; instruction can go in the delay slot.
505
506 ;; Since a normal return (rts) implicitly uses the PR register,
507 ;; we can't allow PR register loads in an rts delay slot.
508
509 (define_delay
510   (eq_attr "type" "return")
511   [(and (eq_attr "in_delay_slot" "yes")
512         (ior (and (eq_attr "interrupt_function" "no")
513                   (eq_attr "type" "!pload,prset"))
514              (and (eq_attr "interrupt_function" "yes")
515                   (ior
516                    (ne (symbol_ref "TARGET_SH3") (const_int 0))
517                    (eq_attr "hit_stack" "no"))))) (nil) (nil)])
518
519 ;; Since a call implicitly uses the PR register, we can't allow
520 ;; a PR register store in a jsr delay slot.
521
522 (define_delay
523   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
524   [(and (eq_attr "in_delay_slot" "yes")
525         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
526
527 ;; Say that we have annulled true branches, since this gives smaller and
528 ;; faster code when branches are predicted as not taken.
529
530 ;; ??? The non-annulled condition should really be "in_delay_slot",
531 ;; but insns that can be filled in non-annulled get priority over insns
532 ;; that can only be filled in anulled.
533
534 (define_delay
535   (and (eq_attr "type" "cbranch")
536        (ne (symbol_ref "TARGET_SH2") (const_int 0)))
537   ;; SH2e has a hardware bug that pretty much prohibits the use of
538   ;; annuled delay slots.
539   [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
540                                         (not (eq_attr "cpu" "sh2e"))) (nil)])
541 \f
542 ;; -------------------------------------------------------------------------
543 ;; SImode signed integer comparisons
544 ;; -------------------------------------------------------------------------
545
546 (define_insn ""
547   [(set (reg:SI T_REG)
548         (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
549                        (match_operand:SI 1 "arith_operand" "K08,r"))
550                (const_int 0)))]
551   "TARGET_SH1"
552   "tst  %1,%0"
553   [(set_attr "type" "mt_group")])
554
555 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
556 ;; That would still allow reload to create cmpi instructions, but would
557 ;; perhaps allow forcing the constant into a register when that is better.
558 ;; Probably should use r0 for mem/imm compares, but force constant into a
559 ;; register for pseudo/imm compares.
560
561 (define_insn "cmpeqsi_t"
562   [(set (reg:SI T_REG)
563         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
564                (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
565   "TARGET_SH1"
566   "@
567         tst     %0,%0
568         cmp/eq  %1,%0
569         cmp/eq  %1,%0"
570    [(set_attr "type" "mt_group")])
571
572 (define_insn "cmpgtsi_t"
573   [(set (reg:SI T_REG)
574         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
575                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
576   "TARGET_SH1"
577   "@
578         cmp/gt  %1,%0
579         cmp/pl  %0"
580    [(set_attr "type" "mt_group")])
581
582 (define_insn "cmpgesi_t"
583   [(set (reg:SI T_REG)
584         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
585                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
586   "TARGET_SH1"
587   "@
588         cmp/ge  %1,%0
589         cmp/pz  %0"
590    [(set_attr "type" "mt_group")])
591
592 ;; -------------------------------------------------------------------------
593 ;; SImode unsigned integer comparisons
594 ;; -------------------------------------------------------------------------
595
596 (define_insn "cmpgeusi_t"
597   [(set (reg:SI T_REG)
598         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
599                 (match_operand:SI 1 "arith_reg_operand" "r")))]
600   "TARGET_SH1"
601   "cmp/hs       %1,%0"
602    [(set_attr "type" "mt_group")])
603
604 (define_insn "cmpgtusi_t"
605   [(set (reg:SI T_REG)
606         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
607                 (match_operand:SI 1 "arith_reg_operand" "r")))]
608   "TARGET_SH1"
609   "cmp/hi       %1,%0"
610    [(set_attr "type" "mt_group")])
611
612 ;; We save the compare operands in the cmpxx patterns and use them when
613 ;; we generate the branch.
614
615 (define_expand "cmpsi"
616   [(set (reg:SI T_REG)
617         (compare (match_operand:SI 0 "cmpsi_operand" "")
618                  (match_operand:SI 1 "arith_operand" "")))]
619   "TARGET_SH1"
620   "
621 {
622   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
623       && GET_CODE (operands[1]) != CONST_INT)
624     operands[0] = copy_to_mode_reg (SImode, operands[0]);
625   sh_compare_op0 = operands[0];
626   sh_compare_op1 = operands[1];
627   DONE;
628 }")
629 \f
630 ;; -------------------------------------------------------------------------
631 ;; DImode signed integer comparisons
632 ;; -------------------------------------------------------------------------
633
634 ;; ??? Could get better scheduling by splitting the initial test from the
635 ;; rest of the insn after reload.  However, the gain would hardly justify
636 ;; the sh.md size increase necessary to do that.
637
638 (define_insn ""
639   [(set (reg:SI T_REG)
640         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
641                        (match_operand:DI 1 "arith_operand" "r"))
642                (const_int 0)))]
643   "TARGET_SH1"
644   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
645                                  insn, operands);"
646   [(set_attr "length" "6")
647    (set_attr "type" "arith3b")])
648
649 (define_insn "cmpeqdi_t"
650   [(set (reg:SI T_REG)
651         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
652                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
653   "TARGET_SH1"
654   "@
655         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
656         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
657   [(set_attr "length" "6")
658    (set_attr "type" "arith3b")])
659
660 (define_split
661   [(set (reg:SI T_REG)
662         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
663                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
664 ;; If we applied this split when not optimizing, it would only be
665 ;; applied during the machine-dependent reorg, when no new basic blocks
666 ;; may be created.
667   "TARGET_SH1 && reload_completed && optimize"
668   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
669    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
670                            (label_ref (match_dup 6))
671                            (pc)))
672    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
673    (match_dup 6)]
674   "
675 {
676   operands[2]
677     = gen_rtx_REG (SImode,
678                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
679   operands[3]
680     = (operands[1] == const0_rtx
681        ? const0_rtx
682        : gen_rtx_REG (SImode,
683                       true_regnum (operands[1])
684                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
685   operands[4] = gen_lowpart (SImode, operands[0]);
686   operands[5] = gen_lowpart (SImode, operands[1]);
687   operands[6] = gen_label_rtx ();
688 }")
689
690 (define_insn "cmpgtdi_t"
691   [(set (reg:SI T_REG)
692         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
693                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
694   "TARGET_SH2"
695   "@
696         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
697         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
698   [(set_attr "length" "8")
699    (set_attr "type" "arith3")])
700
701 (define_insn "cmpgedi_t"
702   [(set (reg:SI T_REG)
703         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
704                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
705   "TARGET_SH2"
706   "@
707         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
708         cmp/pz\\t%S0"
709   [(set_attr "length" "8,2")
710    (set_attr "type" "arith3,mt_group")])
711 \f
712 ;; -------------------------------------------------------------------------
713 ;; DImode unsigned integer comparisons
714 ;; -------------------------------------------------------------------------
715
716 (define_insn "cmpgeudi_t"
717   [(set (reg:SI T_REG)
718         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
719                 (match_operand:DI 1 "arith_reg_operand" "r")))]
720   "TARGET_SH2"
721   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
722   [(set_attr "length" "8")
723    (set_attr "type" "arith3")])
724
725 (define_insn "cmpgtudi_t"
726   [(set (reg:SI T_REG)
727         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
728                 (match_operand:DI 1 "arith_reg_operand" "r")))]
729   "TARGET_SH2"
730   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
731   [(set_attr "length" "8")
732    (set_attr "type" "arith3")])
733
734 (define_insn "cmpeqdi_media"
735   [(set (match_operand:DI 0 "register_operand" "=r")
736         (eq:DI (match_operand:DI 1 "register_operand" "%r")
737                (match_operand:DI 2 "arith_reg_or_0_operand" "Nr")))]
738   "TARGET_SHMEDIA"
739   "cmpeq        %1, %N2, %0"
740   [(set_attr "type" "cmp_media")])
741
742 (define_insn "cmpgtdi_media"
743   [(set (match_operand:DI 0 "register_operand" "=r")
744         (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
745                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
746   "TARGET_SHMEDIA"
747   "cmpgt        %N1, %N2, %0"
748   [(set_attr "type" "cmp_media")])
749
750 (define_insn "cmpgtudi_media"
751   [(set (match_operand:DI 0 "register_operand" "=r")
752         (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
753                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
754   "TARGET_SHMEDIA"
755   "cmpgtu       %N1, %N2, %0"
756   [(set_attr "type" "cmp_media")])
757
758 ;; We save the compare operands in the cmpxx patterns and use them when
759 ;; we generate the branch.
760
761 (define_expand "cmpdi"
762   [(set (reg:SI T_REG)
763         (compare (match_operand:DI 0 "arith_operand" "")
764                  (match_operand:DI 1 "arith_operand" "")))]
765   "TARGET_SH2 || TARGET_SHMEDIA"
766   "
767 {
768   sh_compare_op0 = operands[0];
769   sh_compare_op1 = operands[1];
770   DONE;
771 }")
772 ;; -------------------------------------------------------------------------
773 ;; Conditional move instructions
774 ;; -------------------------------------------------------------------------
775
776 ;; The insn names may seem reversed, but note that cmveq performs the move
777 ;; if op1 == 0, and cmvne does it if op1 != 0.
778
779 (define_insn "movdicc_false"
780   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
781         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
782                              (const_int 0))
783          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
784          (match_operand:DI 3 "arith_reg_operand" "0")))]
785   "TARGET_SHMEDIA"
786   "cmveq        %1, %N2, %0"
787   [(set_attr "type" "arith_media")])
788
789 (define_insn "movdicc_true"
790   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
791         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
792                              (const_int 0))
793          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
794          (match_operand:DI 3 "arith_reg_operand" "0")))]
795   "TARGET_SHMEDIA"
796   "cmvne        %1, %N2, %0"
797   [(set_attr "type" "arith_media")])
798
799 (define_expand "movdicc"
800   [(set (match_operand:DI 0 "register_operand" "")
801         (if_then_else:DI (match_operand 1 "comparison_operator" "")
802                          (match_operand:DI 2 "register_operand" "")
803                          (match_operand:DI 3 "register_operand" "")))]
804   "TARGET_SHMEDIA"
805   "
806 {
807   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
808       && GET_MODE (sh_compare_op0) == DImode
809       && sh_compare_op1 == const0_rtx)
810     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
811                                   sh_compare_op0, sh_compare_op1);
812   else
813     {
814       rtx tmp;
815
816       if (no_new_pseudos)
817         FAIL;
818
819       tmp = gen_reg_rtx (DImode);
820
821       switch (GET_CODE (operands[1]))
822         {
823         case EQ:
824           emit_insn (gen_seq (tmp));
825           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
826           break;
827
828         case NE:
829           emit_insn (gen_seq (tmp));
830           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
831           break;
832
833         case GT:
834           emit_insn (gen_sgt (tmp));
835           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
836           break;
837
838         case LT:
839           emit_insn (gen_slt (tmp));
840           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
841           break;
842
843         case GE:
844           emit_insn (gen_slt (tmp));
845           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
846           break;
847
848         case LE:
849           emit_insn (gen_sgt (tmp));
850           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
851           break;
852
853         case GTU:
854           emit_insn (gen_sgtu (tmp));
855           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
856           break;
857
858         case LTU:
859           emit_insn (gen_sltu (tmp));
860           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
861           break;
862
863         case GEU:
864           emit_insn (gen_sltu (tmp));
865           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
866           break;
867
868         case LEU:
869           emit_insn (gen_sgtu (tmp));
870           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
871           break;
872
873         case UNORDERED:
874           emit_insn (gen_sunordered (tmp));
875           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
876           break;
877
878         case ORDERED:
879           emit_insn (gen_sunordered (tmp));
880           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
881           break;
882
883         case UNEQ:
884         case UNGE:
885         case UNGT:
886         case UNLE:
887         case UNLT:
888         case LTGT:
889           FAIL;
890
891         default:
892           abort ();
893         }
894     }
895 }")
896 \f
897 ;; -------------------------------------------------------------------------
898 ;; Addition instructions
899 ;; -------------------------------------------------------------------------
900
901 (define_expand "adddi3"
902   [(set (match_operand:DI 0 "arith_reg_operand" "")
903         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
904                  (match_operand:DI 2 "arith_operand" "")))]
905   ""
906   "
907 {
908   if (TARGET_SH1)
909     {
910       if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
911         FAIL;
912       operands[2] = force_reg (DImode, operands[2]);
913       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
914       DONE;
915     }
916 }")
917
918 (define_insn "*adddi3_media"
919   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
920         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
921                  (match_operand:DI 2 "arith_operand" "r,I10")))]
922   "TARGET_SHMEDIA"
923   "@
924         add     %1, %2, %0
925         addi    %1, %2, %0"
926   [(set_attr "type" "arith_media")])
927
928 (define_insn "adddi3z_media"
929   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
930         (zero_extend:DI
931          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
932                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
933   "TARGET_SHMEDIA"
934   "addz.l       %1, %N2, %0"
935   [(set_attr "type" "arith_media")])
936
937 (define_insn "adddi3_compact"
938   [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
939         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
940                  (match_operand:DI 2 "arith_reg_operand" "r")))
941    (clobber (reg:SI T_REG))]
942   "TARGET_SH1"
943   "#"
944   [(set_attr "length" "6")])
945
946 (define_split
947   [(set (match_operand:DI 0 "arith_reg_operand" "")
948         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
949                  (match_operand:DI 2 "arith_reg_operand" "")))
950    (clobber (reg:SI T_REG))]
951   "TARGET_SH1 && reload_completed"
952   [(const_int 0)]
953   "
954 {
955   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
956   high0 = gen_rtx_REG (SImode,
957                        true_regnum (operands[0])
958                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
959   high2 = gen_rtx_REG (SImode,
960                        true_regnum (operands[2])
961                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
962   emit_insn (gen_clrt ());
963   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
964   emit_insn (gen_addc1 (high0, high0, high2));
965   DONE;
966 }")
967
968 (define_insn "addc"
969   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
970         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
971                           (match_operand:SI 2 "arith_reg_operand" "r"))
972                  (reg:SI T_REG)))
973    (set (reg:SI T_REG)
974         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
975   "TARGET_SH1"
976   "addc %2,%0"
977   [(set_attr "type" "arith")])
978
979 (define_insn "addc1"
980   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
981         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
982                           (match_operand:SI 2 "arith_reg_operand" "r"))
983                  (reg:SI T_REG)))
984    (clobber (reg:SI T_REG))]
985   "TARGET_SH1"
986   "addc %2,%0"
987   [(set_attr "type" "arith")])
988
989 (define_expand "addsi3"
990   [(set (match_operand:SI 0 "arith_reg_operand" "")
991         (plus:SI (match_operand:SI 1 "arith_operand" "")
992                  (match_operand:SI 2 "arith_operand" "")))]
993   ""
994   "
995 {
996   if (TARGET_SHMEDIA)
997     operands[1] = force_reg (SImode, operands[1]);
998 }")
999
1000 (define_insn "addsi3_media"
1001   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
1002         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1003                  (match_operand:SI 2 "arith_operand" "r,I10")))]
1004   "TARGET_SHMEDIA"
1005   "@
1006         add.l   %1, %2, %0
1007         addi.l  %1, %2, %0"
1008   [(set_attr "type" "arith_media")])
1009
1010 (define_insn "*addsi3_compact"
1011   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1012         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1013                  (match_operand:SI 2 "arith_operand" "rI08")))]
1014   "TARGET_SH1"
1015   "add  %2,%0"
1016   [(set_attr "type" "arith")])
1017
1018 ;; -------------------------------------------------------------------------
1019 ;; Subtraction instructions
1020 ;; -------------------------------------------------------------------------
1021
1022 (define_expand "subdi3"
1023   [(set (match_operand:DI 0 "arith_reg_operand" "")
1024         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1025                   (match_operand:DI 2 "arith_reg_operand" "")))]
1026   ""
1027   "
1028 {
1029   if (TARGET_SH1)
1030     {
1031       operands[1] = force_reg (DImode, operands[1]);
1032       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1033       DONE;
1034     }
1035 }")
1036
1037 (define_insn "*subdi3_media"
1038   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1039         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1040                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1041   "TARGET_SHMEDIA"
1042   "sub  %N1, %2, %0"
1043   [(set_attr "type" "arith_media")])
1044
1045 (define_insn "subdi3_compact"
1046   [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
1047         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1048                  (match_operand:DI 2 "arith_reg_operand" "r")))
1049    (clobber (reg:SI T_REG))]
1050   "TARGET_SH1"
1051   "#"
1052   [(set_attr "length" "6")])
1053
1054 (define_split
1055   [(set (match_operand:DI 0 "arith_reg_operand" "")
1056         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1057                   (match_operand:DI 2 "arith_reg_operand" "")))
1058    (clobber (reg:SI T_REG))]
1059   "TARGET_SH1 && reload_completed"
1060   [(const_int 0)]
1061   "
1062 {
1063   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1064   high0 = gen_rtx_REG (SImode,
1065                        true_regnum (operands[0])
1066                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1067   high2 = gen_rtx_REG (SImode,
1068                        true_regnum (operands[2])
1069                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1070   emit_insn (gen_clrt ());
1071   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1072   emit_insn (gen_subc1 (high0, high0, high2));
1073   DONE;
1074 }")
1075
1076 (define_insn "subc"
1077   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1078         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1079                             (match_operand:SI 2 "arith_reg_operand" "r"))
1080                   (reg:SI T_REG)))
1081    (set (reg:SI T_REG)
1082         (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1083                           (reg:SI T_REG))
1084                 (match_dup 1)))]
1085   "TARGET_SH1"
1086   "subc %2,%0"
1087   [(set_attr "type" "arith")])
1088
1089 (define_insn "subc1"
1090   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1091         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1092                             (match_operand:SI 2 "arith_reg_operand" "r"))
1093                   (reg:SI T_REG)))
1094    (clobber (reg:SI T_REG))]
1095   "TARGET_SH1"
1096   "subc %2,%0"
1097   [(set_attr "type" "arith")])
1098
1099 (define_insn "*subsi3_internal"
1100   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1101         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1102                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1103   "TARGET_SH1"
1104   "sub  %2,%0"
1105   [(set_attr "type" "arith")])
1106
1107 (define_insn "*subsi3_media"
1108   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1109         (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN")
1110                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1111   "TARGET_SHMEDIA"
1112   "sub.l        %N1, %2, %0"
1113   [(set_attr "type" "arith_media")])
1114
1115 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1116 ;; will sometimes save one instruction.  Otherwise we might get
1117 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1118 ;; are the same.
1119
1120 (define_expand "subsi3"
1121   [(set (match_operand:SI 0 "arith_reg_operand" "")
1122         (minus:SI (match_operand:SI 1 "arith_operand" "")
1123                   (match_operand:SI 2 "arith_reg_operand" "")))]
1124   ""
1125   "
1126 {
1127   if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1128     {
1129       emit_insn (gen_negsi2 (operands[0], operands[2]));
1130       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1131       DONE;
1132     }
1133   if (TARGET_SHMEDIA)
1134     {
1135       if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1136         FAIL;
1137       if (operands[1] != const0_rtx)
1138         operands[1] = force_reg (SImode, operands[1]);
1139     }
1140 }")
1141 \f
1142 ;; -------------------------------------------------------------------------
1143 ;; Division instructions
1144 ;; -------------------------------------------------------------------------
1145
1146 ;; We take advantage of the library routines which don't clobber as many
1147 ;; registers as a normal function call would.
1148
1149 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1150 ;; also has an effect on the register that holds the address of the sfunc.
1151 ;; To make this work, we have an extra dummy insn that shows the use
1152 ;; of this register for reorg.
1153
1154 (define_insn "use_sfunc_addr"
1155   [(set (reg:SI PR_REG)
1156         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1157   "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1158   ""
1159   [(set_attr "length" "0")])
1160
1161 (define_insn "udivsi3_sh2a"
1162   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1163         (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1164                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1165   "TARGET_SH2A"
1166   "divu %2,%1"
1167   [(set_attr "type" "arith")
1168    (set_attr "in_delay_slot" "no")])
1169
1170 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1171 ;; hard register 0.  If we used hard register 0, then the next instruction
1172 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1173 ;; gets allocated to a stack slot that needs its address reloaded, then
1174 ;; there is nothing to prevent reload from using r0 to reload the address.
1175 ;; This reload would clobber the value in r0 we are trying to store.
1176 ;; If we let reload allocate r0, then this problem can never happen.
1177
1178 (define_insn "udivsi3_i1"
1179   [(set (match_operand:SI 0 "register_operand" "=z")
1180         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1181    (clobber (reg:SI T_REG))
1182    (clobber (reg:SI PR_REG))
1183    (clobber (reg:SI R4_REG))
1184    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1185   "TARGET_SH1 && ! TARGET_SH4"
1186   "jsr  @%1%#"
1187   [(set_attr "type" "sfunc")
1188    (set_attr "needs_delay_slot" "yes")])
1189
1190 ; Since shmedia-nofpu code could be linked against shcompact code, and
1191 ; the udivsi3 libcall has the same name, we must consider all registers
1192 ; clobbered that are in the union of the registers clobbered by the
1193 ; shmedia and the shcompact implementation.  Note, if the shcompact
1194 ; implementation actually used shcompact code, we'd need to clobber
1195 ; also r23 and fr23.
1196 (define_insn "udivsi3_i1_media"
1197   [(set (match_operand:SI 0 "register_operand" "=z")
1198         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1199    (clobber (reg:SI T_MEDIA_REG))
1200    (clobber (reg:SI PR_MEDIA_REG))
1201    (clobber (reg:SI R20_REG))
1202    (clobber (reg:SI R21_REG))
1203    (clobber (reg:SI R22_REG))
1204    (clobber (reg:DI TR0_REG))
1205    (clobber (reg:DI TR1_REG))
1206    (clobber (reg:DI TR2_REG))
1207    (use (match_operand:DI 1 "target_operand" "b"))]
1208   "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1209   "blink        %1, r18"
1210   [(set_attr "type" "sfunc")
1211    (set_attr "needs_delay_slot" "yes")])
1212
1213 (define_expand "udivsi3_i4_media"
1214   [(set (match_dup 3)
1215         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1216    (set (match_dup 4)
1217         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1218    (set (match_dup 5) (float:DF (match_dup 3)))
1219    (set (match_dup 6) (float:DF (match_dup 4)))
1220    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1221    (set (match_dup 8) (fix:DI (match_dup 7)))
1222    (set (match_operand:SI 0 "register_operand" "")
1223         (truncate:SI (match_dup 8)))]
1224   "TARGET_SHMEDIA_FPU"
1225   "
1226 {
1227   operands[3] = gen_reg_rtx (DImode);
1228   operands[4] = gen_reg_rtx (DImode);
1229   operands[5] = gen_reg_rtx (DFmode);
1230   operands[6] = gen_reg_rtx (DFmode);
1231   operands[7] = gen_reg_rtx (DFmode);
1232   operands[8] = gen_reg_rtx (DImode);
1233 }")
1234
1235 (define_insn "udivsi3_i4"
1236   [(set (match_operand:SI 0 "register_operand" "=y")
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:DF DR0_REG))
1241    (clobber (reg:DF DR2_REG))
1242    (clobber (reg:DF DR4_REG))
1243    (clobber (reg:SI R0_REG))
1244    (clobber (reg:SI R1_REG))
1245    (clobber (reg:SI R4_REG))
1246    (clobber (reg:SI R5_REG))
1247    (use (reg:PSI FPSCR_REG))
1248    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1249   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1250   "jsr  @%1%#"
1251   [(set_attr "type" "sfunc")
1252    (set_attr "fp_mode" "double")
1253    (set_attr "needs_delay_slot" "yes")])
1254
1255 (define_insn "udivsi3_i4_single"
1256   [(set (match_operand:SI 0 "register_operand" "=y")
1257         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1258    (clobber (reg:SI T_REG))
1259    (clobber (reg:SI PR_REG))
1260    (clobber (reg:DF DR0_REG))
1261    (clobber (reg:DF DR2_REG))
1262    (clobber (reg:DF DR4_REG))
1263    (clobber (reg:SI R0_REG))
1264    (clobber (reg:SI R1_REG))
1265    (clobber (reg:SI R4_REG))
1266    (clobber (reg:SI R5_REG))
1267    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1268   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1269   "jsr  @%1%#"
1270   [(set_attr "type" "sfunc")
1271    (set_attr "needs_delay_slot" "yes")])
1272
1273 (define_expand "udivsi3"
1274   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1275    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1276    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1277    (parallel [(set (match_operand:SI 0 "register_operand" "")
1278                    (udiv:SI (reg:SI R4_REG)
1279                             (reg:SI R5_REG)))
1280               (clobber (reg:SI T_REG))
1281               (clobber (reg:SI PR_REG))
1282               (clobber (reg:SI R4_REG))
1283               (use (match_dup 3))])]
1284   ""
1285   "
1286 {
1287   rtx first, last;
1288
1289   operands[3] = gen_reg_rtx (Pmode);
1290   /* Emit the move of the address to a pseudo outside of the libcall.  */
1291   if (TARGET_HARD_SH4 && TARGET_SH2E)
1292     {
1293       emit_move_insn (operands[3], function_symbol (\"__udivsi3_i4\"));
1294       if (TARGET_FPU_SINGLE)
1295         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1296       else
1297         last = gen_udivsi3_i4 (operands[0], operands[3]);
1298     }
1299   else if (TARGET_SHMEDIA_FPU)
1300     {
1301       operands[1] = force_reg (SImode, operands[1]);
1302       operands[2] = force_reg (SImode, operands[2]);
1303       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1304       DONE;
1305     }
1306   else if (TARGET_SH2A)
1307     {
1308       operands[1] = force_reg (SImode, operands[1]);
1309       operands[2] = force_reg (SImode, operands[2]);
1310       emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1311       DONE;
1312     }
1313   else if (TARGET_SH5)
1314     {
1315       emit_move_insn (operands[3],
1316                       function_symbol (TARGET_FPU_ANY
1317                                        ? \"__udivsi3_i4\"
1318                                        : \"__udivsi3\"));
1319
1320       if (TARGET_SHMEDIA)
1321         last = gen_udivsi3_i1_media (operands[0],
1322                                      Pmode == DImode
1323                                      ? operands[3]
1324                                      : gen_rtx_SUBREG (DImode, operands[3],
1325                                                        0));
1326       else if (TARGET_FPU_ANY)
1327         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1328       else
1329         last = gen_udivsi3_i1 (operands[0], operands[3]);
1330     }
1331   else
1332     {
1333       emit_move_insn (operands[3], function_symbol (\"__udivsi3\"));
1334       last = gen_udivsi3_i1 (operands[0], operands[3]);
1335     }
1336   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1337   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1338   last = emit_insn (last);
1339   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1340      invariant code motion can move it.  */
1341   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1342   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1343   DONE;
1344 }")
1345
1346 (define_insn "divsi3_sh2a"
1347   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1348         (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1349                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1350   "TARGET_SH2A"
1351   "divs %2,%1"
1352   [(set_attr "type" "arith")
1353    (set_attr "in_delay_slot" "no")])
1354
1355 (define_insn "divsi3_i1"
1356   [(set (match_operand:SI 0 "register_operand" "=z")
1357         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1358    (clobber (reg:SI T_REG))
1359    (clobber (reg:SI PR_REG))
1360    (clobber (reg:SI R1_REG))
1361    (clobber (reg:SI R2_REG))
1362    (clobber (reg:SI R3_REG))
1363    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1364   "TARGET_SH1 && ! TARGET_SH4"
1365   "jsr  @%1%#"
1366   [(set_attr "type" "sfunc")
1367    (set_attr "needs_delay_slot" "yes")])
1368
1369 ; Since shmedia-nofpu code could be linked against shcompact code, and
1370 ; the sdivsi3 libcall has the same name, we must consider all registers
1371 ; clobbered that are in the union of the registers clobbered by the
1372 ; shmedia and the shcompact implementation.  Note, if the shcompact
1373 ; implementation actually used shcompact code, we'd need to clobber
1374 ; also r22, r23 and fr23.
1375 (define_insn "divsi3_i1_media"
1376   [(set (match_operand:SI 0 "register_operand" "=z")
1377         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1378    (clobber (reg:SI T_MEDIA_REG))
1379    (clobber (reg:SI PR_MEDIA_REG))
1380    (clobber (reg:SI R1_REG))
1381    (clobber (reg:SI R2_REG))
1382    (clobber (reg:SI R3_REG))
1383    (clobber (reg:SI R20_REG))
1384    (clobber (reg:SI R21_REG))
1385    (clobber (reg:DI TR0_REG))
1386    (clobber (reg:DI TR1_REG))
1387    (clobber (reg:DI TR2_REG))
1388    (use (match_operand:DI 1 "target_operand" "b"))]
1389   "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1390   "blink        %1, r18"
1391   [(set_attr "type" "sfunc")])
1392
1393 (define_expand "divsi3_i4_media"
1394   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1395    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1396    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1397    (set (match_operand:SI 0 "register_operand" "=r")
1398         (fix:SI (match_dup 5)))]
1399   "TARGET_SHMEDIA_FPU"
1400   "
1401 {
1402   operands[3] = gen_reg_rtx (DFmode);
1403   operands[4] = gen_reg_rtx (DFmode);
1404   operands[5] = gen_reg_rtx (DFmode);
1405 }")
1406
1407 (define_insn "divsi3_i4"
1408   [(set (match_operand:SI 0 "register_operand" "=y")
1409         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1410    (clobber (reg:SI PR_REG))
1411    (clobber (reg:DF DR0_REG))
1412    (clobber (reg:DF DR2_REG))
1413    (use (reg:PSI FPSCR_REG))
1414    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1415   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1416   "jsr  @%1%#"
1417   [(set_attr "type" "sfunc")
1418    (set_attr "fp_mode" "double")
1419    (set_attr "needs_delay_slot" "yes")])
1420
1421 (define_insn "divsi3_i4_single"
1422   [(set (match_operand:SI 0 "register_operand" "=y")
1423         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1424    (clobber (reg:SI PR_REG))
1425    (clobber (reg:DF DR0_REG))
1426    (clobber (reg:DF DR2_REG))
1427    (clobber (reg:SI R2_REG))
1428    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1429   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1430   "jsr  @%1%#"
1431   [(set_attr "type" "sfunc")
1432    (set_attr "needs_delay_slot" "yes")])
1433
1434 (define_expand "divsi3"
1435   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1436    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1437    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1438    (parallel [(set (match_operand:SI 0 "register_operand" "")
1439                    (div:SI (reg:SI R4_REG)
1440                            (reg:SI R5_REG)))
1441               (clobber (reg:SI T_REG))
1442               (clobber (reg:SI PR_REG))
1443               (clobber (reg:SI R1_REG))
1444               (clobber (reg:SI R2_REG))
1445               (clobber (reg:SI R3_REG))
1446               (use (match_dup 3))])]
1447   ""
1448   "
1449 {
1450   rtx first, last;
1451
1452   operands[3] = gen_reg_rtx (Pmode);
1453   /* Emit the move of the address to a pseudo outside of the libcall.  */
1454   if (TARGET_HARD_SH4 && TARGET_SH2E)
1455     {
1456       emit_move_insn (operands[3], function_symbol (\"__sdivsi3_i4\"));
1457       if (TARGET_FPU_SINGLE)
1458         last = gen_divsi3_i4_single (operands[0], operands[3]);
1459       else
1460         last = gen_divsi3_i4 (operands[0], operands[3]);
1461     }
1462   else if (TARGET_SH2A)
1463     {
1464       operands[1] = force_reg (SImode, operands[1]);
1465       operands[2] = force_reg (SImode, operands[2]);
1466       emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
1467       DONE;
1468     }
1469   else if (TARGET_SHMEDIA_FPU)
1470     {
1471       operands[1] = force_reg (SImode, operands[1]);
1472       operands[2] = force_reg (SImode, operands[2]);
1473       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
1474       DONE;
1475     }
1476   else if (TARGET_SH5)
1477     {
1478       emit_move_insn (operands[3],
1479                       function_symbol (TARGET_FPU_ANY
1480                                        ? \"__sdivsi3_i4\"
1481                                        : \"__sdivsi3\"));
1482
1483       if (TARGET_SHMEDIA)
1484         last = gen_divsi3_i1_media (operands[0],
1485                                     Pmode == DImode
1486                                     ? operands[3]
1487                                     : gen_rtx_SUBREG (DImode, operands[3],
1488                                                       0));
1489       else if (TARGET_FPU_ANY)
1490         last = gen_divsi3_i4_single (operands[0], operands[3]);
1491       else
1492         last = gen_divsi3_i1 (operands[0], operands[3]);
1493     }
1494   else
1495     {
1496       emit_move_insn (operands[3], function_symbol (\"__sdivsi3\"));
1497       last = gen_divsi3_i1 (operands[0], operands[3]);
1498     }
1499   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1500   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1501   last = emit_insn (last);
1502   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1503      invariant code motion can move it.  */
1504   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1505   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1506   DONE;
1507 }")
1508 \f
1509 ;; -------------------------------------------------------------------------
1510 ;; Multiplication instructions
1511 ;; -------------------------------------------------------------------------
1512
1513 (define_insn "umulhisi3_i"
1514   [(set (reg:SI MACL_REG)
1515         (mult:SI (zero_extend:SI
1516                   (match_operand:HI 0 "arith_reg_operand" "r"))
1517                  (zero_extend:SI
1518                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
1519   "TARGET_SH1"
1520   "mulu.w       %1,%0"
1521   [(set_attr "type" "smpy")])
1522
1523 (define_insn "mulhisi3_i"
1524   [(set (reg:SI MACL_REG)
1525         (mult:SI (sign_extend:SI
1526                   (match_operand:HI 0 "arith_reg_operand" "r"))
1527                  (sign_extend:SI
1528                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
1529   "TARGET_SH1"
1530   "muls.w       %1,%0"
1531   [(set_attr "type" "smpy")])
1532
1533 (define_expand "mulhisi3"
1534   [(set (reg:SI MACL_REG)
1535         (mult:SI (sign_extend:SI
1536                   (match_operand:HI 1 "arith_reg_operand" ""))
1537                  (sign_extend:SI
1538                   (match_operand:HI 2 "arith_reg_operand" ""))))
1539    (set (match_operand:SI 0 "arith_reg_operand" "")
1540         (reg:SI MACL_REG))]
1541   "TARGET_SH1"
1542   "
1543 {
1544   rtx first, last;
1545
1546   first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1547   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1548   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1549      invariant code motion can move it.  */
1550   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1551   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1552   /* expand_binop can't find a suitable code in umul_widen_optab to
1553      make a REG_EQUAL note from, so make one here.
1554      See also smulsi3_highpart.
1555      ??? Alternatively, we could put this at the calling site of expand_binop,
1556      i.e. expand_expr.  */
1557   REG_NOTES (last)
1558     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1559                          REG_NOTES (last));
1560   DONE;
1561 }")
1562
1563 (define_expand "umulhisi3"
1564   [(set (reg:SI MACL_REG)
1565         (mult:SI (zero_extend:SI
1566                   (match_operand:HI 1 "arith_reg_operand" ""))
1567                  (zero_extend:SI
1568                   (match_operand:HI 2 "arith_reg_operand" ""))))
1569    (set (match_operand:SI 0 "arith_reg_operand" "")
1570         (reg:SI MACL_REG))]
1571   "TARGET_SH1"
1572   "
1573 {
1574   rtx first, last;
1575
1576   first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1577   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1578   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1579      invariant code motion can move it.  */
1580   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1581   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1582   /* expand_binop can't find a suitable code in umul_widen_optab to
1583      make a REG_EQUAL note from, so make one here.
1584      See also smulsi3_highpart.
1585      ??? Alternatively, we could put this at the calling site of expand_binop,
1586      i.e. expand_expr.  */
1587   REG_NOTES (last)
1588     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1589                          REG_NOTES (last));
1590   DONE;
1591 }")
1592
1593 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1594 ;; a call to a routine which clobbers known registers.
1595
1596 (define_insn ""
1597   [(set (match_operand:SI 1 "register_operand" "=z")
1598         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1599    (clobber (reg:SI MACL_REG))
1600    (clobber (reg:SI T_REG))
1601    (clobber (reg:SI PR_REG))
1602    (clobber (reg:SI R3_REG))
1603    (clobber (reg:SI R2_REG))
1604    (clobber (reg:SI R1_REG))
1605    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1606   "TARGET_SH1"
1607   "jsr  @%0%#"
1608   [(set_attr "type" "sfunc")
1609    (set_attr "needs_delay_slot" "yes")])
1610
1611 (define_expand "mulsi3_call"
1612   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1613    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1614    (parallel[(set (match_operand:SI 0 "register_operand" "")
1615                   (mult:SI (reg:SI R4_REG)
1616                            (reg:SI R5_REG)))
1617              (clobber (reg:SI MACL_REG))
1618              (clobber (reg:SI T_REG))
1619              (clobber (reg:SI PR_REG))
1620              (clobber (reg:SI R3_REG))
1621              (clobber (reg:SI R2_REG))
1622              (clobber (reg:SI R1_REG))
1623              (use (match_operand:SI 3 "register_operand" ""))])]
1624   "TARGET_SH1"
1625   "")
1626
1627 (define_insn "mul_r"
1628   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1629         (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
1630                  (match_operand:SI 2 "arith_reg_operand" "z")))]
1631   "TARGET_SH2A"
1632   "mulr %2,%0"
1633   [(set_attr "type" "dmpy")])
1634
1635 (define_insn "mul_l"
1636   [(set (reg:SI MACL_REG)
1637         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1638                  (match_operand:SI 1 "arith_reg_operand" "r")))]
1639   "TARGET_SH2"
1640   "mul.l        %1,%0"
1641   [(set_attr "type" "dmpy")])
1642
1643 (define_expand "mulsi3"
1644   [(set (reg:SI MACL_REG)
1645         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
1646                   (match_operand:SI 2 "arith_reg_operand" "")))
1647    (set (match_operand:SI 0 "arith_reg_operand" "")
1648         (reg:SI MACL_REG))]
1649   "TARGET_SH1"
1650   "
1651 {
1652   rtx first, last;
1653
1654   if (!TARGET_SH2)
1655     {
1656       /* The address must be set outside the libcall,
1657          since it goes into a pseudo.  */
1658       rtx sym = function_symbol (\"__mulsi3\");
1659       rtx addr = force_reg (SImode, sym);
1660       rtx insns = gen_mulsi3_call (operands[0], operands[1],
1661                                    operands[2], addr);
1662       first = insns;
1663       last = emit_insn (insns);
1664     }
1665   else
1666     {
1667       rtx macl = gen_rtx_REG (SImode, MACL_REG);
1668
1669       first = emit_insn (gen_mul_l (operands[1], operands[2]));
1670       /* consec_sets_giv can only recognize the first insn that sets a
1671          giv as the giv insn.  So we must tag this also with a REG_EQUAL
1672          note.  */
1673       last = emit_insn (gen_movsi_i ((operands[0]), macl));
1674     }
1675   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1676      invariant code motion can move it.  */
1677   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1678   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1679   DONE;
1680 }")
1681
1682 (define_insn "mulsidi3_i"
1683   [(set (reg:SI MACH_REG)
1684         (truncate:SI
1685          (lshiftrt:DI
1686           (mult:DI
1687            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1688            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1689           (const_int 32))))
1690    (set (reg:SI MACL_REG)
1691         (mult:SI (match_dup 0)
1692                  (match_dup 1)))]
1693   "TARGET_SH2"
1694   "dmuls.l      %1,%0"
1695   [(set_attr "type" "dmpy")])
1696
1697 (define_expand "mulsidi3"
1698   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1699         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1700                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1701   "TARGET_SH2 || TARGET_SHMEDIA"
1702   "
1703 {
1704   if (TARGET_SH2)
1705     {
1706        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1707                                         operands[2]));
1708        DONE;
1709     }
1710 }")
1711
1712 (define_insn "mulsidi3_media"
1713   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1714         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1715                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1716   "TARGET_SHMEDIA"
1717   "muls.l       %1, %2, %0"
1718   [(set_attr "type" "dmpy_media")])
1719
1720 (define_insn "mulsidi3_compact"
1721   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1722         (mult:DI
1723          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1724          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1725    (clobber (reg:SI MACH_REG))
1726    (clobber (reg:SI MACL_REG))]
1727   "TARGET_SH2"
1728   "#")
1729
1730 (define_split
1731   [(set (match_operand:DI 0 "arith_reg_operand" "")
1732         (mult:DI
1733          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1734          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1735    (clobber (reg:SI MACH_REG))
1736    (clobber (reg:SI MACL_REG))]
1737   "TARGET_SH2"
1738   [(const_int 0)]
1739   "
1740 {
1741   rtx low_dst = gen_lowpart (SImode, operands[0]);
1742   rtx high_dst = gen_highpart (SImode, operands[0]);
1743
1744   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1745
1746   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1747   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1748   /* We need something to tag the possible REG_EQUAL notes on to.  */
1749   emit_move_insn (operands[0], operands[0]);
1750   DONE;
1751 }")
1752
1753 (define_insn "umulsidi3_i"
1754   [(set (reg:SI MACH_REG)
1755         (truncate:SI
1756          (lshiftrt:DI
1757           (mult:DI
1758            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1759            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1760           (const_int 32))))
1761    (set (reg:SI MACL_REG)
1762         (mult:SI (match_dup 0)
1763                  (match_dup 1)))]
1764   "TARGET_SH2"
1765   "dmulu.l      %1,%0"
1766   [(set_attr "type" "dmpy")])
1767
1768 (define_expand "umulsidi3"
1769   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1770         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1771                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1772   "TARGET_SH2 || TARGET_SHMEDIA"
1773   "
1774 {
1775   if (TARGET_SH2)
1776     {
1777        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1778                                          operands[2]));
1779        DONE;
1780     }
1781 }")
1782
1783 (define_insn "umulsidi3_media"
1784   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1785         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1786                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1787   "TARGET_SHMEDIA"
1788   "mulu.l       %1, %2, %0"
1789   [(set_attr "type" "dmpy_media")])
1790
1791 (define_insn "umulsidi3_compact"
1792   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1793         (mult:DI
1794          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1795          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1796    (clobber (reg:SI MACH_REG))
1797    (clobber (reg:SI MACL_REG))]
1798   "TARGET_SH2"
1799   "#")
1800
1801 (define_split
1802   [(set (match_operand:DI 0 "arith_reg_operand" "")
1803         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1804                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1805    (clobber (reg:SI MACH_REG))
1806    (clobber (reg:SI MACL_REG))]
1807   "TARGET_SH2"
1808   [(const_int 0)]
1809   "
1810 {
1811   rtx low_dst = gen_lowpart (SImode, operands[0]);
1812   rtx high_dst = gen_highpart (SImode, operands[0]);
1813
1814   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1815
1816   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1817   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1818   /* We need something to tag the possible REG_EQUAL notes on to.  */
1819   emit_move_insn (operands[0], operands[0]);
1820   DONE;
1821 }")
1822
1823 (define_insn "smulsi3_highpart_i"
1824   [(set (reg:SI MACH_REG)
1825         (truncate:SI
1826          (lshiftrt:DI
1827           (mult:DI
1828            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1829            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1830           (const_int 32))))
1831    (clobber (reg:SI MACL_REG))]
1832   "TARGET_SH2"
1833   "dmuls.l      %1,%0"
1834   [(set_attr "type" "dmpy")])
1835
1836 (define_expand "smulsi3_highpart"
1837   [(parallel
1838     [(set (reg:SI MACH_REG)
1839           (truncate:SI
1840            (lshiftrt:DI
1841             (mult:DI
1842              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1843              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1844             (const_int 32))))
1845     (clobber (reg:SI MACL_REG))])
1846    (set (match_operand:SI 0 "arith_reg_operand" "")
1847         (reg:SI MACH_REG))]
1848   "TARGET_SH2"
1849   "
1850 {
1851   rtx first, last;
1852
1853   first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1854   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1855   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1856      invariant code motion can move it.  */
1857   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1858   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1859   /* expand_binop can't find a suitable code in mul_highpart_optab to
1860      make a REG_EQUAL note from, so make one here.
1861      See also {,u}mulhisi.
1862      ??? Alternatively, we could put this at the calling site of expand_binop,
1863      i.e. expand_mult_highpart.  */
1864   REG_NOTES (last)
1865     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1866                          REG_NOTES (last));
1867   DONE;
1868 }")
1869
1870 (define_insn "umulsi3_highpart_i"
1871   [(set (reg:SI MACH_REG)
1872         (truncate:SI
1873          (lshiftrt:DI
1874           (mult:DI
1875            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1876            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1877           (const_int 32))))
1878    (clobber (reg:SI MACL_REG))]
1879   "TARGET_SH2"
1880   "dmulu.l      %1,%0"
1881   [(set_attr "type" "dmpy")])
1882
1883 (define_expand "umulsi3_highpart"
1884   [(parallel
1885     [(set (reg:SI MACH_REG)
1886           (truncate:SI
1887            (lshiftrt:DI
1888             (mult:DI
1889              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1890              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1891             (const_int 32))))
1892     (clobber (reg:SI MACL_REG))])
1893    (set (match_operand:SI 0 "arith_reg_operand" "")
1894         (reg:SI MACH_REG))]
1895   "TARGET_SH2"
1896   "
1897 {
1898   rtx first, last;
1899
1900   first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1901   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1902   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1903      invariant code motion can move it.  */
1904   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1905   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1906   DONE;
1907 }")
1908 \f
1909 ;; -------------------------------------------------------------------------
1910 ;; Logical operations
1911 ;; -------------------------------------------------------------------------
1912
1913 (define_insn "*andsi3_compact"
1914   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1915         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1916                 (match_operand:SI 2 "logical_operand" "r,K08")))]
1917   "TARGET_SH1"
1918   "and  %2,%0"
1919   [(set_attr "type" "arith")])
1920
1921 ;; If the constant is 255, then emit an extu.b instruction instead of an
1922 ;; and, since that will give better code.
1923
1924 (define_expand "andsi3"
1925   [(set (match_operand:SI 0 "arith_reg_operand" "")
1926         (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1927                 (match_operand:SI 2 "logical_operand" "")))]
1928   "TARGET_SH1"
1929   "
1930 {
1931   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1932     {
1933       emit_insn (gen_zero_extendqisi2 (operands[0],
1934                                        gen_lowpart (QImode, operands[1])));
1935       DONE;
1936     }
1937 }")
1938
1939 (define_insn_and_split "anddi3"
1940   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1941         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
1942                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
1943   "TARGET_SHMEDIA"
1944   "@
1945         and     %1, %2, %0
1946         andi    %1, %2, %0
1947         #"
1948   "reload_completed
1949    && ! logical_operand (operands[2], DImode)"
1950   [(const_int 0)]
1951   "
1952 {
1953   if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
1954     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
1955   else
1956     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
1957   DONE;
1958 }"
1959   [(set_attr "type" "arith_media")])
1960
1961 (define_insn "andcdi3"
1962   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1963         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
1964                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
1965   "TARGET_SHMEDIA"
1966   "andc %1,%2,%0"
1967   [(set_attr "type" "arith_media")])
1968
1969 (define_insn "iorsi3"
1970   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1971         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1972                 (match_operand:SI 2 "logical_operand" "r,K08")))]
1973   "TARGET_SH1"
1974   "or   %2,%0"
1975   [(set_attr "type" "arith")])
1976
1977 (define_insn "iordi3"
1978   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1979         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1980                 (match_operand:DI 2 "logical_operand" "r,I10")))]
1981   "TARGET_SHMEDIA"
1982   "@
1983         or      %1, %2, %0
1984         ori     %1, %2, %0"
1985   [(set_attr "type" "arith_media")])
1986
1987 (define_insn "xorsi3"
1988   [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
1989         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1990                 (match_operand:SI 2 "logical_operand" "K08,r")))]
1991   "TARGET_SH1"
1992   "xor  %2,%0"
1993   [(set_attr "type" "arith")])
1994
1995 (define_insn "xordi3"
1996   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1997         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1998                 (match_operand:DI 2 "shmedia_6bit_operand" "r,I06")))]
1999   "TARGET_SHMEDIA"
2000   "@
2001         xor     %1, %2, %0
2002         xori    %1, %2, %0"
2003   [(set_attr "type" "arith_media")])
2004
2005 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
2006 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
2007 (define_split
2008   [(set (match_operand:DI 0 "arith_reg_operand" "")
2009         (sign_extend:DI (match_operator 4 "binary_logical_operator"
2010                           [(match_operand 1 "any_register_operand" "")
2011                            (match_operand 2 "any_register_operand" "")])))]
2012   "TARGET_SHMEDIA"
2013   [(set (match_dup 5) (match_dup 4))
2014    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
2015 "
2016 {
2017   enum machine_mode inmode = GET_MODE (operands[1]);
2018   int offset = 0;
2019
2020   if (GET_CODE (operands[0]) == SUBREG)
2021     {
2022       offset = SUBREG_BYTE (operands[0]);
2023       operands[0] = SUBREG_REG (operands[0]);
2024     }
2025   if (GET_CODE (operands[0]) != REG)
2026     abort ();
2027   if (! TARGET_LITTLE_ENDIAN)
2028     offset += 8 - GET_MODE_SIZE (inmode);
2029   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
2030 }")
2031 \f
2032 ;; -------------------------------------------------------------------------
2033 ;; Shifts and rotates
2034 ;; -------------------------------------------------------------------------
2035
2036 (define_expand "rotldi3"
2037   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2038         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2039                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
2040   "TARGET_SHMEDIA"
2041   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2042
2043 (define_insn "rotldi3_mextr"
2044   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2045         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2046                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
2047   "TARGET_SHMEDIA"
2048   "*
2049 {
2050   static char templ[16];
2051
2052   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2053            8 - (int) (INTVAL (operands[2]) >> 3));
2054   return templ;
2055 }"
2056   [(set_attr "type" "arith_media")])
2057
2058 (define_expand "rotrdi3"
2059   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2060         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2061                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
2062   "TARGET_SHMEDIA"
2063   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2064
2065 (define_insn "rotrdi3_mextr"
2066   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2067         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2068                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
2069   "TARGET_SHMEDIA"
2070   "*
2071 {
2072   static char templ[16];
2073
2074   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2075   return templ;
2076 }"
2077   [(set_attr "type" "arith_media")])
2078
2079 (define_insn "rotlsi3_1"
2080   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2081         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2082                    (const_int 1)))
2083    (set (reg:SI T_REG)
2084         (lshiftrt:SI (match_dup 1) (const_int 31)))]
2085   "TARGET_SH1"
2086   "rotl %0"
2087   [(set_attr "type" "arith")])
2088
2089 (define_insn "rotlsi3_31"
2090   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2091         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2092                    (const_int 31)))
2093    (clobber (reg:SI T_REG))]
2094   "TARGET_SH1"
2095   "rotr %0"
2096   [(set_attr "type" "arith")])
2097
2098 (define_insn "rotlsi3_16"
2099   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2100         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2101                    (const_int 16)))]
2102   "TARGET_SH1"
2103   "swap.w       %1,%0"
2104   [(set_attr "type" "arith")])
2105
2106 (define_expand "rotlsi3"
2107   [(set (match_operand:SI 0 "arith_reg_operand" "")
2108         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2109                    (match_operand:SI 2 "immediate_operand" "")))]
2110   "TARGET_SH1"
2111   "
2112 {
2113   static const char rot_tab[] = {
2114     000, 000, 000, 000, 000, 000, 010, 001,
2115     001, 001, 011, 013, 003, 003, 003, 003,
2116     003, 003, 003, 003, 003, 013, 012, 002,
2117     002, 002, 010, 000, 000, 000, 000, 000,
2118   };
2119
2120   int count, choice;
2121
2122   if (GET_CODE (operands[2]) != CONST_INT)
2123     FAIL;
2124   count = INTVAL (operands[2]);
2125   choice = rot_tab[count];
2126   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2127     FAIL;
2128   choice &= 7;
2129   switch (choice)
2130     {
2131     case 0:
2132       emit_move_insn (operands[0], operands[1]);
2133       count -= (count & 16) * 2;
2134       break;
2135     case 3:
2136      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2137      count -= 16;
2138      break;
2139     case 1:
2140     case 2:
2141       {
2142         rtx parts[2];
2143         parts[0] = gen_reg_rtx (SImode);
2144         parts[1] = gen_reg_rtx (SImode);
2145         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2146         emit_move_insn (parts[choice-1], operands[1]);
2147         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2148         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2149         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2150         count = (count & ~16) - 8;
2151       }
2152     }
2153
2154   for (; count > 0; count--)
2155     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2156   for (; count < 0; count++)
2157     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2158
2159   DONE;
2160 }")
2161
2162 (define_insn "*rotlhi3_8"
2163   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2164         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2165                    (const_int 8)))]
2166   "TARGET_SH1"
2167   "swap.b       %1,%0"
2168   [(set_attr "type" "arith")])
2169
2170 (define_expand "rotlhi3"
2171   [(set (match_operand:HI 0 "arith_reg_operand" "")
2172         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2173                    (match_operand:HI 2 "immediate_operand" "")))]
2174   "TARGET_SH1"
2175   "
2176 {
2177   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2178     FAIL;
2179 }")
2180
2181 ;;
2182 ;; shift left
2183
2184 (define_insn "ashlsi3_sh2a"
2185   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2186         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2187                    (match_operand:SI 2 "arith_reg_operand" "r")))]
2188   "TARGET_SH2A"
2189   "shad %2,%0"
2190   [(set_attr "type" "arith")
2191    (set_attr "length" "4")])
2192
2193 ;; This pattern is used by init_expmed for computing the costs of shift
2194 ;; insns.
2195
2196 (define_insn_and_split "ashlsi3_std"
2197   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2198         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2199                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
2200    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2201   "TARGET_SH3
2202    || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2203        && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
2204   "@
2205    shld %2,%0
2206    add  %0,%0
2207    shll%O2      %0
2208    #"
2209   "TARGET_SH3
2210    && reload_completed
2211    && GET_CODE (operands[2]) == CONST_INT
2212    && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2213   [(set (match_dup 3) (match_dup 2))
2214    (parallel
2215     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2216      (clobber (match_dup 4))])]
2217   "operands[4] = gen_rtx_SCRATCH (SImode);"
2218   [(set_attr "length" "*,*,*,4")
2219    (set_attr "type" "dyn_shift,arith,arith,arith")])
2220
2221 (define_insn "ashlhi3_k"
2222   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2223         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2224                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
2225   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2226   "@
2227         add     %0,%0
2228         shll%O2 %0"
2229   [(set_attr "type" "arith")])
2230
2231 (define_insn "ashlsi3_n"
2232   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2233         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2234                    (match_operand:SI 2 "const_int_operand" "n")))
2235    (clobber (reg:SI T_REG))]
2236   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2237   "#"
2238   [(set (attr "length")
2239         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2240                (const_string "2")
2241                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2242                (const_string "4")
2243                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2244                (const_string "6")]
2245               (const_string "8")))
2246    (set_attr "type" "arith")])
2247
2248 (define_split
2249   [(set (match_operand:SI 0 "arith_reg_operand" "")
2250         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2251                    (match_operand:SI 2 "const_int_operand" "")))
2252    (clobber (reg:SI T_REG))]
2253   "TARGET_SH1 && reload_completed"
2254   [(use (reg:SI R0_REG))]
2255   "
2256 {
2257   gen_shifty_op (ASHIFT, operands);
2258   DONE;
2259 }")
2260
2261 (define_insn "ashlsi3_media"
2262   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2263         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2264                    (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2265   "TARGET_SHMEDIA"
2266   "@
2267         shlld.l %1, %2, %0
2268         shlli.l %1, %2, %0"
2269   [(set_attr "type" "arith_media")])
2270
2271 (define_expand "ashlsi3"
2272   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2273                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2274                               (match_operand:SI 2 "nonmemory_operand" "")))
2275               (clobber (reg:SI T_REG))])]
2276   ""
2277   "
2278 {
2279   if (TARGET_SHMEDIA)
2280     {
2281       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2282       DONE;
2283     }
2284   if (GET_CODE (operands[2]) == CONST_INT
2285       && sh_dynamicalize_shift_p (operands[2]))
2286     operands[2] = force_reg (SImode, operands[2]);
2287   if (TARGET_SH3)
2288     {
2289       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2290       DONE;
2291     }
2292   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2293     FAIL;
2294 }")
2295
2296 (define_insn "*ashlhi3_n"
2297   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2298         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2299                    (match_operand:HI 2 "const_int_operand" "n")))
2300    (clobber (reg:SI T_REG))]
2301   "TARGET_SH1"
2302   "#"
2303   [(set (attr "length")
2304         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2305                (const_string "2")
2306                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2307                (const_string "4")]
2308               (const_string "6")))
2309    (set_attr "type" "arith")])
2310
2311 (define_expand "ashlhi3"
2312   [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
2313                    (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2314                               (match_operand:SI 2 "nonmemory_operand" "")))
2315               (clobber (reg:SI T_REG))])]
2316   "TARGET_SH1"
2317   "
2318 {
2319   if (GET_CODE (operands[2]) != CONST_INT)
2320     FAIL;
2321   /* It may be possible to call gen_ashlhi3 directly with more generic
2322      operands.  Make sure operands[1] is a HImode register here.  */
2323   if (!arith_reg_operand (operands[1], HImode))
2324     operands[1] = copy_to_mode_reg (HImode, operands[1]);
2325 }")
2326
2327 (define_split
2328   [(set (match_operand:HI 0 "arith_reg_operand" "")
2329         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2330                    (match_operand:HI 2 "const_int_operand" "")))
2331    (clobber (reg:SI T_REG))]
2332   "TARGET_SH1 && reload_completed"
2333   [(use (reg:SI R0_REG))]
2334   "
2335 {
2336   gen_shifty_hi_op (ASHIFT, operands);
2337   DONE;
2338 }")
2339
2340 ;
2341 ; arithmetic shift right
2342 ;
2343
2344 (define_insn "ashrsi3_sh2a"
2345   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2346         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2347                    (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2348   "TARGET_SH2A"
2349   "shad %2,%0"
2350   [(set_attr "type" "dyn_shift")
2351    (set_attr "length" "4")])
2352
2353 (define_insn "ashrsi3_k"
2354   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2355         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2356                      (match_operand:SI 2 "const_int_operand" "M")))
2357    (clobber (reg:SI T_REG))]
2358   "TARGET_SH1 && INTVAL (operands[2]) == 1"
2359   "shar %0"
2360   [(set_attr "type" "arith")])
2361
2362 ;; We can't do HImode right shifts correctly unless we start out with an
2363 ;; explicit zero / sign extension; doing that would result in worse overall
2364 ;; code, so just let the machine independent code widen the mode.
2365 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2366
2367
2368 ;; ??? This should be a define expand.
2369
2370 (define_insn "ashrsi2_16"
2371   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2372         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2373                      (const_int 16)))]
2374   "TARGET_SH1"
2375   "#"
2376   [(set_attr "length" "4")])
2377
2378 (define_split
2379   [(set (match_operand:SI 0 "arith_reg_operand" "")
2380         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2381                      (const_int 16)))]
2382   "TARGET_SH1"
2383   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2384    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2385   "operands[2] = gen_lowpart (HImode, operands[0]);")
2386
2387 ;; ??? This should be a define expand.
2388
2389 (define_insn "ashrsi2_31"
2390   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2391         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2392                      (const_int 31)))
2393    (clobber (reg:SI T_REG))]
2394   "TARGET_SH1"
2395   "#"
2396   [(set_attr "length" "4")])
2397
2398 (define_split
2399   [(set (match_operand:SI 0 "arith_reg_operand" "")
2400         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2401                      (const_int 31)))
2402    (clobber (reg:SI T_REG))]
2403   "TARGET_SH1"
2404   [(const_int 0)]
2405   "
2406 {
2407   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2408   emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2409   DONE;
2410 }")
2411
2412 (define_insn "ashlsi_c"
2413   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2414         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2415    (set (reg:SI T_REG)
2416         (lt:SI (match_dup 1) (const_int 0)))]
2417   "TARGET_SH1"
2418   "shll %0"
2419   [(set_attr "type" "arith")])
2420
2421 (define_insn "ashrsi3_d"
2422   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2423         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2424                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2425   "TARGET_SH3"
2426   "shad %2,%0"
2427   [(set_attr "type" "dyn_shift")])
2428
2429 (define_insn "ashrsi3_n"
2430   [(set (reg:SI R4_REG)
2431         (ashiftrt:SI (reg:SI R4_REG)
2432                      (match_operand:SI 0 "const_int_operand" "i")))
2433    (clobber (reg:SI T_REG))
2434    (clobber (reg:SI PR_REG))
2435    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2436   "TARGET_SH1"
2437   "jsr  @%1%#"
2438   [(set_attr "type" "sfunc")
2439    (set_attr "needs_delay_slot" "yes")])
2440
2441 (define_insn "ashrsi3_media"
2442   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2443         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2444                      (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2445   "TARGET_SHMEDIA"
2446   "@
2447         shard.l %1, %2, %0
2448         shari.l %1, %2, %0"
2449   [(set_attr "type" "arith_media")])
2450
2451 (define_expand "ashrsi3"
2452   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2453                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2454                                 (match_operand:SI 2 "nonmemory_operand" "")))
2455               (clobber (reg:SI T_REG))])]
2456   ""
2457   "
2458 {
2459   if (TARGET_SHMEDIA)
2460     {
2461       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2462       DONE;
2463     }
2464   if (expand_ashiftrt (operands))
2465     DONE;
2466   else
2467     FAIL;
2468 }")
2469
2470 ;; logical shift right
2471
2472 (define_insn "lshrsi3_sh2a"
2473   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2474         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2475                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2476   "TARGET_SH2A"
2477   "shld %2,%0"
2478   [(set_attr "type" "dyn_shift")
2479    (set_attr "length" "4")])
2480
2481 (define_insn "lshrsi3_d"
2482   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2483         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2484                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2485   "TARGET_SH3"
2486   "shld %2,%0"
2487   [(set_attr "type" "dyn_shift")])
2488
2489 ;;  Only the single bit shift clobbers the T bit.
2490
2491 (define_insn "lshrsi3_m"
2492   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2493         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2494                      (match_operand:SI 2 "const_int_operand" "M")))
2495    (clobber (reg:SI T_REG))]
2496   "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2497   "shlr %0"
2498   [(set_attr "type" "arith")])
2499
2500 (define_insn "lshrsi3_k"
2501   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2502         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2503                      (match_operand:SI 2 "const_int_operand" "P27")))]
2504   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
2505    && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2506   "shlr%O2      %0"
2507   [(set_attr "type" "arith")])
2508
2509 (define_insn "lshrsi3_n"
2510   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2511         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2512                      (match_operand:SI 2 "const_int_operand" "n")))
2513    (clobber (reg:SI T_REG))]
2514   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2515   "#"
2516   [(set (attr "length")
2517         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2518                (const_string "2")
2519                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2520                (const_string "4")
2521                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2522                (const_string "6")]
2523               (const_string "8")))
2524    (set_attr "type" "arith")])
2525
2526 (define_split
2527   [(set (match_operand:SI 0 "arith_reg_operand" "")
2528         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2529                      (match_operand:SI 2 "const_int_operand" "")))
2530    (clobber (reg:SI T_REG))]
2531   "TARGET_SH1 && reload_completed"
2532   [(use (reg:SI R0_REG))]
2533   "
2534 {
2535   gen_shifty_op (LSHIFTRT, operands);
2536   DONE;
2537 }")
2538
2539 (define_insn "lshrsi3_media"
2540   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2541         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2542                      (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2543   "TARGET_SHMEDIA"
2544   "@
2545         shlrd.l %1, %2, %0
2546         shlri.l %1, %2, %0"
2547   [(set_attr "type" "arith_media")])
2548
2549 (define_expand "lshrsi3"
2550   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2551                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2552                                 (match_operand:SI 2 "nonmemory_operand" "")))
2553               (clobber (reg:SI T_REG))])]
2554   ""
2555   "
2556 {
2557   if (TARGET_SHMEDIA)
2558     {
2559       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2560       DONE;
2561     }
2562   if (GET_CODE (operands[2]) == CONST_INT
2563       && sh_dynamicalize_shift_p (operands[2]))
2564     operands[2] = force_reg (SImode, operands[2]);
2565   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2566     {
2567       rtx count = copy_to_mode_reg (SImode, operands[2]);
2568       emit_insn (gen_negsi2 (count, count));
2569       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2570       DONE;
2571     }
2572   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2573     FAIL;
2574 }")
2575
2576 ;; ??? This should be a define expand.
2577
2578 (define_insn "ashldi3_k"
2579   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2580         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2581                    (const_int 1)))
2582    (clobber (reg:SI T_REG))]
2583   "TARGET_SH1"
2584   "shll %R0\;rotcl      %S0"
2585   [(set_attr "length" "4")
2586    (set_attr "type" "arith")])
2587
2588 (define_insn "ashldi3_media"
2589   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2590         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2591                    (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2592   "TARGET_SHMEDIA"
2593   "@
2594         shlld   %1, %2, %0
2595         shlli   %1, %2, %0"
2596   [(set_attr "type" "arith_media")])
2597
2598 (define_expand "ashldi3"
2599   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2600                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2601                               (match_operand:DI 2 "immediate_operand" "")))
2602               (clobber (reg:SI T_REG))])]
2603   ""
2604   "
2605 {
2606   if (TARGET_SHMEDIA)
2607     {
2608       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2609       DONE;
2610     }
2611   if (GET_CODE (operands[2]) != CONST_INT
2612       || INTVAL (operands[2]) != 1)
2613     FAIL;
2614 }")
2615
2616 ;; ??? This should be a define expand.
2617
2618 (define_insn "lshrdi3_k"
2619   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2620         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2621                      (const_int 1)))
2622    (clobber (reg:SI T_REG))]
2623   "TARGET_SH1"
2624   "shlr %S0\;rotcr      %R0"
2625   [(set_attr "length" "4")
2626    (set_attr "type" "arith")])
2627
2628 (define_insn "lshrdi3_media"
2629   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2630         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2631                      (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2632   "TARGET_SHMEDIA"
2633   "@
2634         shlrd   %1, %2, %0
2635         shlri   %1, %2, %0"
2636   [(set_attr "type" "arith_media")])
2637
2638 (define_expand "lshrdi3"
2639   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2640                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2641                                (match_operand:DI 2 "immediate_operand" "")))
2642              (clobber (reg:SI T_REG))])]
2643   ""
2644   "
2645 {
2646   if (TARGET_SHMEDIA)
2647     {
2648       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2649       DONE;
2650     }
2651   if (GET_CODE (operands[2]) != CONST_INT
2652       || INTVAL (operands[2]) != 1)
2653     FAIL;
2654 }")
2655
2656 ;; ??? This should be a define expand.
2657
2658 (define_insn "ashrdi3_k"
2659   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2660         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2661                      (const_int 1)))
2662    (clobber (reg:SI T_REG))]
2663   "TARGET_SH1"
2664   "shar %S0\;rotcr      %R0"
2665   [(set_attr "length" "4")
2666    (set_attr "type" "arith")])
2667
2668 (define_insn "ashrdi3_media"
2669   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2670         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2671                      (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2672   "TARGET_SHMEDIA"
2673   "@
2674         shard   %1, %2, %0
2675         shari   %1, %2, %0"
2676   [(set_attr "type" "arith_media")])
2677
2678 (define_expand "ashrdi3"
2679   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2680                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2681                                 (match_operand:DI 2 "immediate_operand" "")))
2682               (clobber (reg:SI T_REG))])]
2683   ""
2684   "
2685 {
2686   if (TARGET_SHMEDIA)
2687     {
2688       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2689       DONE;
2690     }
2691   if (GET_CODE (operands[2]) != CONST_INT
2692       || INTVAL (operands[2]) != 1)
2693     FAIL;
2694 }")
2695
2696 ;; combined left/right shift
2697
2698 (define_split
2699   [(set (match_operand:SI 0 "register_operand" "")
2700         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2701                            (match_operand:SI 2 "const_int_operand" ""))
2702                 (match_operand:SI 3 "const_int_operand" "")))]
2703   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2704   [(use (reg:SI R0_REG))]
2705   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2706    DONE;")
2707
2708 (define_split
2709   [(set (match_operand:SI 0 "register_operand" "")
2710         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2711                            (match_operand:SI 2 "const_int_operand" ""))
2712                 (match_operand:SI 3 "const_int_operand" "")))
2713    (clobber (reg:SI T_REG))]
2714   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2715   [(use (reg:SI R0_REG))]
2716   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2717    DONE;")
2718
2719 (define_insn ""
2720   [(set (match_operand:SI 0 "register_operand" "=r")
2721         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2722                            (match_operand:SI 2 "const_int_operand" "n"))
2723                 (match_operand:SI 3 "const_int_operand" "n")))
2724    (clobber (reg:SI T_REG))]
2725   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2726  "#"
2727   [(set (attr "length")
2728         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2729                (const_string "4")
2730                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2731                (const_string "6")
2732                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2733                (const_string "8")
2734                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2735                (const_string "10")
2736                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2737                (const_string "12")
2738                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2739                (const_string "14")
2740                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2741                (const_string "16")]
2742               (const_string "18")))
2743    (set_attr "type" "arith")])
2744
2745 (define_insn ""
2746   [(set (match_operand:SI 0 "register_operand" "=z")
2747         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2748                            (match_operand:SI 2 "const_int_operand" "n"))
2749                 (match_operand:SI 3 "const_int_operand" "n")))
2750    (clobber (reg:SI T_REG))]
2751   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2752  "#"
2753   [(set (attr "length")
2754         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2755                (const_string "4")
2756                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2757                (const_string "6")
2758                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2759                (const_string "8")]
2760               (const_string "10")))
2761    (set_attr "type" "arith")])
2762
2763 ;; shift left / and combination with a scratch register: The combine pass
2764 ;; does not accept the individual instructions, even though they are
2765 ;; cheap.  But it needs a precise description so that it is usable after
2766 ;; reload.
2767 (define_insn "and_shl_scratch"
2768   [(set (match_operand:SI 0 "register_operand" "=r,&r")
2769         (lshiftrt:SI
2770          (ashift:SI
2771           (and:SI
2772            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2773                         (match_operand:SI 2 "const_int_operand" "N,n"))
2774            (match_operand:SI 3 "" "0,r"))
2775           (match_operand:SI 4 "const_int_operand" "n,n"))
2776          (match_operand:SI 5 "const_int_operand" "n,n")))
2777    (clobber (reg:SI T_REG))]
2778   "TARGET_SH1"
2779   "#"
2780   [(set (attr "length")
2781         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2782                (const_string "4")
2783                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2784                (const_string "6")
2785                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2786                (const_string "8")
2787                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2788                (const_string "10")]
2789               (const_string "12")))
2790    (set_attr "type" "arith")])
2791
2792 (define_split
2793   [(set (match_operand:SI 0 "register_operand" "")
2794         (lshiftrt:SI
2795          (ashift:SI
2796           (and:SI
2797            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2798                         (match_operand:SI 2 "const_int_operand" ""))
2799            (match_operand:SI 3 "register_operand" ""))
2800           (match_operand:SI 4 "const_int_operand" ""))
2801          (match_operand:SI 5 "const_int_operand" "")))
2802    (clobber (reg:SI T_REG))]
2803   "TARGET_SH1"
2804   [(use (reg:SI R0_REG))]
2805   "
2806 {
2807   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2808
2809   if (INTVAL (operands[2]))
2810     {
2811       gen_shifty_op (LSHIFTRT, operands);
2812     }
2813   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2814   operands[2] = operands[4];
2815   gen_shifty_op (ASHIFT, operands);
2816   if (INTVAL (operands[5]))
2817     {
2818       operands[2] = operands[5];
2819       gen_shifty_op (LSHIFTRT, operands);
2820     }
2821   DONE;
2822 }")
2823
2824 ;; signed left/right shift combination.
2825 (define_split
2826   [(set (match_operand:SI 0 "register_operand" "")
2827         (sign_extract:SI
2828          (ashift:SI (match_operand:SI 1 "register_operand" "")
2829                     (match_operand:SI 2 "const_int_operand" ""))
2830          (match_operand:SI 3 "const_int_operand" "")
2831          (const_int 0)))
2832    (clobber (reg:SI T_REG))]
2833   "TARGET_SH1"
2834   [(use (reg:SI R0_REG))]
2835   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2836    DONE;")
2837
2838 (define_insn "shl_sext_ext"
2839   [(set (match_operand:SI 0 "register_operand" "=r")
2840         (sign_extract:SI
2841          (ashift:SI (match_operand:SI 1 "register_operand" "0")
2842                     (match_operand:SI 2 "const_int_operand" "n"))
2843          (match_operand:SI 3 "const_int_operand" "n")
2844          (const_int 0)))
2845    (clobber (reg:SI T_REG))]
2846   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2847   "#"
2848   [(set (attr "length")
2849         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2850                (const_string "2")
2851                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2852                (const_string "4")
2853                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2854                (const_string "6")
2855                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2856                (const_string "8")
2857                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2858                (const_string "10")
2859                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2860                (const_string "12")
2861                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2862                (const_string "14")
2863                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2864                (const_string "16")]
2865               (const_string "18")))
2866     (set_attr "type" "arith")])
2867
2868 (define_insn "shl_sext_sub"
2869   [(set (match_operand:SI 0 "register_operand" "=z")
2870         (sign_extract:SI
2871          (ashift:SI (match_operand:SI 1 "register_operand" "0")
2872                     (match_operand:SI 2 "const_int_operand" "n"))
2873          (match_operand:SI 3 "const_int_operand" "n")
2874          (const_int 0)))
2875    (clobber (reg:SI T_REG))]
2876   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2877   "#"
2878   [(set (attr "length")
2879         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2880                (const_string "6")
2881                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2882                (const_string "8")
2883                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2884                (const_string "10")
2885                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2886                (const_string "12")]
2887               (const_string "14")))
2888     (set_attr "type" "arith")])
2889
2890 ;; These patterns are found in expansions of DImode shifts by 16, and
2891 ;; allow the xtrct instruction to be generated from C source.
2892
2893 (define_insn "xtrct_left"
2894   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2895         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2896                            (const_int 16))
2897                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2898                              (const_int 16))))]
2899   "TARGET_SH1"
2900   "xtrct        %1,%0"
2901   [(set_attr "type" "arith")])
2902
2903 (define_insn "xtrct_right"
2904   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2905         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2906                              (const_int 16))
2907                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2908                            (const_int 16))))]
2909   "TARGET_SH1"
2910   "xtrct        %2,%0"
2911   [(set_attr "type" "arith")])
2912
2913 ;; -------------------------------------------------------------------------
2914 ;; Unary arithmetic
2915 ;; -------------------------------------------------------------------------
2916
2917 (define_insn "negc"
2918   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2919         (neg:SI (plus:SI (reg:SI T_REG)
2920                          (match_operand:SI 1 "arith_reg_operand" "r"))))
2921    (set (reg:SI T_REG)
2922         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2923                (const_int 0)))]
2924   "TARGET_SH1"
2925   "negc %1,%0"
2926   [(set_attr "type" "arith")])
2927
2928 (define_insn "*negdi_media"
2929   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2930         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2931   "TARGET_SHMEDIA"
2932   "sub  r63, %1, %0"
2933   [(set_attr "type" "arith_media")])
2934
2935 (define_expand "negdi2"
2936   [(set (match_operand:DI 0 "arith_reg_operand" "")
2937         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
2938   ""
2939   "
2940 {
2941   if (TARGET_SH1)
2942     {
2943       int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2944       int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2945
2946       rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2947       rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2948
2949       rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2950       rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2951
2952       emit_insn (gen_clrt ());
2953       emit_insn (gen_negc (low_dst, low_src));
2954       emit_insn (gen_negc (high_dst, high_src));
2955       DONE;
2956     }
2957 }")
2958
2959 (define_insn "negsi2"
2960   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2961         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2962   "TARGET_SH1"
2963   "neg  %1,%0"
2964   [(set_attr "type" "arith")])
2965
2966 (define_insn "one_cmplsi2"
2967   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2968         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2969   "TARGET_SH1"
2970   "not  %1,%0"
2971   [(set_attr "type" "arith")])
2972
2973 (define_expand "one_cmpldi2"
2974   [(set (match_operand:DI 0 "arith_reg_operand" "")
2975         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2976                 (const_int -1)))]
2977   "TARGET_SHMEDIA" "")
2978 \f
2979 ;; -------------------------------------------------------------------------
2980 ;; Zero extension instructions
2981 ;; -------------------------------------------------------------------------
2982
2983 (define_insn "zero_extendsidi2"
2984   [(set (match_operand:DI 0 "register_operand" "=r")
2985         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
2986   "TARGET_SHMEDIA"
2987   "addz.l       %1, r63, %0"
2988   [(set_attr "type" "arith_media")])
2989
2990 (define_insn "zero_extendhidi2"
2991   [(set (match_operand:DI 0 "register_operand" "=r,r")
2992         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
2993   "TARGET_SHMEDIA"
2994   "@
2995         #
2996         ld%M1.uw        %m1, %0"
2997   [(set_attr "type" "*,load_media")])
2998
2999 (define_split
3000   [(set (match_operand:DI 0 "register_operand" "")
3001         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3002   "TARGET_SHMEDIA && reload_completed"
3003   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3004    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
3005   "
3006 {
3007   if (GET_CODE (operands[1]) == TRUNCATE)
3008     operands[1] = XEXP (operands[1], 0);
3009 }")
3010
3011 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
3012 ;; reload the entire truncate expression.
3013 (define_insn_and_split "*loaddi_trunc"
3014   [(set (match_operand 0 "int_gpr_dest" "=r")
3015         (truncate (match_operand:DI 1 "memory_operand" "m")))]
3016   "TARGET_SHMEDIA && reload_completed"
3017   "#"
3018   "TARGET_SHMEDIA && reload_completed"
3019   [(set (match_dup 0) (match_dup 1))]
3020   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
3021
3022 (define_insn "zero_extendqidi2"
3023   [(set (match_operand:DI 0 "register_operand" "=r,r")
3024         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3025   "TARGET_SHMEDIA"
3026   "@
3027         andi    %1, 255, %0
3028         ld%M1.ub        %m1, %0"
3029   [(set_attr "type" "arith_media,load_media")])
3030
3031 (define_expand "zero_extendhisi2"
3032   [(set (match_operand:SI 0 "arith_reg_operand" "")
3033         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3034   ""
3035   "
3036 {
3037   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3038     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3039 }")
3040
3041 (define_insn "*zero_extendhisi2_compact"
3042   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3043         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
3044   "TARGET_SH1"
3045   "extu.w       %1,%0"
3046   [(set_attr "type" "arith")])
3047
3048 (define_insn "*zero_extendhisi2_media"
3049   [(set (match_operand:SI 0 "register_operand" "=r,r")
3050         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3051   "TARGET_SHMEDIA"
3052   "@
3053         #
3054         ld%M1.uw        %m1, %0"
3055   [(set_attr "type" "arith_media,load_media")])
3056
3057 (define_split
3058   [(set (match_operand:SI 0 "register_operand" "")
3059         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3060   "TARGET_SHMEDIA && reload_completed"
3061   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3062    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3063   "
3064 {
3065   if (GET_CODE (operands[1]) == TRUNCATE)
3066     operands[1] = XEXP (operands[1], 0);
3067 }")
3068
3069 (define_expand "zero_extendqisi2"
3070   [(set (match_operand:SI 0 "arith_reg_operand" "")
3071         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3072   ""
3073   "
3074 {
3075   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3076     operands[1] = copy_to_mode_reg (QImode, operands[1]);
3077 }")
3078
3079 (define_insn "*zero_extendqisi2_compact"
3080   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3081         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
3082   "TARGET_SH1"
3083   "extu.b       %1,%0"
3084   [(set_attr "type" "arith")])
3085
3086 (define_insn "*zero_extendqisi2_media"
3087   [(set (match_operand:SI 0 "register_operand" "=r,r")
3088         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3089   "TARGET_SHMEDIA"
3090   "@
3091         andi    %1, 255, %0
3092         ld%M1.ub        %m1, %0"
3093   [(set_attr "type" "arith_media,load_media")])
3094
3095 (define_insn "zero_extendqihi2"
3096   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3097         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
3098   "TARGET_SH1"
3099   "extu.b       %1,%0"
3100   [(set_attr "type" "arith")])
3101
3102 ;; -------------------------------------------------------------------------
3103 ;; Sign extension instructions
3104 ;; -------------------------------------------------------------------------
3105
3106 ;; ??? This should be a define expand.
3107 ;; ??? Or perhaps it should be dropped?
3108
3109 ;; convert_move generates good code for SH[1-4].
3110 (define_insn "extendsidi2"
3111   [(set (match_operand:DI 0 "register_operand" "=r,r")
3112         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3113   "TARGET_SHMEDIA"
3114   "@
3115         add.l   %1, r63, %0
3116         ld%M1.l %m1, %0"
3117   [(set_attr "type" "arith_media,load_media")])
3118
3119 (define_insn "extendhidi2"
3120   [(set (match_operand:DI 0 "register_operand" "=r,r")
3121         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3122   "TARGET_SHMEDIA"
3123   "@
3124         #
3125         ld%M1.w %m1, %0"
3126   [(set_attr "type" "*,load_media")])
3127
3128 (define_split
3129   [(set (match_operand:DI 0 "register_operand" "")
3130         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3131   "TARGET_SHMEDIA && reload_completed"
3132   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3133    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3134   "
3135 {
3136   if (GET_CODE (operands[1]) == TRUNCATE)
3137     operands[1] = XEXP (operands[1], 0);
3138 }")
3139
3140 (define_insn "extendqidi2"
3141   [(set (match_operand:DI 0 "register_operand" "=r,r")
3142         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3143   "TARGET_SHMEDIA"
3144   "@
3145         #
3146         ld%M1.b %m1, %0"
3147   [(set_attr "type" "*,load_media")])
3148
3149 (define_split
3150   [(set (match_operand:DI 0 "register_operand" "")
3151         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
3152   "TARGET_SHMEDIA && reload_completed"
3153   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3154    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3155   "
3156 {
3157   if (GET_CODE (operands[1]) == TRUNCATE)
3158     operands[1] = XEXP (operands[1], 0);
3159 }")
3160
3161 (define_expand "extendhisi2"
3162   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3163         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3164   ""
3165   "")
3166
3167 (define_insn "*extendhisi2_compact"
3168   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3169         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3170   "TARGET_SH1"
3171   "@
3172         exts.w  %1,%0
3173         mov.w   %1,%0"
3174   [(set_attr "type" "arith,load")])
3175
3176 (define_insn "*extendhisi2_media"
3177   [(set (match_operand:SI 0 "register_operand" "=r,r")
3178         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3179   "TARGET_SHMEDIA"
3180   "@
3181         #
3182         ld%M1.w %m1, %0"
3183   [(set_attr "type" "arith_media,load_media")])
3184
3185 (define_split
3186   [(set (match_operand:SI 0 "register_operand" "")
3187         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3188   "TARGET_SHMEDIA && reload_completed"
3189   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3190    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3191   "
3192 {
3193   if (GET_CODE (operands[1]) == TRUNCATE)
3194     operands[1] = XEXP (operands[1], 0);
3195 }")
3196
3197 (define_expand "extendqisi2"
3198   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3199         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3200   ""
3201   "")
3202
3203 (define_insn "*extendqisi2_compact"
3204   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3205         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3206   "TARGET_SH1"
3207   "@
3208         exts.b  %1,%0
3209         mov.b   %1,%0"
3210   [(set_attr "type" "arith,load")])
3211
3212 (define_insn "*extendqisi2_media"
3213   [(set (match_operand:SI 0 "register_operand" "=r,r")
3214         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3215   "TARGET_SHMEDIA"
3216   "@
3217         #
3218         ld%M1.b %m1, %0"
3219   [(set_attr "type" "arith_media,load_media")])
3220
3221 (define_split
3222   [(set (match_operand:SI 0 "register_operand" "")
3223         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
3224   "TARGET_SHMEDIA && reload_completed"
3225   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3226    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3227    "
3228 {
3229   if (GET_CODE (operands[1]) == TRUNCATE)
3230     operands[1] = XEXP (operands[1], 0);
3231 }")
3232
3233 (define_insn "extendqihi2"
3234   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3235         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3236   "TARGET_SH1"
3237   "@
3238         exts.b  %1,%0
3239         mov.b   %1,%0"
3240   [(set_attr "type" "arith,load")])
3241
3242 /* It would seem useful to combine the truncXi patterns into the movXi
3243    patterns, but unary operators are ignored when matching constraints,
3244    so we need separate patterns.  */
3245 (define_insn "truncdisi2"
3246   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
3247         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3248   "TARGET_SHMEDIA"
3249   "@
3250         add.l   %1, r63, %0
3251         st%M0.l %m0, %1
3252         fst%M0.s        %m0, %T1
3253         fmov.ls %1, %0
3254         fmov.sl %T1, %0
3255         fmov.s  %T1, %0"
3256   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3257
3258
3259 (define_insn "truncdihi2"
3260   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
3261         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3262   "TARGET_SHMEDIA"
3263   "@
3264         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3265         st%M0.w %m0, %1"
3266   [(set_attr "type"   "arith_media,store_media")
3267    (set_attr "length" "8,4")])
3268
3269 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3270 ; Because we use zero extension, we can't provide signed QImode compares
3271 ; using a simple compare or conditional banch insn.
3272 (define_insn "truncdiqi2"
3273   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3274         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3275   "TARGET_SHMEDIA"
3276   "@
3277         andi    %1, 255, %0
3278         st%M0.b %m0, %1"
3279   [(set_attr "type"   "arith_media,store")])
3280
3281 ;; -------------------------------------------------------------------------
3282 ;; Move instructions
3283 ;; -------------------------------------------------------------------------
3284
3285 ;; define push and pop so it is easy for sh.c
3286 ;; We can't use push and pop on SHcompact because the stack must always
3287 ;; be 8-byte aligned.
3288
3289 (define_expand "push"
3290   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3291         (match_operand:SI 0 "register_operand" "r,l,x"))]
3292   "TARGET_SH1 && ! TARGET_SH5"
3293   "")
3294
3295 (define_expand "pop"
3296   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3297         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3298   "TARGET_SH1 && ! TARGET_SH5"
3299   "")
3300
3301 (define_expand "push_e"
3302   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3303                    (match_operand:SF 0 "" ""))
3304               (use (reg:PSI FPSCR_REG))
3305               (clobber (scratch:SI))])]
3306   "TARGET_SH1 && ! TARGET_SH5"
3307   "")
3308
3309 (define_insn "push_fpul"
3310   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3311   "TARGET_SH2E && ! TARGET_SH5"
3312   "sts.l        fpul,@-r15"
3313   [(set_attr "type" "store")
3314    (set_attr "late_fp_use" "yes")
3315    (set_attr "hit_stack" "yes")])
3316
3317 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3318 ;; so use that.
3319 (define_expand "push_4"
3320   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3321                    (match_operand:DF 0 "" ""))
3322               (use (reg:PSI FPSCR_REG))
3323               (clobber (scratch:SI))])]
3324   "TARGET_SH1 && ! TARGET_SH5"
3325   "")
3326
3327 (define_expand "pop_e"
3328   [(parallel [(set (match_operand:SF 0 "" "")
3329               (mem:SF (post_inc:SI (reg:SI SP_REG))))
3330               (use (reg:PSI FPSCR_REG))
3331               (clobber (scratch:SI))])]
3332   "TARGET_SH1 && ! TARGET_SH5"
3333   "")
3334
3335 (define_insn "pop_fpul"
3336   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3337   "TARGET_SH2E && ! TARGET_SH5"
3338   "lds.l        @r15+,fpul"
3339   [(set_attr "type" "load")
3340    (set_attr "hit_stack" "yes")])
3341
3342 (define_expand "pop_4"
3343   [(parallel [(set (match_operand:DF 0 "" "")
3344                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
3345               (use (reg:PSI FPSCR_REG))
3346               (clobber (scratch:SI))])]
3347   "TARGET_SH1 && ! TARGET_SH5"
3348   "")
3349
3350 (define_expand "push_fpscr"
3351   [(const_int 0)]
3352   "TARGET_SH2E"
3353   "
3354 {
3355   rtx insn = emit_insn (gen_fpu_switch (gen_rtx_MEM (PSImode,
3356                                                  gen_rtx_PRE_DEC (Pmode,
3357                                                           stack_pointer_rtx)),
3358                                         get_fpscr_rtx ()));
3359   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
3360   DONE;
3361 }")
3362
3363 (define_expand "pop_fpscr"
3364   [(const_int 0)]
3365   "TARGET_SH2E"
3366   "
3367 {
3368   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
3369                                         gen_rtx_MEM (PSImode,
3370                                                  gen_rtx_POST_INC (Pmode,
3371                                                           stack_pointer_rtx))));
3372   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
3373   DONE;
3374 }")
3375
3376 ;; These two patterns can happen as the result of optimization, when
3377 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3378 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3379
3380 (define_insn "clrt"
3381   [(set (reg:SI T_REG) (const_int 0))]
3382   "TARGET_SH1"
3383   "clrt")
3384
3385 (define_insn "sett"
3386   [(set (reg:SI T_REG) (const_int 1))]
3387   "TARGET_SH1"
3388   "sett")
3389
3390 ;; t/r must come after r/r, lest reload will try to reload stuff like
3391 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3392 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3393 (define_insn "movsi_i"
3394   [(set (match_operand:SI 0 "general_movdst_operand"
3395             "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3396         (match_operand:SI 1 "general_movsrc_operand"
3397          "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3398   "TARGET_SH1
3399    && ! TARGET_SH2E
3400    && ! TARGET_SH2A
3401    && (register_operand (operands[0], SImode)
3402        || register_operand (operands[1], SImode))"
3403   "@
3404         mov.l   %1,%0
3405         mov     %1,%0
3406         cmp/pl  %1
3407         mov.l   %1,%0
3408         sts     %1,%0
3409         sts     %1,%0
3410         movt    %0
3411         mov.l   %1,%0
3412         sts.l   %1,%0
3413         sts.l   %1,%0
3414         lds     %1,%0
3415         lds     %1,%0
3416         lds.l   %1,%0
3417         lds.l   %1,%0
3418         fake    %1,%0"
3419   [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3420    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3421
3422 ;; t/r must come after r/r, lest reload will try to reload stuff like
3423 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3424 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3425 ;; will require a reload.
3426 ;; ??? We can't include f/f because we need the proper FPSCR setting when
3427 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
3428 (define_insn "movsi_ie"
3429   [(set (match_operand:SI 0 "general_movdst_operand"
3430             "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
3431         (match_operand:SI 1 "general_movsrc_operand"
3432          "Q,rI08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
3433   "(TARGET_SH2E || TARGET_SH2A)
3434    && (register_operand (operands[0], SImode)
3435        || register_operand (operands[1], SImode))"
3436   "@
3437         mov.l   %1,%0
3438         mov     %1,%0
3439         movi20  %1,%0
3440         cmp/pl  %1
3441         mov.l   %1,%0
3442         sts     %1,%0
3443         sts     %1,%0
3444         movt    %0
3445         mov.l   %1,%0
3446         sts.l   %1,%0
3447         sts.l   %1,%0
3448         lds     %1,%0
3449         lds     %1,%0
3450         lds.l   %1,%0
3451         lds.l   %1,%0
3452         lds.l   %1,%0
3453         sts.l   %1,%0
3454         fake    %1,%0
3455         lds     %1,%0
3456         sts     %1,%0
3457         fsts    fpul,%0
3458         flds    %1,fpul
3459         fmov    %1,%0
3460         ! move optimized away"
3461   [(set_attr "type" "pcload_si,move,move,*,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,load,store,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
3462    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
3463    (set_attr "length" "*,*,4,*,4,*,*,*,4,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3464
3465 (define_insn "movsi_i_lowpart"
3466   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3467         (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
3468    "TARGET_SH1
3469     && (register_operand (operands[0], SImode)
3470         || register_operand (operands[1], SImode))"
3471   "@
3472         mov.l   %1,%0
3473         mov     %1,%0
3474         mov.l   %1,%0
3475         sts     %1,%0
3476         sts     %1,%0
3477         movt    %0
3478         mov.l   %1,%0
3479         fake    %1,%0"
3480   [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
3481
3482 (define_insn_and_split "load_ra"
3483   [(set (match_operand:SI 0 "general_movdst_operand" "")
3484         (unspec:SI [(match_operand 1 "register_operand" "")] UNSPEC_RA))]
3485   "TARGET_SH1"
3486   "#"
3487   "&& ! currently_expanding_to_rtl"
3488   [(set (match_dup 0) (match_dup 1))]
3489   "
3490 {
3491   if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
3492     operands[1] = gen_rtx_MEM (SImode, return_address_pointer_rtx);
3493 }")
3494
3495 (define_insn "*movsi_media"
3496   [(set (match_operand:SI 0 "general_movdst_operand"
3497                 "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
3498         (match_operand:SI 1 "general_movsrc_operand"
3499          "r,I16C16,nCpg,m,rZ,m,f,rZ,f,f,r,*b,Csy"))]
3500   "TARGET_SHMEDIA_FPU
3501    && (register_operand (operands[0], SImode)
3502        || sh_register_operand (operands[1], SImode))"
3503   "@
3504         add.l   %1, r63, %0
3505         movi    %1, %0
3506         #
3507         ld%M1.l %m1, %0
3508         st%M0.l %m0, %N1
3509         fld%M1.s        %m1, %0
3510         fst%M0.s        %m0, %1
3511         fmov.ls %N1, %0
3512         fmov.sl %1, %0
3513         fmov.s  %1, %0
3514         ptabs   %1, %0
3515         gettr   %1, %0
3516         pt      %1, %0"
3517   [(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")
3518    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3519
3520 (define_insn "*movsi_media_nofpu"
3521   [(set (match_operand:SI 0 "general_movdst_operand"
3522                 "=r,r,r,r,m,*b,r,b")
3523         (match_operand:SI 1 "general_movsrc_operand"
3524          "r,I16C16,nCpg,m,rZ,r,*b,Csy"))]
3525   "TARGET_SHMEDIA
3526    && (register_operand (operands[0], SImode)
3527        || sh_register_operand (operands[1], SImode))"
3528   "@
3529         add.l   %1, r63, %0
3530         movi    %1, %0
3531         #
3532         ld%M1.l %m1, %0
3533         st%M0.l %m0, %N1
3534         ptabs   %1, %0
3535         gettr   %1, %0
3536         pt      %1, %0"
3537   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3538    (set_attr "length" "4,4,8,4,4,4,4,12")])
3539
3540 (define_split
3541   [(set (match_operand:SI 0 "arith_reg_operand" "")
3542         (match_operand:SI 1 "immediate_operand" ""))]
3543   "TARGET_SHMEDIA && reload_completed
3544    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3545   [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3546   "
3547 {
3548   operands[2] = shallow_copy_rtx (operands[1]);
3549   PUT_MODE (operands[2], DImode);
3550 }")
3551
3552 (define_split
3553   [(set (match_operand:SI 0 "register_operand" "")
3554         (match_operand:SI 1 "immediate_operand" ""))]
3555   "TARGET_SHMEDIA && reload_completed
3556    && ((GET_CODE (operands[1]) == CONST_INT
3557         && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
3558        || GET_CODE (operands[1]) == CONST_DOUBLE)"
3559   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3560
3561 (define_expand "movsi"
3562   [(set (match_operand:SI 0 "general_movdst_operand" "")
3563         (match_operand:SI 1 "general_movsrc_operand" ""))]
3564   ""
3565   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
3566
3567 (define_expand "ic_invalidate_line"
3568   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
3569                                 (match_dup 1)] UNSPEC_ICACHE)
3570               (clobber (scratch:SI))])]
3571   "TARGET_HARD_SH4 || TARGET_SH5"
3572   "
3573 {
3574   if (TARGET_SHMEDIA)
3575     {
3576       emit_insn (gen_ic_invalidate_line_media (operands[0]));
3577       DONE;
3578     }
3579   else if (TARGET_SHCOMPACT)
3580     {
3581       operands[1] = function_symbol (\"__ic_invalidate\");
3582       operands[1] = force_reg (Pmode, operands[1]);
3583       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3584       DONE;
3585     }
3586   else if (TARGET_SH4A_ARCH)
3587     {
3588       emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
3589       DONE;
3590     }
3591   operands[0] = force_reg (Pmode, operands[0]);
3592   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3593                                                                Pmode)));
3594 }")
3595
3596 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
3597 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3598 ;; the requirement *1*00 for associative address writes.  The alignment of
3599 ;; %0 implies that its least significant bit is cleared,
3600 ;; thus we clear the V bit of a matching entry if there is one.
3601 (define_insn "ic_invalidate_line_i"
3602   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
3603                      (match_operand:SI 1 "register_operand" "r")]
3604                      UNSPEC_ICACHE)
3605    (clobber (match_scratch:SI 2 "=&r"))]
3606   "TARGET_HARD_SH4"
3607   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
3608   [(set_attr "length" "8")
3609    (set_attr "type" "cwb")])
3610
3611 (define_insn "ic_invalidate_line_sh4a"
3612   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
3613                     UNSPEC_ICACHE)]
3614   "TARGET_SH4A_ARCH"
3615   "ocbwb\\t@%0\;synco\;icbi\\t@%0"
3616   [(set_attr "length" "16")
3617    (set_attr "type" "cwb")])
3618
3619 ;; ??? could make arg 0 an offsettable memory operand to allow to save
3620 ;; an add in the code that calculates the address.
3621 (define_insn "ic_invalidate_line_media"
3622   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3623                     UNSPEC_ICACHE)]
3624   "TARGET_SHMEDIA"
3625   "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
3626   [(set_attr "length" "16")
3627    (set_attr "type" "invalidate_line_media")])
3628
3629 (define_insn "ic_invalidate_line_compact"
3630   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3631                      (match_operand:SI 1 "register_operand" "r")]
3632                     UNSPEC_ICACHE)
3633    (clobber (reg:SI PR_REG))]
3634   "TARGET_SHCOMPACT"
3635   "jsr @%1%#"
3636   [(set_attr "type" "sfunc")
3637    (set_attr "needs_delay_slot" "yes")])
3638
3639 (define_expand "initialize_trampoline"
3640   [(match_operand:SI 0 "" "")
3641    (match_operand:SI 1 "" "")
3642    (match_operand:SI 2 "" "")]
3643   "TARGET_SHCOMPACT"
3644   "
3645 {
3646   rtx sfun, tramp;
3647
3648   tramp = force_reg (Pmode, operands[0]);
3649   sfun = force_reg (Pmode, function_symbol (\"__init_trampoline\"));
3650   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3651   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3652
3653   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3654   DONE;
3655 }")
3656
3657 (define_insn "initialize_trampoline_compact"
3658   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3659                      (match_operand:SI 1 "register_operand" "r")
3660                      (reg:SI R2_REG) (reg:SI R3_REG)]
3661                     UNSPEC_INIT_TRAMP)
3662
3663    (clobber (reg:SI PR_REG))]
3664   "TARGET_SHCOMPACT"
3665   "jsr @%1%#"
3666   [(set_attr "type" "sfunc")
3667    (set_attr "needs_delay_slot" "yes")])
3668
3669 (define_insn "movqi_i"
3670   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3671         (match_operand:QI 1 "general_movsrc_operand"  "ri,m,r,t,l,r"))]
3672   "TARGET_SH1
3673    && (arith_reg_operand (operands[0], QImode)
3674        || arith_reg_operand (operands[1], QImode))"
3675   "@
3676         mov     %1,%0
3677         mov.b   %1,%0
3678         mov.b   %1,%0
3679         movt    %0
3680         sts     %1,%0
3681         lds     %1,%0"
3682  [(set_attr "type" "move,load,store,move,move,move")])
3683
3684 (define_insn "*movqi_media"
3685   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
3686         (match_operand:QI 1 "general_movsrc_operand" "r,I16C16,m,rZ"))]
3687   "TARGET_SHMEDIA
3688    && (arith_reg_operand (operands[0], QImode)
3689        || arith_reg_or_0_operand (operands[1], QImode))"
3690   "@
3691         add.l   %1, r63, %0
3692         movi    %1, %0
3693         ld%M1.ub        %m1, %0
3694         st%M0.b %m0, %N1"
3695   [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
3696
3697 (define_expand "movqi"
3698   [(set (match_operand:QI 0 "general_operand" "")
3699         (match_operand:QI 1 "general_operand"  ""))]
3700   ""
3701   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
3702
3703 (define_expand "reload_inqi"
3704   [(set (match_operand:SI 2 "" "=&r")
3705         (match_operand:QI 1 "inqhi_operand" ""))
3706    (set (match_operand:QI 0 "arith_reg_operand" "=r")
3707         (truncate:QI (match_dup 3)))]
3708   "TARGET_SHMEDIA"
3709   "
3710 {
3711   rtx inner = XEXP (operands[1], 0);
3712   int regno = REGNO (inner);
3713
3714   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3715   operands[1] = gen_rtx_REG (SImode, regno);
3716   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3717 }")
3718
3719 /* When storing r0, we have to avoid reg+reg addressing.  */
3720 (define_insn "movhi_i"
3721   [(set (match_operand:HI 0 "general_movdst_operand"   "=r,r,r,r,m,r,l,r")
3722         (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
3723   "TARGET_SH1
3724    && (arith_reg_operand (operands[0], HImode)
3725        || arith_reg_operand (operands[1], HImode))
3726    && (GET_CODE (operands[0]) != MEM
3727        || GET_CODE (XEXP (operands[0], 0)) != PLUS
3728        || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
3729        || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
3730   "@
3731         mov.w   %1,%0
3732         mov     %1,%0
3733         mov.w   %1,%0
3734         movt    %0
3735         mov.w   %1,%0
3736         sts     %1,%0
3737         lds     %1,%0
3738         fake    %1,%0"
3739   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
3740
3741 (define_insn "*movhi_media"
3742   [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
3743         (match_operand:HI 1 "general_movsrc_operand" "r,I16C16,n,m,rZ"))]
3744   "TARGET_SHMEDIA
3745    && (arith_reg_operand (operands[0], HImode)
3746        || arith_reg_or_0_operand (operands[1], HImode))"
3747   "@
3748         add.l   %1, r63, %0
3749         movi    %1, %0
3750         #
3751         ld%M1.w %m1, %0
3752         st%M0.w %m0, %N1"
3753   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
3754
3755 (define_split
3756   [(set (match_operand:HI 0 "register_operand" "")
3757         (match_operand:HI 1 "immediate_operand" ""))]
3758   "TARGET_SHMEDIA && reload_completed
3759    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3760   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3761
3762 (define_expand "movhi"
3763   [(set (match_operand:HI 0 "general_movdst_operand" "")
3764         (match_operand:HI 1 "general_movsrc_operand"  ""))]
3765   ""
3766   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3767
3768 (define_expand "reload_inhi"
3769   [(set (match_operand:SI 2 "" "=&r")
3770         (match_operand:HI 1 "inqhi_operand" ""))
3771    (set (match_operand:HI 0 "arith_reg_operand" "=r")
3772         (truncate:HI (match_dup 3)))]
3773   "TARGET_SHMEDIA"
3774   "
3775 {
3776   rtx inner = XEXP (operands[1], 0);
3777   int regno = REGNO (inner);
3778
3779   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3780   operands[1] = gen_rtx_REG (SImode, regno);
3781   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3782 }")
3783
3784 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3785 ;; compiled with -m2 -ml -O3 -funroll-loops
3786 (define_insn "*movdi_i"
3787   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3788         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
3789   "TARGET_SH1
3790    && (arith_reg_operand (operands[0], DImode)
3791        || arith_reg_operand (operands[1], DImode))"
3792   "* return output_movedouble (insn, operands, DImode);"
3793   [(set_attr "length" "4")
3794    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
3795
3796 ;; If the output is a register and the input is memory or a register, we have
3797 ;; to be careful and see which word needs to be loaded first.
3798
3799 (define_split
3800   [(set (match_operand:DI 0 "general_movdst_operand" "")
3801         (match_operand:DI 1 "general_movsrc_operand" ""))]
3802   "TARGET_SH1 && reload_completed"
3803   [(set (match_dup 2) (match_dup 3))
3804    (set (match_dup 4) (match_dup 5))]
3805   "
3806 {
3807   int regno;
3808
3809   if ((GET_CODE (operands[0]) == MEM
3810        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3811       || (GET_CODE (operands[1]) == MEM
3812           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3813     FAIL;
3814
3815   if (GET_CODE (operands[0]) == REG)
3816     regno = REGNO (operands[0]);
3817   else if (GET_CODE (operands[0]) == SUBREG)
3818     regno = subreg_regno (operands[0]);
3819   else if (GET_CODE (operands[0]) == MEM)
3820     regno = -1;
3821   else
3822     abort ();
3823
3824   if (regno == -1
3825       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
3826     {
3827       operands[2] = operand_subword (operands[0], 0, 0, DImode);
3828       operands[3] = operand_subword (operands[1], 0, 0, DImode);
3829       operands[4] = operand_subword (operands[0], 1, 0, DImode);
3830       operands[5] = operand_subword (operands[1], 1, 0, DImode);
3831     }
3832   else
3833     {
3834       operands[2] = operand_subword (operands[0], 1, 0, DImode);
3835       operands[3] = operand_subword (operands[1], 1, 0, DImode);
3836       operands[4] = operand_subword (operands[0], 0, 0, DImode);
3837       operands[5] = operand_subword (operands[1], 0, 0, DImode);
3838     }
3839
3840   if (operands[2] == 0 || operands[3] == 0
3841       || operands[4] == 0 || operands[5] == 0)
3842     FAIL;
3843 }")
3844
3845 (define_insn "*movdi_media"
3846   [(set (match_operand:DI 0 "general_movdst_operand"
3847                  "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
3848         (match_operand:DI 1 "general_movsrc_operand"
3849          "r,I16C16,nCpgF,m,rlZ,m,f,rZ,f,f,r,*b,Csy"))]
3850   "TARGET_SHMEDIA_FPU
3851    && (register_operand (operands[0], DImode)
3852        || sh_register_operand (operands[1], DImode))"
3853   "@
3854         add     %1, r63, %0
3855         movi    %1, %0
3856         #
3857         ld%M1.q %m1, %0
3858         st%M0.q %m0, %N1
3859         fld%M1.d        %m1, %0
3860         fst%M0.d        %m0, %1
3861         fmov.qd %N1, %0
3862         fmov.dq %1, %0
3863         fmov.d  %1, %0
3864         ptabs   %1, %0
3865         gettr   %1, %0
3866         pt      %1, %0"
3867   [(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")
3868    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3869
3870 (define_insn "*movdi_media_nofpu"
3871   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
3872         (match_operand:DI 1 "general_movsrc_operand" "r,I16C16,nCpgF,m,rlZ,r,*b,Csy"))]
3873   "TARGET_SHMEDIA
3874    && (register_operand (operands[0], DImode)
3875        || sh_register_operand (operands[1], DImode))"
3876   "@
3877         add     %1, r63, %0
3878         movi    %1, %0
3879         #
3880         ld%M1.q %m1, %0
3881         st%M0.q %m0, %N1
3882         ptabs   %1, %0
3883         gettr   %1, %0
3884         pt      %1, %0"
3885   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3886    (set_attr "length" "4,4,16,4,4,4,4,*")])
3887
3888 (define_split
3889   [(set (match_operand:DI 0 "arith_reg_operand" "")
3890         (match_operand:DI 1 "immediate_operand" ""))]
3891   "TARGET_SHMEDIA && reload_completed
3892    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3893   [(set (match_dup 0) (match_dup 1))]
3894   "
3895 {
3896   rtx insn;
3897
3898   if (TARGET_SHMEDIA64)
3899     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3900   else
3901     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3902
3903   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3904                                         REG_NOTES (insn));
3905
3906   DONE;
3907 }")
3908
3909 (define_expand "movdi_const"
3910   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3911         (const:DI (sign_extend:DI
3912                    (truncate:HI
3913                     (ashiftrt:DI
3914                      (match_operand:DI 1 "immediate_operand" "s")
3915                      (const_int 48))))))
3916    (set (match_dup 0)
3917         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3918                 (zero_extend:DI
3919                  (truncate:HI
3920                   (const:DI
3921                    (sign_extend:DI
3922                     (truncate:HI
3923                      (ashiftrt:SI
3924                       (match_dup 1)
3925                       (const_int 32)))))))))
3926    (set (match_dup 0)
3927         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3928                 (zero_extend:DI
3929                  (truncate:HI
3930                   (const:DI
3931                    (sign_extend:DI
3932                     (truncate:HI
3933                      (ashiftrt:SI
3934                       (match_dup 1)
3935                       (const_int 16)))))))))
3936    (set (match_dup 0)
3937         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3938                 (zero_extend:DI
3939                  (truncate:HI
3940                   (const:DI
3941                    (sign_extend:DI
3942                     (truncate:HI
3943                      (match_dup 1))))))))]
3944   "TARGET_SHMEDIA64 && reload_completed
3945    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3946   "
3947 {
3948   sh_mark_label (operands[1], 4);
3949 }")
3950
3951 (define_expand "movdi_const_32bit"
3952   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3953         (const:DI (sign_extend:DI
3954                    (truncate:HI
3955                     (ashiftrt:DI
3956                      (match_operand:DI 1 "immediate_operand" "s")
3957                      (const_int 16))))))
3958    (set (match_dup 0)
3959         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3960                 (zero_extend:DI
3961                  (truncate:HI
3962                   (const:DI
3963                    (sign_extend:DI
3964                     (truncate:HI
3965                      (match_dup 1))))))))]
3966   "TARGET_SHMEDIA32 && reload_completed
3967    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3968   "
3969 {
3970   sh_mark_label (operands[1], 2);
3971 }")
3972
3973 (define_expand "movdi_const_16bit"
3974   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3975         (const:DI (sign_extend:DI
3976                    (truncate:HI
3977                     (match_operand:DI 1 "immediate_operand" "s")))))]
3978   "TARGET_SHMEDIA && flag_pic && reload_completed
3979    && GET_CODE (operands[1]) == SYMBOL_REF"
3980   "")
3981
3982 (define_split
3983   [(set (match_operand:DI 0 "arith_reg_operand" "")
3984         (match_operand:DI 1 "immediate_operand" ""))]
3985   "TARGET_SHMEDIA && reload_completed
3986    && GET_CODE (operands[1]) == CONST_INT
3987    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3988   [(set (match_dup 0) (match_dup 2))
3989    (match_dup 1)]
3990   "
3991 {
3992   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
3993   unsigned HOST_WIDE_INT low = val;
3994   unsigned HOST_WIDE_INT high = val;
3995   unsigned HOST_WIDE_INT sign;
3996   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
3997
3998   /* Sign-extend the 16 least-significant bits.  */
3999   low &= 0xffff;
4000   low ^= 0x8000;
4001   low -= 0x8000;
4002
4003   /* Arithmetic shift right the word by 16 bits.  */
4004   high >>= 16;
4005   sign = 1;
4006   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4007   high ^= sign;
4008   high -= sign;
4009   do
4010     {
4011       /* If we can't generate the constant with a two-insn movi / shori
4012          sequence, try some other strategies.  */
4013       if (! CONST_OK_FOR_I16 (high))
4014         {
4015           /* Try constant load / left shift.  We know VAL != 0.  */
4016           val2 = val ^ (val-1);
4017           if (val2 > 0x1ffff)
4018             {
4019               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
4020
4021               if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
4022                   || (! CONST_OK_FOR_I16 (high >> 16)
4023                       && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
4024                 {
4025                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
4026                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
4027                                                    GEN_INT (trailing_zeroes));
4028                   break;
4029                 }
4030             }
4031           /* Try constant load / right shift.  */
4032           val2 = (val >> 15) + 1;
4033           if (val2 == (val2 & -val2))
4034             {
4035               int shift = 49 - exact_log2 (val2);
4036
4037               val2 = trunc_int_for_mode (val << shift, DImode);
4038               if (CONST_OK_FOR_I16 (val2))
4039                 {
4040                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
4041                                                    GEN_INT (shift));
4042                   break;
4043                 }
4044             }
4045           /* Try mperm.w .  */
4046           val2 = val & 0xffff;
4047           if ((val >> 16 & 0xffff) == val2
4048               && (val >> 32 & 0xffff) == val2
4049               && (val >> 48 & 0xffff) == val2)
4050             {
4051               val2 = (HOST_WIDE_INT) val >> 48;
4052               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
4053               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
4054               break;
4055             }
4056           /* Try movi / mshflo.l  */
4057           val2 = (HOST_WIDE_INT) val >> 32;
4058           if (val2 == ((unsigned HOST_WIDE_INT)
4059                         trunc_int_for_mode (val, SImode)))
4060             {
4061               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4062                                              operands[0]);
4063               break;
4064             }
4065           /* Try movi / mshflo.l w/ r63.  */
4066           val2 = val + ((HOST_WIDE_INT) -1 << 32);
4067           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
4068             {
4069               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4070                                              const0_rtx);
4071               break;
4072             }
4073         }
4074       val2 = high;
4075       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
4076     }
4077   while (0);
4078   operands[2] = GEN_INT (val2);
4079 }")
4080
4081 (define_split
4082   [(set (match_operand:DI 0 "arith_reg_operand" "")
4083         (match_operand:DI 1 "immediate_operand" ""))]
4084   "TARGET_SHMEDIA && reload_completed
4085    && GET_CODE (operands[1]) == CONST_DOUBLE"
4086   [(set (match_dup 0) (match_dup 2))
4087   (set (match_dup 0)
4088        (ior:DI (ashift:DI (match_dup 0) (const_int 16))
4089                (zero_extend:DI (truncate:HI (match_dup 1)))))]
4090   "
4091 {
4092   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4093   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
4094   unsigned HOST_WIDE_INT val = low;
4095   unsigned HOST_WIDE_INT sign;
4096
4097   /* Sign-extend the 16 least-significant bits.  */
4098   val &= 0xffff;
4099   val ^= 0x8000;
4100   val -= 0x8000;
4101   operands[1] = GEN_INT (val);
4102
4103   /* Arithmetic shift right the double-word by 16 bits.  */
4104   low >>= 16;
4105   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
4106   high >>= 16;
4107   sign = 1;
4108   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4109   high ^= sign;
4110   high -= sign;
4111
4112   /* This will only be true if high is a sign-extension of low, i.e.,
4113      it must be either 0 or (unsigned)-1, and be zero iff the
4114      most-significant bit of low is set.  */
4115   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
4116     operands[2] = GEN_INT (low);
4117   else
4118     operands[2] = immed_double_const (low, high, DImode);
4119 }")
4120
4121 (define_insn "shori_media"
4122   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
4123         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
4124                            (const_int 16))
4125                 (zero_extend:DI
4126                  (truncate:HI
4127                   (match_operand:DI 2 "immediate_operand" "I16C16,nF")))))]
4128   "TARGET_SHMEDIA"
4129   "@
4130         shori   %u2, %0
4131         #"
4132   [(set_attr "type" "arith_media,*")])
4133
4134 (define_expand "movdi"
4135   [(set (match_operand:DI 0 "general_movdst_operand" "")
4136         (match_operand:DI 1 "general_movsrc_operand" ""))]
4137   ""
4138   "{ if (prepare_move_operands (operands, DImode)) DONE; }")
4139
4140 (define_insn "movdf_media"
4141   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4142         (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4143   "TARGET_SHMEDIA_FPU
4144    && (register_operand (operands[0], DFmode)
4145        || sh_register_operand (operands[1], DFmode))"
4146   "@
4147         fmov.d  %1, %0
4148         fmov.qd %N1, %0
4149         fmov.dq %1, %0
4150         add     %1, r63, %0
4151         #
4152         fld%M1.d        %m1, %0
4153         fst%M0.d        %m0, %1
4154         ld%M1.q %m1, %0
4155         st%M0.q %m0, %N1"
4156   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4157
4158 (define_insn "movdf_media_nofpu"
4159   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4160         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4161   "TARGET_SHMEDIA
4162    && (register_operand (operands[0], DFmode)
4163        || sh_register_operand (operands[1], DFmode))"
4164   "@
4165         add     %1, r63, %0
4166         #
4167         ld%M1.q %m1, %0
4168         st%M0.q %m0, %N1"
4169   [(set_attr "type" "arith_media,*,load_media,store_media")])
4170
4171 (define_split
4172   [(set (match_operand:DF 0 "arith_reg_operand" "")
4173         (match_operand:DF 1 "immediate_operand" ""))]
4174   "TARGET_SHMEDIA && reload_completed"
4175   [(set (match_dup 3) (match_dup 2))]
4176   "
4177 {
4178   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
4179   long values[2];
4180   REAL_VALUE_TYPE value;
4181
4182   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4183   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
4184
4185   if (HOST_BITS_PER_WIDE_INT >= 64)
4186     operands[2] = immed_double_const ((unsigned long) values[endian]
4187                                       | ((HOST_WIDE_INT) values[1 - endian]
4188                                          << 32), 0, DImode);
4189   else if (HOST_BITS_PER_WIDE_INT == 32)
4190     operands[2] = immed_double_const (values[endian], values[1 - endian],
4191                                       DImode);
4192   else
4193     abort ();
4194
4195   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4196 }")
4197
4198 ;; ??? This should be a define expand.
4199
4200 (define_insn "movdf_k"
4201   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4202         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
4203   "TARGET_SH1
4204    && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
4205        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
4206        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4207        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4208    && (arith_reg_operand (operands[0], DFmode)
4209        || arith_reg_operand (operands[1], DFmode))"
4210   "* return output_movedouble (insn, operands, DFmode);"
4211   [(set_attr "length" "4")
4212    (set_attr "type" "move,pcload,load,store")])
4213
4214 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
4215 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
4216 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
4217 ;; the d/m/c/X alternative, which is split later into single-precision
4218 ;; instructions.  And when not optimizing, no splits are done before fixing
4219 ;; up pcloads, so we need usable length information for that.
4220 (define_insn "movdf_i4"
4221   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
4222         (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
4223    (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
4224    (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
4225   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
4226    && (arith_reg_operand (operands[0], DFmode)
4227        || arith_reg_operand (operands[1], DFmode))"
4228   "@
4229         fmov    %1,%0
4230         #
4231         #
4232         fmov.d  %1,%0
4233         fmov.d  %1,%0
4234         #
4235         #
4236         #
4237         #
4238         #"
4239   [(set_attr_alternative "length"
4240      [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
4241       (const_int 4)
4242       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4243       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4244       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4245       (const_int 4)
4246       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
4247       ;; We can't use 4-byte push/pop on SHcompact, so we have to
4248       ;; increment or decrement r15 explicitly.
4249       (if_then_else
4250        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4251        (const_int 10) (const_int 8))
4252       (if_then_else
4253        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4254        (const_int 10) (const_int 8))])
4255    (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
4256    (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
4257    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4258                                            (const_string "double")
4259                                            (const_string "none")))])
4260
4261 ;; Moving DFmode between fp/general registers through memory
4262 ;; (the top of the stack) is faster than moving through fpul even for
4263 ;; little endian.  Because the type of an instruction is important for its
4264 ;; scheduling,  it is beneficial to split these operations, rather than
4265 ;; emitting them in one single chunk, even if this will expose a stack
4266 ;; use that will prevent scheduling of other stack accesses beyond this
4267 ;; instruction.
4268 (define_split
4269   [(set (match_operand:DF 0 "register_operand" "")
4270         (match_operand:DF 1 "register_operand" ""))
4271    (use (match_operand:PSI 2 "fpscr_operand" ""))
4272    (clobber (match_scratch:SI 3 "=X"))]
4273   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
4274    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
4275   [(const_int 0)]
4276   "
4277 {
4278   rtx insn, tos;
4279
4280   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
4281     {
4282       emit_move_insn (stack_pointer_rtx,
4283                       plus_constant (stack_pointer_rtx, -8));
4284       tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4285     }
4286   else
4287     tos = gen_rtx_MEM (DFmode, gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
4288   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
4289   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
4290     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4291   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4292     tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4293   else
4294     tos = gen_rtx_MEM (DFmode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
4295   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
4296   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4297     emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
4298   else
4299     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4300   DONE;
4301 }")
4302
4303 ;; local-alloc sometimes allocates scratch registers even when not required,
4304 ;; so we must be prepared to handle these.
4305
4306 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
4307 (define_split
4308   [(set (match_operand:DF 0 "general_movdst_operand" "")
4309         (match_operand:DF 1 "general_movsrc_operand"  ""))
4310    (use (match_operand:PSI 2 "fpscr_operand" ""))
4311    (clobber (match_scratch:SI 3 ""))]
4312   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
4313    && reload_completed
4314    && true_regnum (operands[0]) < 16
4315    && true_regnum (operands[1]) < 16"
4316   [(set (match_dup 0) (match_dup 1))]
4317   "
4318 {
4319   /* If this was a reg <-> mem operation with base + index reg addressing,
4320      we have to handle this in a special way.  */
4321   rtx mem = operands[0];
4322   int store_p = 1;
4323   if (! memory_operand (mem, DFmode))
4324     {
4325       mem = operands[1];
4326       store_p = 0;
4327     }
4328   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
4329     mem = SUBREG_REG (mem);
4330   if (GET_CODE (mem) == MEM)
4331     {
4332       rtx addr = XEXP (mem, 0);
4333       if (GET_CODE (addr) == PLUS
4334           && GET_CODE (XEXP (addr, 0)) == REG
4335           && GET_CODE (XEXP (addr, 1)) == REG)
4336         {
4337           int offset;
4338           rtx reg0 = gen_rtx_REG (Pmode, 0);
4339           rtx regop = operands[store_p], word0 ,word1;
4340
4341           if (GET_CODE (regop) == SUBREG)
4342             alter_subreg (&regop);
4343           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4344             offset = 2;
4345           else
4346             offset = 4;
4347           mem = copy_rtx (mem);
4348           PUT_MODE (mem, SImode);
4349           word0 = gen_rtx_SUBREG (SImode, regop, 0);
4350           alter_subreg (&word0);
4351           word1 = gen_rtx_SUBREG (SImode, regop, 4);
4352           alter_subreg (&word1);
4353           if (store_p || ! refers_to_regno_p (REGNO (word0),
4354                                               REGNO (word0) + 1, addr, 0))
4355             {
4356               emit_insn (store_p
4357                          ? gen_movsi_ie (mem, word0)
4358                          : gen_movsi_ie (word0, mem));
4359               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4360               mem = copy_rtx (mem);
4361               emit_insn (store_p
4362                          ? gen_movsi_ie (mem, word1)
4363                          : gen_movsi_ie (word1, mem));
4364               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4365             }
4366           else
4367             {
4368               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4369               emit_insn (gen_movsi_ie (word1, mem));
4370               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4371               mem = copy_rtx (mem);
4372               emit_insn (gen_movsi_ie (word0, mem));
4373             }
4374           DONE;
4375         }
4376     }
4377 }")
4378
4379 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4380 (define_split
4381   [(set (match_operand:DF 0 "register_operand" "")
4382         (match_operand:DF 1 "memory_operand"  ""))
4383    (use (match_operand:PSI 2 "fpscr_operand" ""))
4384    (clobber (reg:SI R0_REG))]
4385   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
4386   [(parallel [(set (match_dup 0) (match_dup 1))
4387               (use (match_dup 2))
4388               (clobber (scratch:SI))])]
4389   "")
4390
4391 (define_expand "reload_indf"
4392   [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4393                    (match_operand:DF 1 "immediate_operand" "FQ"))
4394               (use (reg:PSI FPSCR_REG))
4395               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4396   "TARGET_SH1"
4397   "")
4398
4399 (define_expand "reload_outdf"
4400   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4401                    (match_operand:DF 1 "register_operand" "af,r"))
4402               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
4403   "TARGET_SH1"
4404   "")
4405
4406 ;; Simplify no-op moves.
4407 (define_split
4408   [(set (match_operand:SF 0 "register_operand" "")
4409         (match_operand:SF 1 "register_operand" ""))
4410    (use (match_operand:PSI 2 "fpscr_operand" ""))
4411    (clobber (match_scratch:SI 3 ""))]
4412   "TARGET_SH2E && reload_completed
4413    && true_regnum (operands[0]) == true_regnum (operands[1])"
4414   [(set (match_dup 0) (match_dup 0))]
4415   "")
4416
4417 ;; fmovd substitute post-reload splits
4418 (define_split
4419   [(set (match_operand:DF 0 "register_operand" "")
4420         (match_operand:DF 1 "register_operand" ""))
4421    (use (match_operand:PSI 2 "fpscr_operand" ""))
4422    (clobber (match_scratch:SI 3 ""))]
4423   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4424    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4425    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4426   [(const_int 0)]
4427   "
4428 {
4429   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4430   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
4431                            gen_rtx_REG (SFmode, src), operands[2]));
4432   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
4433                            gen_rtx_REG (SFmode, src + 1), operands[2]));
4434   DONE;
4435 }")
4436
4437 (define_split
4438   [(set (match_operand:DF 0 "register_operand" "")
4439         (mem:DF (match_operand:SI 1 "register_operand" "")))
4440    (use (match_operand:PSI 2 "fpscr_operand" ""))
4441    (clobber (match_scratch:SI 3 ""))]
4442   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
4443    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4444    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4445   [(const_int 0)]
4446   "
4447 {
4448   int regno = true_regnum (operands[0]);
4449   rtx insn;
4450   rtx mem2 = gen_rtx_MEM (SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
4451
4452   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
4453                                            regno + !! TARGET_LITTLE_ENDIAN),
4454                                   mem2, operands[2]));
4455   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
4456   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
4457                                            regno + ! TARGET_LITTLE_ENDIAN),
4458                                   gen_rtx_MEM (SFmode, operands[1]),
4459                                   operands[2]));
4460   DONE;
4461 }")
4462
4463 (define_split
4464   [(set (match_operand:DF 0 "register_operand" "")
4465         (match_operand:DF 1 "memory_operand" ""))
4466    (use (match_operand:PSI 2 "fpscr_operand" ""))
4467    (clobber (match_scratch:SI 3 ""))]
4468   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
4469    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
4470   [(const_int 0)]
4471   "
4472 {
4473   int regno = true_regnum (operands[0]);
4474   rtx addr, insn, adjust = NULL_RTX;
4475   rtx mem2 = copy_rtx (operands[1]);
4476   rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4477   rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4478
4479   PUT_MODE (mem2, SFmode);
4480   operands[1] = copy_rtx (mem2);
4481   addr = XEXP (mem2, 0);
4482   if (GET_CODE (addr) != POST_INC)
4483     {
4484       /* If we have to modify the stack pointer, the value that we have
4485          read with post-increment might be modified by an interrupt,
4486          so write it back.  */
4487       if (REGNO (addr) == STACK_POINTER_REGNUM)
4488         adjust = gen_push_e (reg0);
4489       else
4490         adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4491       XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4492     }
4493   addr = XEXP (addr, 0);
4494   insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4495   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4496   insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4497   if (adjust)
4498     emit_insn (adjust);
4499   else
4500     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4501   DONE;
4502 }")
4503
4504 (define_split
4505   [(set (match_operand:DF 0 "memory_operand" "")
4506         (match_operand:DF 1 "register_operand" ""))
4507    (use (match_operand:PSI 2 "fpscr_operand" ""))
4508    (clobber (match_scratch:SI 3 ""))]
4509   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
4510    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4511   [(const_int 0)]
4512   "
4513 {
4514   int regno = true_regnum (operands[1]);
4515   rtx insn, addr, adjust = NULL_RTX;
4516
4517   operands[0] = copy_rtx (operands[0]);
4518   PUT_MODE (operands[0], SFmode);
4519   insn = emit_insn (gen_movsf_ie (operands[0],
4520                                   gen_rtx_REG (SFmode,
4521                                            regno + ! TARGET_LITTLE_ENDIAN),
4522                                   operands[2]));
4523   operands[0] = copy_rtx (operands[0]);
4524   addr = XEXP (operands[0], 0);
4525   if (GET_CODE (addr) != PRE_DEC)
4526     {
4527       adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4528       emit_insn_before (adjust, insn);
4529       XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
4530     }
4531   addr = XEXP (addr, 0);
4532   if (! adjust)
4533     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4534   insn = emit_insn (gen_movsf_ie (operands[0],
4535                                   gen_rtx_REG (SFmode,
4536                                            regno + !! TARGET_LITTLE_ENDIAN),
4537                                   operands[2]));
4538   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4539   DONE;
4540 }")
4541
4542 ;; If the output is a register and the input is memory or a register, we have
4543 ;; to be careful and see which word needs to be loaded first.
4544
4545 (define_split
4546   [(set (match_operand:DF 0 "general_movdst_operand" "")
4547         (match_operand:DF 1 "general_movsrc_operand" ""))]
4548   "TARGET_SH1 && reload_completed"
4549   [(set (match_dup 2) (match_dup 3))
4550    (set (match_dup 4) (match_dup 5))]
4551   "
4552 {
4553   int regno;
4554
4555   if ((GET_CODE (operands[0]) == MEM
4556        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4557       || (GET_CODE (operands[1]) == MEM
4558           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4559     FAIL;
4560
4561   if (GET_CODE (operands[0]) == REG)
4562     regno = REGNO (operands[0]);
4563   else if (GET_CODE (operands[0]) == SUBREG)
4564     regno = subreg_regno (operands[0]);
4565   else if (GET_CODE (operands[0]) == MEM)
4566     regno = -1;
4567   else
4568     abort ();
4569
4570   if (regno == -1
4571       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
4572     {
4573       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4574       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4575       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4576       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4577     }
4578   else
4579     {
4580       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4581       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4582       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4583       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4584     }
4585
4586   if (operands[2] == 0 || operands[3] == 0
4587       || operands[4] == 0 || operands[5] == 0)
4588     FAIL;
4589 }")
4590
4591 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4592 ;; used only once, let combine add in the index again.
4593
4594 (define_split
4595   [(set (match_operand:SI 0 "register_operand" "")
4596         (match_operand:SI 1 "" ""))
4597    (clobber (match_operand 2 "register_operand" ""))]
4598   "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4599   [(use (reg:SI R0_REG))]
4600   "
4601 {
4602   rtx addr, reg, const_int;
4603
4604   if (GET_CODE (operands[1]) != MEM)
4605     FAIL;
4606   addr = XEXP (operands[1], 0);
4607   if (GET_CODE (addr) != PLUS)
4608     FAIL;
4609   reg = XEXP (addr, 0);
4610   const_int = XEXP (addr, 1);
4611   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4612          && GET_CODE (const_int) == CONST_INT))
4613     FAIL;
4614   emit_move_insn (operands[2], const_int);
4615   emit_move_insn (operands[0],
4616                   change_address (operands[1], VOIDmode,
4617                                   gen_rtx_PLUS (SImode, reg, operands[2])));
4618   DONE;
4619 }")
4620
4621 (define_split
4622   [(set (match_operand:SI 1 "" "")
4623         (match_operand:SI 0 "register_operand" ""))
4624    (clobber (match_operand 2 "register_operand" ""))]
4625   "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4626   [(use (reg:SI R0_REG))]
4627   "
4628 {
4629   rtx addr, reg, const_int;
4630
4631   if (GET_CODE (operands[1]) != MEM)
4632     FAIL;
4633   addr = XEXP (operands[1], 0);
4634   if (GET_CODE (addr) != PLUS)
4635     FAIL;
4636   reg = XEXP (addr, 0);
4637   const_int = XEXP (addr, 1);
4638   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4639          && GET_CODE (const_int) == CONST_INT))
4640     FAIL;
4641   emit_move_insn (operands[2], const_int);
4642   emit_move_insn (change_address (operands[1], VOIDmode,
4643                                   gen_rtx_PLUS (SImode, reg, operands[2])),
4644                   operands[0]);
4645   DONE;
4646 }")
4647
4648 (define_expand "movdf"
4649   [(set (match_operand:DF 0 "general_movdst_operand" "")
4650         (match_operand:DF 1 "general_movsrc_operand" ""))]
4651   ""
4652   "
4653 {
4654   if (prepare_move_operands (operands, DFmode)) DONE;
4655   if (TARGET_SHMEDIA)
4656     {
4657       if (TARGET_SHMEDIA_FPU)
4658         emit_insn (gen_movdf_media (operands[0], operands[1]));
4659       else
4660         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4661       DONE;
4662     }
4663   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
4664     {
4665       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4666       DONE;
4667     }
4668 }")
4669
4670 ;;This is incompatible with the way gcc uses subregs.
4671 ;;(define_insn "movv2sf_i"
4672 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4673 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4674 ;;  "TARGET_SHMEDIA_FPU
4675 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
4676 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
4677 ;;  "@
4678 ;;      #
4679 ;;      fld%M1.p        %m1, %0
4680 ;;      fst%M0.p        %m0, %1"
4681 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
4682
4683 (define_insn_and_split "movv2sf_i"
4684   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
4685         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
4686   "TARGET_SHMEDIA_FPU"
4687   "#"
4688   "TARGET_SHMEDIA_FPU && reload_completed"
4689   [(set (match_dup 0) (match_dup 1))]
4690   "
4691 {
4692   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
4693   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
4694 }")
4695
4696 (define_expand "movv2sf"
4697   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
4698         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
4699   "TARGET_SHMEDIA_FPU"
4700   "
4701 {
4702   if (prepare_move_operands (operands, V2SFmode))
4703     DONE;
4704 }")
4705
4706 (define_expand "addv2sf3"
4707   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4708    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4709    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4710   "TARGET_SHMEDIA_FPU"
4711   "
4712 {
4713   sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
4714   DONE;
4715 }")
4716
4717 (define_expand "subv2sf3"
4718   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4719    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4720    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4721   "TARGET_SHMEDIA_FPU"
4722   "
4723 {
4724   sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
4725   DONE;
4726 }")
4727
4728 (define_expand "mulv2sf3"
4729   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4730    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4731    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4732   "TARGET_SHMEDIA_FPU"
4733   "
4734 {
4735   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
4736   DONE;
4737 }")
4738
4739 (define_expand "divv2sf3"
4740   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4741    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4742    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4743   "TARGET_SHMEDIA_FPU"
4744   "
4745 {
4746   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
4747   DONE;
4748 }")
4749
4750 (define_insn_and_split "*movv4sf_i"
4751   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4752         (match_operand:V4SF 1 "general_operand" "fZ,m,fZ"))]
4753   "TARGET_SHMEDIA_FPU"
4754   "#"
4755   "&& reload_completed"
4756   [(const_int 0)]
4757   "
4758 {
4759   int i;
4760
4761   for (i = 0; i < 4/2; i++)
4762     {
4763       rtx x, y;
4764
4765       if (GET_CODE (operands[0]) == MEM)
4766         x = gen_rtx_MEM (V2SFmode,
4767                          plus_constant (XEXP (operands[0], 0),
4768                                         i * GET_MODE_SIZE (V2SFmode)));
4769       else
4770         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
4771
4772       if (GET_CODE (operands[1]) == MEM)
4773         y = gen_rtx_MEM (V2SFmode,
4774                          plus_constant (XEXP (operands[1], 0),
4775                                         i * GET_MODE_SIZE (V2SFmode)));
4776       else
4777         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
4778
4779       emit_insn (gen_movv2sf_i (x, y));
4780     }
4781
4782   DONE;
4783 }"
4784   [(set_attr "length" "8")])
4785
4786 (define_expand "movv4sf"
4787   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
4788         (match_operand:V4SF 1 "general_operand" ""))]
4789   "TARGET_SHMEDIA_FPU"
4790   "
4791 {
4792   if (prepare_move_operands (operands, V4SFmode))
4793     DONE;
4794 }")
4795
4796 (define_insn_and_split "*movv16sf_i"
4797   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4798         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4799   "TARGET_SHMEDIA_FPU"
4800   "#"
4801   "&& reload_completed"
4802   [(const_int 0)]
4803   "
4804 {
4805   int i;
4806
4807   for (i = 0; i < 16/2; i++)
4808     {
4809       rtx x,y;
4810
4811       if (GET_CODE (operands[0]) == MEM)
4812         x = gen_rtx_MEM (V2SFmode,
4813                          plus_constant (XEXP (operands[0], 0),
4814                                         i * GET_MODE_SIZE (V2SFmode)));
4815       else
4816         {
4817           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
4818           alter_subreg (&x);
4819         }
4820
4821       if (GET_CODE (operands[1]) == MEM)
4822         y = gen_rtx_MEM (V2SFmode,
4823                          plus_constant (XEXP (operands[1], 0),
4824                                         i * GET_MODE_SIZE (V2SFmode)));
4825       else
4826         {
4827           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
4828           alter_subreg (&y);
4829         }
4830
4831       emit_insn (gen_movv2sf_i (x, y));
4832     }
4833
4834   DONE;
4835 }"
4836   [(set_attr "length" "32")])
4837
4838 (define_expand "movv16sf"
4839   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4840         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4841   "TARGET_SHMEDIA_FPU"
4842   "
4843 {
4844   if (prepare_move_operands (operands, V16SFmode))
4845     DONE;
4846 }")
4847
4848 (define_insn "movsf_media"
4849   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4850         (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4851   "TARGET_SHMEDIA_FPU
4852    && (register_operand (operands[0], SFmode)
4853        || sh_register_operand (operands[1], SFmode))"
4854   "@
4855         fmov.s  %1, %0
4856         fmov.ls %N1, %0
4857         fmov.sl %1, %0
4858         add.l   %1, r63, %0
4859         #
4860         fld%M1.s        %m1, %0
4861         fst%M0.s        %m0, %1
4862         ld%M1.l %m1, %0
4863         st%M0.l %m0, %N1"
4864   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4865
4866 (define_insn "movsf_media_nofpu"
4867   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
4868         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4869   "TARGET_SHMEDIA
4870    && (register_operand (operands[0], SFmode)
4871        || sh_register_operand (operands[1], SFmode))"
4872   "@
4873         add.l   %1, r63, %0
4874         #
4875         ld%M1.l %m1, %0
4876         st%M0.l %m0, %N1"
4877   [(set_attr "type" "arith_media,*,load_media,store_media")])
4878
4879 (define_split
4880   [(set (match_operand:SF 0 "arith_reg_operand" "")
4881         (match_operand:SF 1 "immediate_operand" ""))]
4882   "TARGET_SHMEDIA && reload_completed
4883    && ! FP_REGISTER_P (true_regnum (operands[0]))"
4884   [(set (match_dup 3) (match_dup 2))]
4885   "
4886 {
4887   long values;
4888   REAL_VALUE_TYPE value;
4889
4890   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4891   REAL_VALUE_TO_TARGET_SINGLE (value, values);
4892   operands[2] = GEN_INT (values);
4893
4894   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4895 }")
4896
4897 (define_insn "movsf_i"
4898   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
4899         (match_operand:SF 1 "general_movsrc_operand"  "r,G,FQ,mr,r,r,l"))]
4900   "TARGET_SH1
4901    && (! TARGET_SH2E
4902        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4903        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4904        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4905    && (arith_reg_operand (operands[0], SFmode)
4906        || arith_reg_operand (operands[1], SFmode))"
4907   "@
4908         mov     %1,%0
4909         mov     #0,%0
4910         mov.l   %1,%0
4911         mov.l   %1,%0
4912         mov.l   %1,%0
4913         lds     %1,%0
4914         sts     %1,%0"
4915   [(set_attr "type" "move,move,pcload,load,store,move,move")])
4916
4917 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4918 ;; update_flow_info would not know where to put REG_EQUAL notes
4919 ;; when the destination changes mode.
4920 (define_insn "movsf_ie"
4921   [(set (match_operand:SF 0 "general_movdst_operand"
4922          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
4923         (match_operand:SF 1 "general_movsrc_operand"
4924           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4925    (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"))
4926    (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
4927
4928   "TARGET_SH2E
4929    && (arith_reg_operand (operands[0], SFmode)
4930        || arith_reg_operand (operands[1], SFmode)
4931        || arith_reg_operand (operands[3], SImode)
4932        || (fpul_operand (operands[0], SFmode)
4933            && memory_operand (operands[1], SFmode)
4934            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4935        || (fpul_operand (operands[1], SFmode)
4936            && memory_operand (operands[0], SFmode)
4937            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
4938   "@
4939         fmov    %1,%0
4940         mov     %1,%0
4941         fldi0   %0
4942         fldi1   %0
4943         #
4944         fmov.s  %1,%0
4945         fmov.s  %1,%0
4946         mov.l   %1,%0
4947         mov.l   %1,%0
4948         mov.l   %1,%0
4949         fsts    fpul,%0
4950         flds    %1,fpul
4951         lds.l   %1,%0
4952         #
4953         sts     %1,%0
4954         lds     %1,%0
4955         sts.l   %1,%0
4956         lds.l   %1,%0
4957         ! move optimized away"
4958   [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
4959    (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
4960    (set_attr "length" "*,*,*,*,4,4,4,*,*,*,2,2,2,4,2,2,2,2,0")
4961    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4962                                            (const_string "single")
4963                                            (const_string "none")))])
4964
4965 (define_split
4966   [(set (match_operand:SF 0 "register_operand" "")
4967         (match_operand:SF 1 "register_operand" ""))
4968    (use (match_operand:PSI 2 "fpscr_operand" ""))
4969    (clobber (reg:SI FPUL_REG))]
4970   "TARGET_SH1"
4971   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
4972               (use (match_dup 2))
4973               (clobber (scratch:SI))])
4974    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
4975               (use (match_dup 2))
4976               (clobber (scratch:SI))])]
4977   "")
4978
4979 (define_expand "movsf"
4980   [(set (match_operand:SF 0 "general_movdst_operand" "")
4981         (match_operand:SF 1 "general_movsrc_operand" ""))]
4982   ""
4983   "
4984 {
4985   if (prepare_move_operands (operands, SFmode))
4986     DONE;
4987   if (TARGET_SHMEDIA)
4988     {
4989       if (TARGET_SHMEDIA_FPU)
4990         emit_insn (gen_movsf_media (operands[0], operands[1]));
4991       else
4992         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
4993       DONE;
4994     }
4995   if (TARGET_SH2E)
4996     {
4997       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
4998       DONE;
4999     }
5000 }")
5001
5002 (define_insn "mov_nop"
5003   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
5004   "TARGET_SH2E"
5005   ""
5006   [(set_attr "length" "0")
5007    (set_attr "type" "nil")])
5008
5009 (define_expand "reload_insf"
5010   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
5011                    (match_operand:SF 1 "immediate_operand" "FQ"))
5012               (use (reg:PSI FPSCR_REG))
5013               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5014   "TARGET_SH1"
5015   "")
5016
5017 (define_expand "reload_insi"
5018   [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
5019                    (match_operand:SF 1 "immediate_operand" "FQ"))
5020               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5021   "TARGET_SH1"
5022   "")
5023
5024 (define_insn "*movsi_y"
5025   [(set (match_operand:SI 0 "register_operand" "=y,y")
5026         (match_operand:SI 1 "immediate_operand" "Qi,I08"))
5027    (clobber (match_scratch:SI 2 "=&z,r"))]
5028   "TARGET_SH2E
5029    && (reload_in_progress || reload_completed)"
5030   "#"
5031   [(set_attr "length" "4")
5032    (set_attr "type" "pcload,move")])
5033
5034 (define_split
5035   [(set (match_operand:SI 0 "register_operand" "")
5036         (match_operand:SI 1 "immediate_operand" ""))
5037    (clobber (match_operand:SI 2 "register_operand" ""))]
5038   "TARGET_SH1"
5039   [(set (match_dup 2) (match_dup 1))
5040    (set (match_dup 0) (match_dup 2))]
5041   "")
5042
5043 (define_split
5044   [(set (match_operand:SI 0 "register_operand" "")
5045         (match_operand:SI 1 "memory_operand" ""))
5046    (clobber (reg:SI R0_REG))]
5047   "TARGET_SH1"
5048   [(set (match_dup 0) (match_dup 1))]
5049   "")
5050 \f
5051 ;; ------------------------------------------------------------------------
5052 ;; Define the real conditional branch instructions.
5053 ;; ------------------------------------------------------------------------
5054
5055 (define_insn "branch_true"
5056   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
5057                            (label_ref (match_operand 0 "" ""))
5058                            (pc)))]
5059   "TARGET_SH1"
5060   "* return output_branch (1, insn, operands);"
5061   [(set_attr "type" "cbranch")])
5062
5063 (define_insn "branch_false"
5064   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
5065                            (label_ref (match_operand 0 "" ""))
5066                            (pc)))]
5067   "TARGET_SH1"
5068   "* return output_branch (0, insn, operands);"
5069   [(set_attr "type" "cbranch")])
5070
5071 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
5072 ;; which destination is too far away.
5073 ;; The const_int_operand is distinct for each branch target; it avoids
5074 ;; unwanted matches with redundant_insn.
5075 (define_insn "block_branch_redirect"
5076   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
5077   "TARGET_SH1"
5078   ""
5079   [(set_attr "length" "0")])
5080
5081 ;; This one has the additional purpose to record a possible scratch register
5082 ;; for the following branch.
5083 ;; ??? Unfortunately, just setting the scratch register is not good enough,
5084 ;; because the insn then might be deemed dead and deleted.  And we can't
5085 ;; make the use in the jump insn explicit because that would disable
5086 ;; delay slot scheduling from the target.
5087 (define_insn "indirect_jump_scratch"
5088   [(set (match_operand:SI 0 "register_operand" "=r")
5089         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
5090    (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
5091   "TARGET_SH1"
5092   ""
5093   [(set_attr "length" "0")])
5094
5095 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
5096 ;; being pulled into the delay slot of a condbranch that has been made to
5097 ;; jump around the unconditional jump because it was out of range.
5098 (define_insn "stuff_delay_slot"
5099   [(set (pc)
5100         (unspec [(match_operand 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
5101    (set (reg:SI T_REG) (match_operand 1 "const_int_operand" ""))]
5102   "TARGET_SH1"
5103   ""
5104   [(set_attr "length" "0")
5105    (set_attr "cond_delay_slot" "yes")])
5106 \f
5107 ;; Conditional branch insns
5108
5109 (define_expand "beq_media"
5110   [(set (pc)
5111         (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
5112                           (match_operand:DI 2 "arith_operand" "r,I06"))
5113                       (label_ref:DI (match_operand 0 "" ""))
5114                       (pc)))]
5115   "TARGET_SHMEDIA"
5116   "")
5117
5118 (define_insn "*beq_media_i"
5119   [(set (pc)
5120         (if_then_else (match_operator 3 "equality_comparison_operator"
5121                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
5122                          (match_operand:DI 2 "arith_operand" "r,I06")])
5123                       (match_operand:DI 0 "target_operand" "b,b")
5124                       (pc)))]
5125   "TARGET_SHMEDIA"
5126   "@
5127         b%o3%'  %1, %2, %0
5128         b%o3i%' %1, %2, %0"
5129   [(set_attr "type" "cbranch_media")])
5130
5131 (define_expand "bne_media"
5132   [(set (pc)
5133         (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
5134                           (match_operand:DI 2 "arith_operand" "r,I06"))
5135                       (label_ref:DI (match_operand 0 "" ""))
5136                       (pc)))]
5137   "TARGET_SHMEDIA"
5138   "")
5139
5140 (define_expand "bgt_media"
5141   [(set (pc)
5142         (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5143                           (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5144                       (label_ref:DI (match_operand 0 "" ""))
5145                       (pc)))]
5146   "TARGET_SHMEDIA"
5147   "")
5148
5149 (define_expand "bge_media"
5150   [(set (pc)
5151         (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5152                           (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5153                       (label_ref:DI (match_operand 0 "" ""))
5154                       (pc)))]
5155   "TARGET_SHMEDIA"
5156   "")
5157
5158 (define_expand "bgtu_media"
5159   [(set (pc)
5160         (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5161                            (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5162                       (label_ref:DI (match_operand 0 "" ""))
5163                       (pc)))]
5164   "TARGET_SHMEDIA"
5165   "")
5166
5167 (define_expand "bgeu_media"
5168   [(set (pc)
5169         (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5170                            (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5171                       (label_ref:DI (match_operand 0 "" ""))
5172                       (pc)))]
5173   "TARGET_SHMEDIA"
5174   "")
5175
5176 (define_insn "*bgt_media_i"
5177   [(set (pc)
5178         (if_then_else (match_operator 3 "greater_comparison_operator"
5179                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5180                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5181                       (match_operand:DI 0 "target_operand" "b")
5182                       (pc)))]
5183   "TARGET_SHMEDIA"
5184   "b%o3%'       %N1, %N2, %0"
5185   [(set_attr "type" "cbranch_media")])
5186
5187 ;; These are only needed to make invert_jump() happy.
5188 (define_insn "*blt_media_i"
5189   [(set (pc)
5190         (if_then_else (match_operator 3 "less_comparison_operator"
5191                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5192                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5193                       (match_operand:DI 0 "target_operand" "b")
5194                       (pc)))]
5195   "TARGET_SHMEDIA"
5196   "b%o3%'       %N2, %N1, %0"
5197   [(set_attr "type" "cbranch_media")])
5198
5199 (define_expand "beq"
5200   [(set (pc)
5201         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5202                       (label_ref (match_operand 0 "" ""))
5203                       (pc)))]
5204   ""
5205   "
5206 {
5207   if (TARGET_SHMEDIA)
5208     {
5209       if (GET_MODE (sh_compare_op0) != DImode)
5210         {
5211           rtx tmp = gen_reg_rtx (DImode);
5212
5213           emit_insn (gen_seq (tmp));
5214           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5215           DONE;
5216         }
5217
5218       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5219       emit_jump_insn (gen_beq_media (operands[0],
5220                                      sh_compare_op0, sh_compare_op1));
5221       DONE;
5222     }
5223
5224   from_compare (operands, EQ);
5225 }")
5226
5227 (define_expand "bne"
5228   [(set (pc)
5229         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5230                       (label_ref (match_operand 0 "" ""))
5231                       (pc)))]
5232   ""
5233   "
5234 {
5235   if (TARGET_SHMEDIA)
5236     {
5237       if (GET_MODE (sh_compare_op0) != DImode)
5238         {
5239           rtx tmp = gen_reg_rtx (DImode);
5240
5241           emit_insn (gen_seq (tmp));
5242           emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
5243           DONE;
5244         }
5245
5246       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5247       emit_jump_insn (gen_bne_media (operands[0],
5248                                      sh_compare_op0, sh_compare_op1));
5249       DONE;
5250     }
5251
5252   from_compare (operands, EQ);
5253 }")
5254
5255 (define_expand "bgt"
5256   [(set (pc)
5257         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5258                       (label_ref (match_operand 0 "" ""))
5259                       (pc)))]
5260   ""
5261   "
5262 {
5263   if (TARGET_SHMEDIA)
5264     {
5265       if (GET_MODE (sh_compare_op0) != DImode)
5266         {
5267           rtx tmp = gen_reg_rtx (DImode);
5268
5269           emit_insn (gen_sgt (tmp));
5270           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5271           DONE;
5272         }
5273
5274       if (sh_compare_op0 != const0_rtx)
5275         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5276       if (sh_compare_op1 != const0_rtx)
5277         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5278       emit_jump_insn (gen_bgt_media (operands[0],
5279                                      sh_compare_op0, sh_compare_op1));
5280       DONE;
5281     }
5282
5283   from_compare (operands, GT);
5284 }")
5285
5286 (define_expand "blt"
5287   [(set (pc)
5288         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5289                       (label_ref (match_operand 0 "" ""))
5290                       (pc)))]
5291   ""
5292   "
5293 {
5294   if (TARGET_SHMEDIA)
5295     {
5296       if (GET_MODE (sh_compare_op0) != DImode)
5297         {
5298           rtx tmp = gen_reg_rtx (DImode);
5299
5300           emit_insn (gen_slt (tmp));
5301           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5302           DONE;
5303         }
5304
5305       if (sh_compare_op0 != const0_rtx)
5306         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5307       if (sh_compare_op1 != const0_rtx)
5308         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5309       emit_jump_insn (gen_bgt_media (operands[0],
5310                                      sh_compare_op1, sh_compare_op0));
5311       DONE;
5312     }
5313
5314   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5315     {
5316       rtx tmp = sh_compare_op0;
5317       sh_compare_op0 = sh_compare_op1;
5318       sh_compare_op1 = tmp;
5319       emit_insn (gen_bgt (operands[0]));
5320       DONE;
5321     }
5322   from_compare (operands, GE);
5323 }")
5324
5325 (define_expand "ble"
5326   [(set (pc)
5327         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5328                       (label_ref (match_operand 0 "" ""))
5329                       (pc)))]
5330   ""
5331   "
5332 {
5333   if (TARGET_SHMEDIA)
5334     {
5335       if (GET_MODE (sh_compare_op0) != DImode)
5336         {
5337           rtx tmp = gen_reg_rtx (DImode);
5338
5339           emit_insn (gen_sle (tmp));
5340           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5341           DONE;
5342         }
5343
5344       if (sh_compare_op0 != const0_rtx)
5345         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5346       if (sh_compare_op1 != const0_rtx)
5347         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5348       emit_jump_insn (gen_bge_media (operands[0],
5349                                      sh_compare_op1, sh_compare_op0));
5350       DONE;
5351     }
5352
5353   if (TARGET_SH2E
5354       && TARGET_IEEE
5355       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5356     {
5357       rtx tmp = sh_compare_op0;
5358       sh_compare_op0 = sh_compare_op1;
5359       sh_compare_op1 = tmp;
5360       emit_insn (gen_bge (operands[0]));
5361       DONE;
5362     }
5363   from_compare (operands, GT);
5364 }")
5365
5366 (define_expand "bge"
5367   [(set (pc)
5368         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5369                       (label_ref (match_operand 0 "" ""))
5370                       (pc)))]
5371   ""
5372   "
5373 {
5374   if (TARGET_SHMEDIA)
5375     {
5376       if (GET_MODE (sh_compare_op0) != DImode)
5377         {
5378           rtx tmp = gen_reg_rtx (DImode);
5379
5380           emit_insn (gen_sge (tmp));
5381           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5382           DONE;
5383         }
5384
5385       if (sh_compare_op0 != const0_rtx)
5386         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5387       if (sh_compare_op1 != const0_rtx)
5388         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5389       emit_jump_insn (gen_bge_media (operands[0],
5390                                      sh_compare_op0, sh_compare_op1));
5391       DONE;
5392     }
5393
5394   if (TARGET_SH2E
5395       && ! TARGET_IEEE
5396       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5397     {
5398       rtx tmp = sh_compare_op0;
5399       sh_compare_op0 = sh_compare_op1;
5400       sh_compare_op1 = tmp;
5401       emit_insn (gen_ble (operands[0]));
5402       DONE;
5403     }
5404   from_compare (operands, GE);
5405 }")
5406
5407 (define_expand "bgtu"
5408   [(set (pc)
5409         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5410                       (label_ref (match_operand 0 "" ""))
5411                       (pc)))]
5412   ""
5413   "
5414 {
5415   if (TARGET_SHMEDIA)
5416     {
5417       if (sh_compare_op0 != const0_rtx)
5418         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5419       if (sh_compare_op1 != const0_rtx)
5420         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5421       emit_jump_insn (gen_bgtu_media (operands[0],
5422                                       sh_compare_op0, sh_compare_op1));
5423       DONE;
5424     }
5425
5426   from_compare (operands, GTU);
5427 }")
5428
5429 (define_expand "bltu"
5430   [(set (pc)
5431         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5432                       (label_ref (match_operand 0 "" ""))
5433                       (pc)))]
5434   ""
5435   "
5436 {
5437   if (TARGET_SHMEDIA)
5438     {
5439       if (sh_compare_op0 != const0_rtx)
5440         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5441       if (sh_compare_op1 != const0_rtx)
5442         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5443       emit_jump_insn (gen_bgtu_media (operands[0],
5444                                       sh_compare_op1, sh_compare_op0));
5445       DONE;
5446     }
5447
5448   from_compare (operands, GEU);
5449 }")
5450
5451 (define_expand "bgeu"
5452   [(set (pc)
5453         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5454                       (label_ref (match_operand 0 "" ""))
5455                       (pc)))]
5456   ""
5457   "
5458 {
5459   if (TARGET_SHMEDIA)
5460     {
5461       if (sh_compare_op0 != const0_rtx)
5462         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5463       if (sh_compare_op1 != const0_rtx)
5464         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5465       emit_jump_insn (gen_bgeu_media (operands[0],
5466                                       sh_compare_op0, sh_compare_op1));
5467       DONE;
5468     }
5469
5470   from_compare (operands, GEU);
5471 }")
5472
5473 (define_expand "bleu"
5474   [(set (pc)
5475         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5476                       (label_ref (match_operand 0 "" ""))
5477                       (pc)))]
5478   ""
5479   "
5480 {
5481   if (TARGET_SHMEDIA)
5482     {
5483       if (sh_compare_op0 != const0_rtx)
5484         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5485       if (sh_compare_op1 != const0_rtx)
5486         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5487       emit_jump_insn (gen_bgeu_media (operands[0],
5488                                       sh_compare_op1, sh_compare_op0));
5489       DONE;
5490     }
5491
5492   from_compare (operands, GTU);
5493 }")
5494
5495 (define_expand "bunordered"
5496   [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5497    (set (pc)
5498         (if_then_else (ne (match_dup 1) (const_int 0))
5499                       (label_ref:DI (match_operand 0 "" ""))
5500                       (pc)))]
5501   "TARGET_SHMEDIA"
5502   "
5503 {
5504   operands[1] = gen_reg_rtx (DImode);
5505   operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5506   operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5507 }")
5508 \f
5509 ;; ------------------------------------------------------------------------
5510 ;; Jump and linkage insns
5511 ;; ------------------------------------------------------------------------
5512
5513 (define_insn "jump_compact"
5514   [(set (pc)
5515         (label_ref (match_operand 0 "" "")))]
5516   "TARGET_SH1"
5517   "*
5518 {
5519   /* The length is 16 if the delay slot is unfilled.  */
5520   if (get_attr_length(insn) > 4)
5521     return output_far_jump(insn, operands[0]);
5522   else
5523     return   \"bra      %l0%#\";
5524 }"
5525   [(set_attr "type" "jump")
5526    (set_attr "needs_delay_slot" "yes")])
5527
5528 ;; ??? It would be much saner to explicitly use the scratch register
5529 ;; in the jump insn, and have indirect_jump_scratch only set it,
5530 ;; but fill_simple_delay_slots would refuse to do delay slot filling
5531 ;; from the target then, as it uses simplejump_p.
5532 ;;(define_insn "jump_compact_far"
5533 ;;  [(set (pc)
5534 ;;      (label_ref (match_operand 0 "" "")))
5535 ;;   (use (match_operand 1 "register_operand" "r")]
5536 ;;  "TARGET_SH1"
5537 ;;  "* return output_far_jump(insn, operands[0], operands[1]);"
5538 ;;  [(set_attr "type" "jump")
5539 ;;   (set_attr "needs_delay_slot" "yes")])
5540
5541 (define_insn "jump_media"
5542   [(set (pc)
5543         (match_operand:DI 0 "target_operand" "b"))]
5544   "TARGET_SHMEDIA"
5545   "blink        %0, r63"
5546   [(set_attr "type" "jump_media")])
5547
5548 (define_expand "jump"
5549   [(set (pc)
5550         (label_ref (match_operand 0 "" "")))]
5551   ""
5552   "
5553 {
5554   if (TARGET_SH1)
5555     emit_jump_insn (gen_jump_compact (operands[0]));
5556   else if (TARGET_SHMEDIA)
5557     {
5558       if (reload_in_progress || reload_completed)
5559         FAIL;
5560       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5561                                                          operands[0])));
5562     }
5563   DONE;
5564 }")
5565
5566 (define_insn "force_mode_for_call"
5567   [(use (reg:PSI FPSCR_REG))]
5568   "TARGET_SHCOMPACT"
5569   ""
5570   [(set_attr "length" "0")
5571    (set (attr "fp_mode")
5572         (if_then_else (eq_attr "fpu_single" "yes")
5573                       (const_string "single") (const_string "double")))])
5574
5575 (define_insn "calli"
5576   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5577          (match_operand 1 "" ""))
5578    (use (reg:PSI FPSCR_REG))
5579    (clobber (reg:SI PR_REG))]
5580   "TARGET_SH1"
5581   "jsr  @%0%#"
5582   [(set_attr "type" "call")
5583    (set (attr "fp_mode")
5584         (if_then_else (eq_attr "fpu_single" "yes")
5585                       (const_string "single") (const_string "double")))
5586    (set_attr "needs_delay_slot" "yes")
5587    (set_attr "fp_set" "unknown")])
5588
5589 ;; This is a pc-rel call, using bsrf, for use with PIC.
5590
5591 (define_insn "calli_pcrel"
5592   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5593          (match_operand 1 "" ""))
5594    (use (reg:PSI FPSCR_REG))
5595    (use (reg:SI PIC_REG))
5596    (use (match_operand 2 "" ""))
5597    (clobber (reg:SI PR_REG))]
5598   "TARGET_SH2"
5599   "bsrf %0\\n%O2:%#"
5600   [(set_attr "type" "call")
5601    (set (attr "fp_mode")
5602         (if_then_else (eq_attr "fpu_single" "yes")
5603                       (const_string "single") (const_string "double")))
5604    (set_attr "needs_delay_slot" "yes")
5605    (set_attr "fp_set" "unknown")])
5606
5607 (define_insn_and_split "call_pcrel"
5608   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5609          (match_operand 1 "" ""))
5610    (use (reg:PSI FPSCR_REG))
5611    (use (reg:SI PIC_REG))
5612    (clobber (reg:SI PR_REG))
5613    (clobber (match_scratch:SI 2 "=r"))]
5614   "TARGET_SH2"
5615   "#"
5616   "reload_completed"
5617   [(const_int 0)]
5618   "
5619 {
5620   rtx lab = PATTERN (gen_call_site ());
5621
5622   if (SYMBOL_REF_LOCAL_P (operands[0]))
5623     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5624   else
5625     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5626   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5627   DONE;
5628 }"
5629   [(set_attr "type" "call")
5630    (set (attr "fp_mode")
5631         (if_then_else (eq_attr "fpu_single" "yes")
5632                       (const_string "single") (const_string "double")))
5633    (set_attr "needs_delay_slot" "yes")
5634    (set_attr "fp_set" "unknown")])
5635
5636 (define_insn "call_compact"
5637   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5638          (match_operand 1 "" ""))
5639    (match_operand 2 "immediate_operand" "n")
5640    (use (reg:SI R0_REG))
5641    (use (reg:SI R1_REG))
5642    (use (reg:PSI FPSCR_REG))
5643    (clobber (reg:SI PR_REG))]
5644   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5645   "jsr  @%0%#"
5646   [(set_attr "type" "call")
5647    (set (attr "fp_mode")
5648         (if_then_else (eq_attr "fpu_single" "yes")
5649                       (const_string "single") (const_string "double")))
5650    (set_attr "needs_delay_slot" "yes")])
5651
5652 (define_insn "call_compact_rettramp"
5653   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5654          (match_operand 1 "" ""))
5655    (match_operand 2 "immediate_operand" "n")
5656    (use (reg:SI R0_REG))
5657    (use (reg:SI R1_REG))
5658    (use (reg:PSI FPSCR_REG))
5659    (clobber (reg:SI R10_REG))
5660    (clobber (reg:SI PR_REG))]
5661   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5662   "jsr  @%0%#"
5663   [(set_attr "type" "call")
5664    (set (attr "fp_mode")
5665         (if_then_else (eq_attr "fpu_single" "yes")
5666                       (const_string "single") (const_string "double")))
5667    (set_attr "needs_delay_slot" "yes")])
5668
5669 (define_insn "call_media"
5670   [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5671          (match_operand 1 "" ""))
5672    (clobber (reg:DI PR_MEDIA_REG))]
5673   "TARGET_SHMEDIA"
5674   "blink        %0, r18"
5675   [(set_attr "type" "jump_media")])
5676
5677 (define_insn "call_valuei"
5678   [(set (match_operand 0 "" "=rf")
5679         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5680               (match_operand 2 "" "")))
5681    (use (reg:PSI FPSCR_REG))
5682    (clobber (reg:SI PR_REG))]
5683   "TARGET_SH1"
5684   "jsr  @%1%#"
5685   [(set_attr "type" "call")
5686    (set (attr "fp_mode")
5687         (if_then_else (eq_attr "fpu_single" "yes")
5688                       (const_string "single") (const_string "double")))
5689    (set_attr "needs_delay_slot" "yes")
5690    (set_attr "fp_set" "unknown")])
5691
5692 (define_insn "call_valuei_pcrel"
5693   [(set (match_operand 0 "" "=rf")
5694         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5695               (match_operand 2 "" "")))
5696    (use (reg:PSI FPSCR_REG))
5697    (use (reg:SI PIC_REG))
5698    (use (match_operand 3 "" ""))
5699    (clobber (reg:SI PR_REG))]
5700   "TARGET_SH2"
5701   "bsrf %1\\n%O3:%#"
5702   [(set_attr "type" "call")
5703    (set (attr "fp_mode")
5704         (if_then_else (eq_attr "fpu_single" "yes")
5705                       (const_string "single") (const_string "double")))
5706    (set_attr "needs_delay_slot" "yes")
5707    (set_attr "fp_set" "unknown")])
5708
5709 (define_insn_and_split "call_value_pcrel"
5710   [(set (match_operand 0 "" "=rf")
5711         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5712               (match_operand 2 "" "")))
5713    (use (reg:PSI FPSCR_REG))
5714    (use (reg:SI PIC_REG))
5715    (clobber (reg:SI PR_REG))
5716    (clobber (match_scratch:SI 3 "=r"))]
5717   "TARGET_SH2"
5718   "#"
5719   "reload_completed"
5720   [(const_int 0)]
5721   "
5722 {
5723   rtx lab = PATTERN (gen_call_site ());
5724
5725   if (SYMBOL_REF_LOCAL_P (operands[1]))
5726     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5727   else
5728     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5729   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5730                                          operands[2], lab));
5731   DONE;
5732 }"
5733   [(set_attr "type" "call")
5734    (set (attr "fp_mode")
5735         (if_then_else (eq_attr "fpu_single" "yes")
5736                       (const_string "single") (const_string "double")))
5737    (set_attr "needs_delay_slot" "yes")
5738    (set_attr "fp_set" "unknown")])
5739
5740 (define_insn "call_value_compact"
5741   [(set (match_operand 0 "" "=rf")
5742         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5743               (match_operand 2 "" "")))
5744    (match_operand 3 "immediate_operand" "n")
5745    (use (reg:SI R0_REG))
5746    (use (reg:SI R1_REG))
5747    (use (reg:PSI FPSCR_REG))
5748    (clobber (reg:SI PR_REG))]
5749   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5750   "jsr  @%1%#"
5751   [(set_attr "type" "call")
5752    (set (attr "fp_mode")
5753         (if_then_else (eq_attr "fpu_single" "yes")
5754                       (const_string "single") (const_string "double")))
5755    (set_attr "needs_delay_slot" "yes")])
5756
5757 (define_insn "call_value_compact_rettramp"
5758   [(set (match_operand 0 "" "=rf")
5759         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5760               (match_operand 2 "" "")))
5761    (match_operand 3 "immediate_operand" "n")
5762    (use (reg:SI R0_REG))
5763    (use (reg:SI R1_REG))
5764    (use (reg:PSI FPSCR_REG))
5765    (clobber (reg:SI R10_REG))
5766    (clobber (reg:SI PR_REG))]
5767   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5768   "jsr  @%1%#"
5769   [(set_attr "type" "call")
5770    (set (attr "fp_mode")
5771         (if_then_else (eq_attr "fpu_single" "yes")
5772                       (const_string "single") (const_string "double")))
5773    (set_attr "needs_delay_slot" "yes")])
5774
5775 (define_insn "call_value_media"
5776   [(set (match_operand 0 "" "=rf")
5777         (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5778               (match_operand 2 "" "")))
5779    (clobber (reg:DI PR_MEDIA_REG))]
5780   "TARGET_SHMEDIA"
5781   "blink        %1, r18"
5782   [(set_attr "type" "jump_media")])
5783
5784 (define_expand "call"
5785   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5786                             (match_operand 1 "" ""))
5787               (match_operand 2 "" "")
5788               (use (reg:PSI FPSCR_REG))
5789               (clobber (reg:SI PR_REG))])]
5790   ""
5791   "
5792 {
5793   if (TARGET_SHMEDIA)
5794     {
5795       operands[0] = XEXP (operands[0], 0);
5796       if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5797         {
5798           if (! SYMBOL_REF_LOCAL_P (operands[0]))
5799             {
5800               rtx reg = gen_reg_rtx (Pmode);
5801
5802               emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5803               operands[0] = reg;
5804             }
5805           else
5806             {
5807               operands[0] = gen_sym2PIC (operands[0]);
5808               PUT_MODE (operands[0], Pmode);
5809             }
5810         }
5811       if (GET_MODE (operands[0]) == SImode)
5812         {
5813           if (GET_CODE (operands[0]) == REG)
5814             operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5815           else if (GET_CODE (operands[0]) == SUBREG)
5816             {
5817               operands[0] = SUBREG_REG (operands[0]);
5818               if (GET_MODE (operands[0]) != DImode)
5819                 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5820             }
5821           else if (TARGET_SHMEDIA64)
5822             {
5823               operands[0] = shallow_copy_rtx (operands[0]);
5824               PUT_MODE (operands[0], DImode);
5825             }
5826           else
5827             {
5828               rtx reg = gen_reg_rtx (DImode);
5829
5830               operands[0] = copy_to_mode_reg (SImode, operands[0]);
5831               emit_insn (gen_extendsidi2 (reg, operands[0]));
5832               operands[0] = reg;
5833             }
5834         }
5835       if (! target_reg_operand (operands[0], DImode))
5836         operands[0] = copy_to_mode_reg (DImode, operands[0]);
5837       emit_call_insn (gen_call_media (operands[0], operands[1]));
5838       DONE;
5839     }
5840   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5841     {
5842       rtx cookie_rtx = operands[2];
5843       long cookie = INTVAL (cookie_rtx);
5844       rtx func = XEXP (operands[0], 0);
5845       rtx r0, r1;
5846
5847       if (flag_pic)
5848         {
5849           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5850             {
5851               rtx reg = gen_reg_rtx (Pmode);
5852
5853               emit_insn (gen_symGOTPLT2reg (reg, func));
5854               func = reg;
5855             }
5856           else
5857             func = legitimize_pic_address (func, Pmode, 0);
5858         }
5859
5860       r0 = gen_rtx_REG (SImode, R0_REG);
5861       r1 = gen_rtx_REG (SImode, R1_REG);
5862
5863       /* Since such a call function may use all call-clobbered
5864          registers, we force a mode switch earlier, so that we don't
5865          run out of registers when adjusting fpscr for the call.  */
5866       emit_insn (gen_force_mode_for_call ());
5867
5868       operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5869       if (flag_pic)
5870         {
5871           rtx reg = gen_reg_rtx (Pmode);
5872
5873           emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5874           operands[0] = reg;
5875         }
5876       operands[0] = force_reg (SImode, operands[0]);
5877
5878       emit_move_insn (r0, func);
5879       emit_move_insn (r1, cookie_rtx);
5880
5881       if (cookie & CALL_COOKIE_RET_TRAMP (1))
5882         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5883                                                    operands[2]));
5884       else
5885         emit_call_insn (gen_call_compact (operands[0], operands[1],
5886                                           operands[2]));
5887
5888       DONE;
5889     }
5890   else if (TARGET_SHCOMPACT && flag_pic
5891            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5892            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
5893     {
5894       rtx reg = gen_reg_rtx (Pmode);
5895
5896       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5897       XEXP (operands[0], 0) = reg;
5898     }
5899   if (flag_pic && TARGET_SH2
5900       && GET_CODE (operands[0]) == MEM
5901       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5902     {
5903       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
5904       DONE;
5905     }
5906   else
5907   {
5908     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5909     operands[1] = operands[2];
5910   }
5911
5912   emit_call_insn (gen_calli (operands[0], operands[1]));
5913   DONE;
5914 }")
5915
5916 (define_insn "call_pop_compact"
5917   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5918          (match_operand 1 "" ""))
5919    (match_operand 2 "immediate_operand" "n")
5920    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5921                                  (match_operand 3 "immediate_operand" "n")))
5922    (use (reg:SI R0_REG))
5923    (use (reg:SI R1_REG))
5924    (use (reg:PSI FPSCR_REG))
5925    (clobber (reg:SI PR_REG))]
5926   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5927   "jsr  @%0%#"
5928   [(set_attr "type" "call")
5929    (set (attr "fp_mode")
5930         (if_then_else (eq_attr "fpu_single" "yes")
5931                       (const_string "single") (const_string "double")))
5932    (set_attr "needs_delay_slot" "yes")])
5933
5934 (define_insn "call_pop_compact_rettramp"
5935   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5936          (match_operand 1 "" ""))
5937    (match_operand 2 "immediate_operand" "n")
5938    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5939                                  (match_operand 3 "immediate_operand" "n")))
5940    (use (reg:SI R0_REG))
5941    (use (reg:SI R1_REG))
5942    (use (reg:PSI FPSCR_REG))
5943    (clobber (reg:SI R10_REG))
5944    (clobber (reg:SI PR_REG))]
5945   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5946   "jsr  @%0%#"
5947   [(set_attr "type" "call")
5948    (set (attr "fp_mode")
5949         (if_then_else (eq_attr "fpu_single" "yes")
5950                       (const_string "single") (const_string "double")))
5951    (set_attr "needs_delay_slot" "yes")])
5952
5953 (define_expand "call_pop"
5954   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5955                     (match_operand 1 "" ""))
5956              (match_operand 2 "" "")
5957              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5958                                            (match_operand 3 "" "")))])]
5959   "TARGET_SHCOMPACT"
5960   "
5961 {
5962   if (operands[2] && INTVAL (operands[2]))
5963     {
5964       rtx cookie_rtx = operands[2];
5965       long cookie = INTVAL (cookie_rtx);
5966       rtx func = XEXP (operands[0], 0);
5967       rtx r0, r1;
5968
5969       if (flag_pic)
5970         {
5971           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5972             {
5973               rtx reg = gen_reg_rtx (Pmode);
5974
5975               emit_insn (gen_symGOTPLT2reg (reg, func));
5976               func = reg;
5977             }
5978           else
5979             func = legitimize_pic_address (func, Pmode, 0);
5980         }
5981
5982       r0 = gen_rtx_REG (SImode, R0_REG);
5983       r1 = gen_rtx_REG (SImode, R1_REG);
5984
5985       /* Since such a call function may use all call-clobbered
5986          registers, we force a mode switch earlier, so that we don't
5987          run out of registers when adjusting fpscr for the call.  */
5988       emit_insn (gen_force_mode_for_call ());
5989
5990       operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5991       if (flag_pic)
5992         {
5993           rtx reg = gen_reg_rtx (Pmode);
5994
5995           emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5996           operands[0] = reg;
5997         }
5998       operands[0] = force_reg (SImode, operands[0]);
5999
6000       emit_move_insn (r0, func);
6001       emit_move_insn (r1, cookie_rtx);
6002
6003       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6004         emit_call_insn (gen_call_pop_compact_rettramp
6005                         (operands[0], operands[1], operands[2], operands[3]));
6006       else
6007         emit_call_insn (gen_call_pop_compact
6008                         (operands[0], operands[1], operands[2], operands[3]));
6009
6010       DONE;
6011     }
6012
6013   abort ();
6014 }")
6015
6016 (define_expand "call_value"
6017   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6018                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6019                                  (match_operand 2 "" "")))
6020               (match_operand 3 "" "")
6021               (use (reg:PSI FPSCR_REG))
6022               (clobber (reg:SI PR_REG))])]
6023   ""
6024   "
6025 {
6026   if (TARGET_SHMEDIA)
6027     {
6028       operands[1] = XEXP (operands[1], 0);
6029       if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
6030         {
6031           if (! SYMBOL_REF_LOCAL_P (operands[1]))
6032             {
6033               rtx reg = gen_reg_rtx (Pmode);
6034
6035               emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6036               operands[1] = reg;
6037             }
6038           else
6039             {
6040               operands[1] = gen_sym2PIC (operands[1]);
6041               PUT_MODE (operands[1], Pmode);
6042             }
6043         }
6044       if (GET_MODE (operands[1]) == SImode)
6045         {
6046           if (GET_CODE (operands[1]) == REG)
6047             operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6048           else if (GET_CODE (operands[1]) == SUBREG)
6049             {
6050               operands[1] = SUBREG_REG (operands[1]);
6051               if (GET_MODE (operands[1]) != DImode)
6052                 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6053             }
6054           else if (TARGET_SHMEDIA64)
6055             {
6056               operands[1] = shallow_copy_rtx (operands[1]);
6057               PUT_MODE (operands[1], DImode);
6058             }
6059           else
6060             {
6061               rtx reg = gen_reg_rtx (DImode);
6062
6063               operands[1] = copy_to_mode_reg (SImode, operands[1]);
6064               emit_insn (gen_extendsidi2 (reg, operands[1]));
6065               operands[1] = reg;
6066             }
6067         }
6068       if (! target_reg_operand (operands[1], DImode))
6069         operands[1] = copy_to_mode_reg (DImode, operands[1]);
6070       emit_call_insn (gen_call_value_media (operands[0], operands[1],
6071                                             operands[2]));
6072       DONE;
6073     }
6074   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6075     {
6076       rtx cookie_rtx = operands[3];
6077       long cookie = INTVAL (cookie_rtx);
6078       rtx func = XEXP (operands[1], 0);
6079       rtx r0, r1;
6080
6081       if (flag_pic)
6082         {
6083           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6084             {
6085               rtx reg = gen_reg_rtx (Pmode);
6086
6087               emit_insn (gen_symGOTPLT2reg (reg, func));
6088               func = reg;
6089             }
6090           else
6091             func = legitimize_pic_address (func, Pmode, 0);
6092         }
6093
6094       r0 = gen_rtx_REG (SImode, R0_REG);
6095       r1 = gen_rtx_REG (SImode, R1_REG);
6096
6097       /* Since such a call function may use all call-clobbered
6098          registers, we force a mode switch earlier, so that we don't
6099          run out of registers when adjusting fpscr for the call.  */
6100       emit_insn (gen_force_mode_for_call ());
6101
6102       operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6103       if (flag_pic)
6104         {
6105           rtx reg = gen_reg_rtx (Pmode);
6106
6107           emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6108           operands[1] = reg;
6109         }
6110       operands[1] = force_reg (SImode, operands[1]);
6111
6112       emit_move_insn (r0, func);
6113       emit_move_insn (r1, cookie_rtx);
6114
6115       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6116         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
6117                                                          operands[1],
6118                                                          operands[2],
6119                                                          operands[3]));
6120       else
6121         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
6122                                                 operands[2], operands[3]));
6123
6124       DONE;
6125     }
6126   else if (TARGET_SHCOMPACT && flag_pic
6127            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6128            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
6129     {
6130       rtx reg = gen_reg_rtx (Pmode);
6131
6132       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6133       XEXP (operands[1], 0) = reg;
6134     }
6135   if (flag_pic && TARGET_SH2
6136       && GET_CODE (operands[1]) == MEM
6137       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6138     {
6139       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6140                                             operands[2]));
6141       DONE;
6142     }
6143   else
6144     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
6145
6146   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6147   DONE;
6148 }")
6149
6150 (define_insn "sibcalli"
6151   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
6152          (match_operand 1 "" ""))
6153    (use (reg:PSI FPSCR_REG))
6154    (return)]
6155   "TARGET_SH1"
6156   "jmp  @%0%#"
6157   [(set_attr "needs_delay_slot" "yes")
6158    (set (attr "fp_mode")
6159         (if_then_else (eq_attr "fpu_single" "yes")
6160                       (const_string "single") (const_string "double")))
6161    (set_attr "type" "jump_ind")])
6162
6163 (define_insn "sibcalli_pcrel"
6164   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
6165          (match_operand 1 "" ""))
6166    (use (match_operand 2 "" ""))
6167    (use (reg:PSI FPSCR_REG))
6168    (return)]
6169   "TARGET_SH2"
6170   "braf %0\\n%O2:%#"
6171   [(set_attr "needs_delay_slot" "yes")
6172    (set (attr "fp_mode")
6173         (if_then_else (eq_attr "fpu_single" "yes")
6174                       (const_string "single") (const_string "double")))
6175    (set_attr "type" "jump_ind")])
6176
6177 (define_insn_and_split "sibcall_pcrel"
6178   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6179          (match_operand 1 "" ""))
6180    (use (reg:PSI FPSCR_REG))
6181    (clobber (match_scratch:SI 2 "=k"))
6182    (return)]
6183   "TARGET_SH2"
6184   "#"
6185   "reload_completed"
6186   [(const_int 0)]
6187   "
6188 {
6189   rtx lab = PATTERN (gen_call_site ());
6190   rtx call_insn;
6191
6192   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6193   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6194                                                   lab));
6195   SIBLING_CALL_P (call_insn) = 1;
6196   DONE;
6197 }"
6198   [(set_attr "needs_delay_slot" "yes")
6199    (set (attr "fp_mode")
6200         (if_then_else (eq_attr "fpu_single" "yes")
6201                       (const_string "single") (const_string "double")))
6202    (set_attr "type" "jump_ind")])
6203
6204 (define_insn "sibcall_compact"
6205   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6206          (match_operand 1 "" ""))
6207    (return)
6208    (use (match_operand:SI 2 "register_operand" "z,x"))
6209    (use (reg:SI R1_REG))
6210    (use (reg:PSI FPSCR_REG))
6211    ;; We want to make sure the `x' above will only match MACH_REG
6212    ;; because sibcall_epilogue may clobber MACL_REG.
6213    (clobber (reg:SI MACL_REG))]
6214   "TARGET_SHCOMPACT"
6215   "@
6216         jmp     @%0%#
6217         jmp     @%0\\n  sts     %2, r0"
6218   [(set_attr "needs_delay_slot" "yes,no")
6219    (set_attr "length" "2,4")
6220    (set (attr "fp_mode") (const_string "single"))
6221    (set_attr "type" "jump_ind")])
6222
6223 (define_insn "sibcall_media"
6224   [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6225          (match_operand 1 "" ""))
6226    (use (reg:SI PR_MEDIA_REG))
6227    (return)]
6228   "TARGET_SHMEDIA"
6229   "blink        %0, r63"
6230   [(set_attr "type" "jump_media")])
6231
6232 (define_expand "sibcall"
6233   [(parallel
6234     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6235            (match_operand 1 "" ""))
6236      (match_operand 2 "" "")
6237      (use (reg:PSI FPSCR_REG))
6238      (return)])]
6239   ""
6240   "
6241 {
6242   if (TARGET_SHMEDIA)
6243     {
6244       operands[0] = XEXP (operands[0], 0);
6245       if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6246         {
6247           if (! SYMBOL_REF_LOCAL_P (operands[0]))
6248             {
6249               rtx reg = gen_reg_rtx (Pmode);
6250
6251               /* We must not use GOTPLT for sibcalls, because PIC_REG
6252                  must be restored before the PLT code gets to run.  */
6253               emit_insn (gen_symGOT2reg (reg, operands[0]));
6254               operands[0] = reg;
6255             }
6256           else
6257             {
6258               operands[0] = gen_sym2PIC (operands[0]);
6259               PUT_MODE (operands[0], Pmode);
6260             }
6261         }
6262       if (GET_MODE (operands[0]) == SImode)
6263         {
6264           if (GET_CODE (operands[0]) == REG)
6265             operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6266           else if (GET_CODE (operands[0]) == SUBREG)
6267             {
6268               operands[0] = SUBREG_REG (operands[0]);
6269               if (GET_MODE (operands[0]) != DImode)
6270                 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6271             }
6272           else
6273             {
6274               operands[0] = shallow_copy_rtx (operands[0]);
6275               PUT_MODE (operands[0], DImode);
6276             }
6277         }
6278       if (! target_reg_operand (operands[0], DImode))
6279         operands[0] = copy_to_mode_reg (DImode, operands[0]);
6280       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6281       DONE;
6282     }
6283   else if (TARGET_SHCOMPACT && operands[2]
6284            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6285     {
6286       rtx cookie_rtx = operands[2];
6287       long cookie = INTVAL (cookie_rtx);
6288       rtx func = XEXP (operands[0], 0);
6289       rtx mach, r1;
6290
6291       if (flag_pic)
6292         {
6293           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6294             {
6295               rtx reg = gen_reg_rtx (Pmode);
6296
6297               emit_insn (gen_symGOT2reg (reg, func));
6298               func = reg;
6299             }
6300           else
6301             func = legitimize_pic_address (func, Pmode, 0);
6302         }
6303
6304       /* FIXME: if we could tell whether all argument registers are
6305          already taken, we could decide whether to force the use of
6306          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
6307          simple way to tell.  We could use the CALL_COOKIE, but we
6308          can't currently tell a register used for regular argument
6309          passing from one that is unused.  If we leave it up to reload
6310          to decide which register to use, it seems to always choose
6311          R0_REG, which leaves no available registers in SIBCALL_REGS
6312          to hold the address of the trampoline.  */
6313       mach = gen_rtx_REG (SImode, MACH_REG);
6314       r1 = gen_rtx_REG (SImode, R1_REG);
6315
6316       /* Since such a call function may use all call-clobbered
6317          registers, we force a mode switch earlier, so that we don't
6318          run out of registers when adjusting fpscr for the call.  */
6319       emit_insn (gen_force_mode_for_call ());
6320
6321       operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6322       if (flag_pic)
6323         {
6324           rtx reg = gen_reg_rtx (Pmode);
6325
6326           emit_insn (gen_symGOT2reg (reg, operands[0]));
6327           operands[0] = reg;
6328         }
6329       operands[0] = force_reg (SImode, operands[0]);
6330
6331       /* We don't need a return trampoline, since the callee will
6332          return directly to the upper caller.  */
6333       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6334         {
6335           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6336           cookie_rtx = GEN_INT (cookie);
6337         }
6338
6339       emit_move_insn (mach, func);
6340       emit_move_insn (r1, cookie_rtx);
6341
6342       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6343       DONE;
6344     }
6345   else if (TARGET_SHCOMPACT && flag_pic
6346            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6347            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6348     {
6349       rtx reg = gen_reg_rtx (Pmode);
6350
6351       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6352       XEXP (operands[0], 0) = reg;
6353     }
6354   if (flag_pic && TARGET_SH2
6355       && GET_CODE (operands[0]) == MEM
6356       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6357       /* The PLT needs the PIC register, but the epilogue would have
6358          to restore it, so we can only use PC-relative PIC calls for
6359          static functions.  */
6360       && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6361     {
6362       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6363       DONE;
6364     }
6365   else
6366     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
6367
6368   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6369   DONE;
6370 }")
6371
6372 (define_expand "sibcall_value"
6373   [(set (match_operand 0 "" "")
6374         (call (match_operand 1 "" "")
6375               (match_operand 2 "" "")))
6376    (match_operand 3 "" "")]
6377   ""
6378   "
6379 {
6380   emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
6381   DONE;
6382 }")
6383
6384 (define_insn "call_value_pop_compact"
6385   [(set (match_operand 0 "" "=rf")
6386         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6387               (match_operand 2 "" "")))
6388    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6389                                  (match_operand 4 "immediate_operand" "n")))
6390    (match_operand 3 "immediate_operand" "n")
6391    (use (reg:SI R0_REG))
6392    (use (reg:SI R1_REG))
6393    (use (reg:PSI FPSCR_REG))
6394    (clobber (reg:SI PR_REG))]
6395   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6396   "jsr  @%1%#"
6397   [(set_attr "type" "call")
6398    (set (attr "fp_mode")
6399         (if_then_else (eq_attr "fpu_single" "yes")
6400                       (const_string "single") (const_string "double")))
6401    (set_attr "needs_delay_slot" "yes")])
6402
6403 (define_insn "call_value_pop_compact_rettramp"
6404   [(set (match_operand 0 "" "=rf")
6405         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6406               (match_operand 2 "" "")))
6407    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6408                                  (match_operand 4 "immediate_operand" "n")))
6409    (match_operand 3 "immediate_operand" "n")
6410    (use (reg:SI R0_REG))
6411    (use (reg:SI R1_REG))
6412    (use (reg:PSI FPSCR_REG))
6413    (clobber (reg:SI R10_REG))
6414    (clobber (reg:SI PR_REG))]
6415   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6416   "jsr  @%1%#"
6417   [(set_attr "type" "call")
6418    (set (attr "fp_mode")
6419         (if_then_else (eq_attr "fpu_single" "yes")
6420                       (const_string "single") (const_string "double")))
6421    (set_attr "needs_delay_slot" "yes")])
6422
6423 (define_expand "call_value_pop"
6424   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6425                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6426                                  (match_operand 2 "" "")))
6427               (match_operand 3 "" "")
6428               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6429                                             (match_operand 4 "" "")))])]
6430   "TARGET_SHCOMPACT"
6431   "
6432 {
6433   if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6434     {
6435       rtx cookie_rtx = operands[3];
6436       long cookie = INTVAL (cookie_rtx);
6437       rtx func = XEXP (operands[1], 0);
6438       rtx r0, r1;
6439
6440       if (flag_pic)
6441         {
6442           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6443             {
6444               rtx reg = gen_reg_rtx (Pmode);
6445
6446               emit_insn (gen_symGOTPLT2reg (reg, func));
6447               func = reg;
6448             }
6449           else
6450             func = legitimize_pic_address (func, Pmode, 0);
6451         }
6452
6453       r0 = gen_rtx_REG (SImode, R0_REG);
6454       r1 = gen_rtx_REG (SImode, R1_REG);
6455
6456       /* Since such a call function may use all call-clobbered
6457          registers, we force a mode switch earlier, so that we don't
6458          run out of registers when adjusting fpscr for the call.  */
6459       emit_insn (gen_force_mode_for_call ());
6460
6461       operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6462       if (flag_pic)
6463         {
6464           rtx reg = gen_reg_rtx (Pmode);
6465
6466           emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6467           operands[1] = reg;
6468         }
6469       operands[1] = force_reg (SImode, operands[1]);
6470
6471       emit_move_insn (r0, func);
6472       emit_move_insn (r1, cookie_rtx);
6473
6474       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6475         emit_call_insn (gen_call_value_pop_compact_rettramp
6476                         (operands[0], operands[1], operands[2],
6477                          operands[3], operands[4]));
6478       else
6479         emit_call_insn (gen_call_value_pop_compact
6480                         (operands[0], operands[1], operands[2],
6481                          operands[3], operands[4]));
6482
6483       DONE;
6484     }
6485
6486   abort ();
6487 }")
6488
6489 (define_expand "sibcall_epilogue"
6490   [(return)]
6491   ""
6492   "
6493 {
6494   sh_expand_epilogue (1);
6495   if (TARGET_SHCOMPACT)
6496     {
6497       rtx insn, set;
6498
6499       /* If epilogue clobbers r0, preserve it in macl.  */
6500       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6501         if ((set = single_set (insn))
6502             && GET_CODE (SET_DEST (set)) == REG
6503             && REGNO (SET_DEST (set)) == R0_REG)
6504           {
6505             rtx r0 = gen_rtx_REG (SImode, R0_REG);
6506             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6507             rtx i;
6508
6509             /* We can't tell at this point whether the sibcall is a
6510                sibcall_compact and, if it is, whether it uses r0 or
6511                mach as operand 2, so let the instructions that
6512                preserve r0 be optimized away if r0 turns out to be
6513                dead.  */
6514             i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6515             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6516                                                REG_NOTES (i));
6517             i = emit_move_insn (r0, tmp);
6518             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6519                                                REG_NOTES (i));
6520             break;
6521           }
6522     }
6523   DONE;
6524 }")
6525
6526 (define_insn "indirect_jump_compact"
6527   [(set (pc)
6528         (match_operand:SI 0 "arith_reg_operand" "r"))]
6529   "TARGET_SH1"
6530   "jmp  @%0%#"
6531   [(set_attr "needs_delay_slot" "yes")
6532    (set_attr "type" "jump_ind")])
6533
6534 (define_expand "indirect_jump"
6535   [(set (pc)
6536         (match_operand 0 "register_operand" ""))]
6537   ""
6538   "
6539 {
6540   if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6541     operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6542 }")
6543
6544 ;; The use of operand 1 / 2 helps us distinguish case table jumps
6545 ;; which can be present in structured code from indirect jumps which can not
6546 ;; be present in structured code.  This allows -fprofile-arcs to work.
6547
6548 ;; For SH1 processors.
6549 (define_insn "casesi_jump_1"
6550   [(set (pc)
6551         (match_operand:SI 0 "register_operand" "r"))
6552    (use (label_ref (match_operand 1 "" "")))]
6553   "TARGET_SH1"
6554   "jmp  @%0%#"
6555   [(set_attr "needs_delay_slot" "yes")
6556    (set_attr "type" "jump_ind")])
6557
6558 ;; For all later processors.
6559 (define_insn "casesi_jump_2"
6560   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
6561                       (label_ref (match_operand 1 "" ""))))
6562    (use (label_ref (match_operand 2 "" "")))]
6563   "TARGET_SH2
6564    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
6565   "braf %0%#"
6566   [(set_attr "needs_delay_slot" "yes")
6567    (set_attr "type" "jump_ind")])
6568
6569 (define_insn "casesi_jump_media"
6570   [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6571    (use (label_ref (match_operand 1 "" "")))]
6572   "TARGET_SHMEDIA"
6573   "blink        %0, r63"
6574   [(set_attr "type" "jump_media")])
6575
6576 ;; Call subroutine returning any type.
6577 ;; ??? This probably doesn't work.
6578
6579 (define_expand "untyped_call"
6580   [(parallel [(call (match_operand 0 "" "")
6581                     (const_int 0))
6582               (match_operand 1 "" "")
6583               (match_operand 2 "" "")])]
6584   "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
6585   "
6586 {
6587   int i;
6588
6589   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
6590
6591   for (i = 0; i < XVECLEN (operands[2], 0); i++)
6592     {
6593       rtx set = XVECEXP (operands[2], 0, i);
6594       emit_move_insn (SET_DEST (set), SET_SRC (set));
6595     }
6596
6597   /* The optimizer does not know that the call sets the function value
6598      registers we stored in the result block.  We avoid problems by
6599      claiming that all hard registers are used and clobbered at this
6600      point.  */
6601   emit_insn (gen_blockage ());
6602
6603   DONE;
6604 }")
6605 \f
6606 ;; ------------------------------------------------------------------------
6607 ;; Misc insns
6608 ;; ------------------------------------------------------------------------
6609
6610 (define_insn "dect"
6611   [(set (reg:SI T_REG)
6612         (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6613    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
6614   "TARGET_SH2"
6615   "dt   %0"
6616   [(set_attr "type" "arith")])
6617
6618 (define_insn "nop"
6619   [(const_int 0)]
6620   ""
6621   "nop")
6622
6623 ;; Load address of a label. This is only generated by the casesi expand,
6624 ;; and by machine_dependent_reorg (fixing up fp moves).
6625 ;; This must use unspec, because this only works for labels that are
6626 ;; within range,
6627
6628 (define_insn "mova"
6629   [(set (reg:SI R0_REG)
6630         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
6631   "TARGET_SH1"
6632   "mova %O0,r0"
6633   [(set_attr "in_delay_slot" "no")
6634    (set_attr "type" "arith")])
6635
6636 ;; machine_dependent_reorg will make this a `mova'.
6637 (define_insn "mova_const"
6638   [(set (reg:SI R0_REG)
6639         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
6640   "TARGET_SH1"
6641   "#"
6642   [(set_attr "in_delay_slot" "no")
6643    (set_attr "type" "arith")])
6644
6645 (define_expand "GOTaddr2picreg"
6646   [(set (reg:SI R0_REG)
6647         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6648                    UNSPEC_MOVA))
6649    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
6650    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6651   "" "
6652 {
6653   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
6654   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
6655
6656   if (TARGET_SH5)
6657     operands[1] = gen_datalabel_ref (operands[1]);
6658
6659   if (TARGET_SHMEDIA)
6660     {
6661       rtx tr = gen_rtx_REG (DImode, TR0_REG);
6662       rtx dipic = operands[0];
6663       rtx lab = PATTERN (gen_call_site ());
6664       rtx insn, equiv;
6665
6666       equiv = operands[1];
6667       operands[1] = gen_rtx_MINUS (DImode,
6668                                    operands[1],
6669                                    gen_rtx_CONST
6670                                    (DImode,
6671                                     gen_rtx_MINUS (DImode,
6672                                                    gen_rtx_CONST (DImode,
6673                                                                   lab),
6674                                                    pc_rtx)));
6675       operands[1] = gen_sym2PIC (operands[1]);
6676       PUT_MODE (operands[1], DImode);
6677
6678       if (GET_MODE (dipic) != DImode)
6679         dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6680
6681       if (TARGET_SHMEDIA64)
6682         emit_insn (gen_movdi_const (dipic, operands[1]));
6683       else
6684         emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6685
6686       emit_insn (gen_ptrel (tr, dipic, lab));
6687
6688       if (GET_MODE (operands[0]) != GET_MODE (tr))
6689         tr = gen_lowpart (GET_MODE (operands[0]), tr);
6690
6691       insn = emit_move_insn (operands[0], tr);
6692
6693       REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6694                                             REG_NOTES (insn));
6695
6696       DONE;
6697     }
6698 }
6699 ")
6700
6701 (define_insn "*ptb"
6702   [(set (match_operand:DI 0 "target_reg_operand" "=b")
6703         (const:DI (unspec:DI [(match_operand:DI 1 "" "Csy")]
6704                              UNSPEC_DATALABEL)))]
6705   "TARGET_SHMEDIA && flag_pic
6706    && EXTRA_CONSTRAINT_Csy (operands[1])"
6707   "ptb/u        datalabel %1, %0"
6708   [(set_attr "type" "pt_media")
6709    (set_attr "length" "*")])
6710
6711 (define_insn "ptrel"
6712   [(set (match_operand:DI 0 "target_reg_operand" "=b")
6713         (plus:DI (match_operand:DI 1 "register_operand" "r")
6714               (pc)))
6715    (match_operand:DI 2 "" "")]
6716   "TARGET_SHMEDIA"
6717   "%O2: ptrel/u %1, %0"
6718   [(set_attr "type" "ptabs_media")])
6719
6720 (define_expand "builtin_setjmp_receiver"
6721   [(match_operand 0 "" "")]
6722   "flag_pic"
6723   "
6724 {
6725   emit_insn (gen_GOTaddr2picreg ());
6726   DONE;
6727 }")
6728
6729 (define_expand "call_site"
6730   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
6731   "TARGET_SH1"
6732   "
6733 {
6734   static HOST_WIDE_INT i = 0;
6735   operands[0] = GEN_INT (i);
6736   i++;
6737 }")
6738
6739 (define_expand "sym_label2reg"
6740   [(set (match_operand:SI 0 "" "")
6741         (const:SI (minus:SI
6742                    (const:SI
6743                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6744                    (const:SI
6745                     (plus:SI
6746                      (match_operand:SI 2 "" "")
6747                      (const_int 2))))))]
6748   "TARGET_SH1" "")
6749
6750 (define_expand "symGOT_load"
6751   [(set (match_dup 2) (match_operand 1 "" ""))
6752    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6753    (set (match_operand 0 "" "") (mem (match_dup 3)))]
6754   ""
6755   "
6756 {
6757   rtx insn;
6758
6759   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6760   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6761
6762   if (TARGET_SHMEDIA)
6763     {
6764       rtx reg = operands[2];
6765
6766       if (GET_MODE (reg) != DImode)
6767         reg = gen_rtx_SUBREG (DImode, reg, 0);
6768
6769       if (flag_pic > 1)
6770         emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6771       else
6772         emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6773     }
6774   else
6775     emit_move_insn (operands[2], operands[1]);
6776
6777   emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6778                                              operands[2],
6779                                              gen_rtx_REG (Pmode, PIC_REG)));
6780
6781   insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6782
6783   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6784                                                                   0), 0, 0),
6785                                         REG_NOTES (insn));
6786
6787   DONE;
6788 }")
6789
6790 (define_expand "sym2GOT"
6791   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6792   ""
6793   "")
6794
6795 (define_expand "symGOT2reg"
6796   [(match_operand 0 "" "") (match_operand 1 "" "")]
6797   ""
6798   "
6799 {
6800   rtx gotsym, insn;
6801
6802   gotsym = gen_sym2GOT (operands[1]);
6803   PUT_MODE (gotsym, Pmode);
6804   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6805
6806   MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
6807
6808   DONE;
6809 }")
6810
6811 (define_expand "sym2GOTPLT"
6812   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6813   ""
6814   "")
6815
6816 (define_expand "symGOTPLT2reg"
6817   [(match_operand 0 "" "") (match_operand 1 "" "")]
6818   ""
6819   "
6820 {
6821   emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6822   DONE;
6823 }")
6824
6825 (define_expand "sym2GOTOFF"
6826   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6827   ""
6828   "")
6829
6830 (define_expand "symGOTOFF2reg"
6831   [(match_operand 0 "" "") (match_operand 1 "" "")]
6832   ""
6833   "
6834 {
6835   rtx gotoffsym, insn;
6836   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6837
6838   gotoffsym = gen_sym2GOTOFF (operands[1]);
6839   PUT_MODE (gotoffsym, Pmode);
6840   emit_move_insn (t, gotoffsym);
6841   insn = emit_move_insn (operands[0],
6842                          gen_rtx_PLUS (Pmode, t,
6843                                        gen_rtx_REG (Pmode, PIC_REG)));
6844
6845   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6846                                         REG_NOTES (insn));
6847
6848   DONE;
6849 }")
6850
6851 (define_expand "symPLT_label2reg"
6852   [(set (match_operand:SI 0 "" "")
6853         (const:SI (minus:SI
6854                    (const:SI
6855                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6856                    (const:SI
6857                     (minus:SI
6858                      (const:SI (plus:SI
6859                                 (match_operand:SI 2 "" "")
6860                                 (const_int 2)))
6861                      (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6862    ;; Even though the PIC register is not really used by the call
6863    ;; sequence in which this is expanded, the PLT code assumes the PIC
6864    ;; register is set, so we must not skip its initialization.  Since
6865    ;; we only use this expand as part of calling sequences, and never
6866    ;; to take the address of a function, this is the best point to
6867    ;; insert the (use).  Using the PLT to take the address of a
6868    ;; function would be wrong, not only because the PLT entry could
6869    ;; then be called from a function that doesn't initialize the PIC
6870    ;; register to the proper GOT, but also because pointers to the
6871    ;; same function might not compare equal, should they be set by
6872    ;; different shared libraries.
6873    (use (reg:SI PIC_REG))]
6874   "TARGET_SH1"
6875   "")
6876
6877 (define_expand "sym2PIC"
6878   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6879   ""
6880   "")
6881
6882 ;; TLS code generation.
6883 ;; ??? this should be a define_insn_and_split
6884 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
6885 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
6886 ;; for details.
6887
6888 (define_insn "tls_global_dynamic"
6889   [(set (match_operand:SI 0 "register_operand" "=&z")
6890         (call (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
6891                                   UNSPEC_TLSGD))
6892               (const_int 0)))
6893    (use (reg:PSI FPSCR_REG))
6894    (use (reg:SI PIC_REG))
6895    (clobber (reg:SI PR_REG))
6896    (clobber (scratch:SI))]
6897   "TARGET_SH1"
6898   "*
6899 {
6900   return \"\\
6901 mov.l\\t1f,r4\\n\\
6902 \\tmova\\t2f,r0\\n\\
6903 \\tmov.l\\t2f,r1\\n\\
6904 \\tadd\\tr0,r1\\n\\
6905 \\tjsr\\t@r1\\n\\
6906 \\tadd\\tr12,r4\\n\\
6907 \\tbra\\t3f\\n\\
6908 \\tnop\\n\\
6909 \\t.align\\t2\\n\\
6910 1:\\t.long\\t%a1@TLSGD\\n\\
6911 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6912 3:\";
6913 }"
6914   [(set_attr "type" "tls_load")
6915    (set_attr "length" "26")])
6916
6917 (define_insn "tls_local_dynamic"
6918   [(set (match_operand:SI 0 "register_operand" "=&z")
6919         (call (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
6920                                   UNSPEC_TLSLDM))
6921               (const_int 0)))
6922    (use (reg:PSI FPSCR_REG))
6923    (use (reg:SI PIC_REG))
6924    (clobber (reg:SI PR_REG))
6925    (clobber (scratch:SI))]
6926   "TARGET_SH1"
6927   "*
6928 {
6929   return \"\\
6930 mov.l\\t1f,r4\\n\\
6931 \\tmova\\t2f,r0\\n\\
6932 \\tmov.l\\t2f,r1\\n\\
6933 \\tadd\\tr0,r1\\n\\
6934 \\tjsr\\t@r1\\n\\
6935 \\tadd\\tr12,r4\\n\\
6936 \\tbra\\t3f\\n\\
6937 \\tnop\\n\\
6938 \\t.align\\t2\\n\\
6939 1:\\t.long\\t%a1@TLSLDM\\n\\
6940 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6941 3:\";
6942 }"
6943   [(set_attr "type" "tls_load")
6944    (set_attr "length" "26")])
6945
6946 (define_expand "sym2DTPOFF"
6947   [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
6948   ""
6949   "")
6950
6951 (define_expand "symDTPOFF2reg"
6952   [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
6953   ""
6954   "
6955 {
6956   rtx dtpoffsym, insn;
6957   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6958
6959   dtpoffsym = gen_sym2DTPOFF (operands[1]);
6960   PUT_MODE (dtpoffsym, Pmode);
6961   emit_move_insn (t, dtpoffsym);
6962   insn = emit_move_insn (operands[0],
6963                          gen_rtx_PLUS (Pmode, t, operands[2]));
6964   DONE;
6965 }")
6966
6967 (define_expand "sym2GOTTPOFF"
6968   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
6969   ""
6970   "")
6971
6972 (define_insn "tls_initial_exec"
6973   [(set (match_operand:SI 0 "register_operand" "=&r")
6974         (unspec:SI [(match_operand:SI 1 "" "")]
6975                     UNSPEC_TLSIE))
6976    (use (reg:SI GBR_REG))
6977    (use (reg:SI PIC_REG))
6978    (clobber (reg:SI R0_REG))]
6979   ""
6980   "*
6981 {
6982   return \"\\
6983 mov.l\\t1f,r0\\n\\
6984 \\tstc\\tgbr,%0\\n\\
6985 \\tmov.l\\t@(r0,r12),r0\\n\\
6986 \\tbra\\t2f\\n\\
6987 \\tadd\\tr0,%0\\n\\
6988 \\t.align\\t2\\n\\
6989 1:\\t.long\\t%a1\\n\\
6990 2:\";
6991 }"
6992   [(set_attr "type" "tls_load")
6993    (set_attr "length" "16")])
6994
6995 (define_expand "sym2TPOFF"
6996   [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
6997   ""
6998   "")
6999
7000 (define_expand "symTPOFF2reg"
7001   [(match_operand 0 "" "") (match_operand 1 "" "")]
7002   ""
7003   "
7004 {
7005   rtx tpoffsym, insn;
7006
7007   tpoffsym = gen_sym2TPOFF (operands[1]);
7008   PUT_MODE (tpoffsym, Pmode);
7009   insn = emit_move_insn (operands[0], tpoffsym);
7010   DONE;
7011 }")
7012
7013 (define_insn "load_gbr"
7014   [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
7015    (use (reg:SI GBR_REG))]
7016   ""
7017   "stc  gbr,%0"
7018   [(set_attr "type" "tls_load")])
7019
7020 ;; case instruction for switch statements.
7021
7022 ;; Operand 0 is index
7023 ;; operand 1 is the minimum bound
7024 ;; operand 2 is the maximum bound - minimum bound + 1
7025 ;; operand 3 is CODE_LABEL for the table;
7026 ;; operand 4 is the CODE_LABEL to go to if index out of range.
7027
7028 (define_expand "casesi"
7029   [(match_operand:SI 0 "arith_reg_operand" "")
7030    (match_operand:SI 1 "arith_reg_operand" "")
7031    (match_operand:SI 2 "arith_reg_operand" "")
7032    (match_operand 3 "" "") (match_operand 4 "" "")]
7033   ""
7034   "
7035 {
7036   rtx reg = gen_reg_rtx (SImode);
7037   rtx reg2 = gen_reg_rtx (SImode);
7038   if (TARGET_SHMEDIA)
7039     {
7040       rtx reg = gen_reg_rtx (DImode);
7041       rtx reg2 = gen_reg_rtx (DImode);
7042       rtx reg3 = gen_reg_rtx (DImode);
7043       rtx reg4 = gen_reg_rtx (DImode);
7044       rtx reg5 = gen_reg_rtx (DImode);
7045
7046       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
7047       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
7048       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
7049
7050       emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
7051       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
7052       emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
7053       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
7054       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
7055                                                (DImode, operands[3])));
7056       emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
7057       emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
7058       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
7059       emit_barrier ();
7060       DONE;
7061     }
7062   operands[1] = copy_to_mode_reg (SImode, operands[1]);
7063   operands[2] = copy_to_mode_reg (SImode, operands[2]);
7064   /* If optimizing, casesi_worker depends on the mode of the instruction
7065      before label it 'uses' - operands[3].  */
7066   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
7067                            reg));
7068   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
7069   if (TARGET_SH2)
7070     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
7071   else
7072     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
7073   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
7074      operands[3], but to lab.  We will fix this up in
7075      machine_dependent_reorg.  */
7076   emit_barrier ();
7077   DONE;
7078 }")
7079
7080 (define_expand "casesi_0"
7081   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
7082    (set (match_dup 4) (minus:SI (match_dup 4)
7083                                 (match_operand:SI 1 "arith_operand" "")))
7084    (set (reg:SI T_REG)
7085         (gtu:SI (match_dup 4)
7086                 (match_operand:SI 2 "arith_reg_operand" "")))
7087    (set (pc)
7088         (if_then_else (ne (reg:SI T_REG)
7089                           (const_int 0))
7090                       (label_ref (match_operand 3 "" ""))
7091                       (pc)))]
7092   "TARGET_SH1"
7093   "")
7094
7095 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
7096 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
7097 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
7098
7099 (define_insn "casesi_worker_0"
7100   [(set (match_operand:SI 0 "register_operand" "=r,r")
7101         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
7102                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7103    (clobber (match_scratch:SI 3 "=X,1"))
7104    (clobber (match_scratch:SI 4 "=&z,z"))]
7105   "TARGET_SH1"
7106   "#")
7107
7108 (define_split
7109   [(set (match_operand:SI 0 "register_operand" "")
7110         (unspec:SI [(match_operand:SI 1 "register_operand" "")
7111                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7112    (clobber (match_scratch:SI 3 ""))
7113    (clobber (match_scratch:SI 4 ""))]
7114   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
7115   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7116    (parallel [(set (match_dup 0)
7117               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7118                           (label_ref (match_dup 2))] UNSPEC_CASESI))
7119               (clobber (match_dup 3))])
7120    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
7121   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7122
7123 (define_split
7124   [(set (match_operand:SI 0 "register_operand" "")
7125         (unspec:SI [(match_operand:SI 1 "register_operand" "")
7126                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7127    (clobber (match_scratch:SI 3 ""))
7128    (clobber (match_scratch:SI 4 ""))]
7129   "TARGET_SH2 && reload_completed"
7130   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7131    (parallel [(set (match_dup 0)
7132               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7133                           (label_ref (match_dup 2))] UNSPEC_CASESI))
7134               (clobber (match_dup 3))])]
7135   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7136
7137 (define_insn "casesi_worker_1"
7138   [(set (match_operand:SI 0 "register_operand" "=r,r")
7139         (unspec:SI [(reg:SI R0_REG)
7140                     (match_operand:SI 1 "register_operand" "0,r")
7141                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7142    (clobber (match_scratch:SI 3 "=X,1"))]
7143   "TARGET_SH1"
7144   "*
7145 {
7146   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7147
7148   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7149     abort ();
7150
7151   switch (GET_MODE (diff_vec))
7152     {
7153     case SImode:
7154       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
7155     case HImode:
7156       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
7157     case QImode:
7158       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7159         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
7160       return \"mov.b    @(r0,%1),%0\";
7161     default:
7162       abort ();
7163     }
7164 }"
7165   [(set_attr "length" "4")])
7166
7167 (define_insn "casesi_worker_2"
7168   [(set (match_operand:SI 0 "register_operand" "=r,r")
7169         (unspec:SI [(reg:SI R0_REG)
7170                     (match_operand:SI 1 "register_operand" "0,r")
7171                     (label_ref (match_operand 2 "" ""))
7172                     (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
7173    (clobber (match_operand:SI 4 "" "=X,1"))]
7174   "TARGET_SH2 && reload_completed && flag_pic"
7175   "*
7176 {
7177   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7178   const char *load;
7179
7180   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7181     abort ();
7182
7183   switch (GET_MODE (diff_vec))
7184     {
7185     case SImode:
7186       output_asm_insn (\"shll2    %1\", operands);
7187       load = \"mov.l    @(r0,%1),%0\"; break;
7188     case HImode:
7189       output_asm_insn (\"add    %1,%1\", operands);
7190       load = \"mov.w    @(r0,%1),%0\"; break;
7191     case QImode:
7192       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7193         load = \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
7194       else
7195         load = \"mov.b  @(r0,%1),%0\";
7196       break;
7197     default:
7198       abort ();
7199     }
7200   output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
7201   return load;
7202 }"
7203   [(set_attr "length" "8")])
7204
7205 (define_insn "casesi_shift_media"
7206   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7207         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
7208                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
7209                     UNSPEC_CASESI)))]
7210   "TARGET_SHMEDIA"
7211   "*
7212 {
7213   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7214
7215   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7216     abort ();
7217
7218   switch (GET_MODE (diff_vec))
7219     {
7220     case SImode:
7221       return \"shlli    %1, 2, %0\";
7222     case HImode:
7223       return \"shlli    %1, 1, %0\";
7224     case QImode:
7225       if (rtx_equal_p (operands[0], operands[1]))
7226         return \"\";
7227       return \"add      %1, r63, %0\";
7228     default:
7229       abort ();
7230     }
7231 }"
7232   [(set_attr "type" "arith_media")])
7233
7234 (define_insn "casesi_load_media"
7235   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7236         (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
7237                          (match_operand 2 "arith_reg_operand" "r")
7238                          (label_ref:DI (match_operand 3 "" ""))] 2)))]
7239   "TARGET_SHMEDIA"
7240   "*
7241 {
7242   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
7243
7244   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7245     abort ();
7246
7247   switch (GET_MODE (diff_vec))
7248     {
7249     case SImode:
7250       return \"ldx.l    %1, %2, %0\";
7251     case HImode:
7252 #if 0
7253       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7254         return \"ldx.uw %1, %2, %0\";
7255 #endif
7256       return \"ldx.w    %1, %2, %0\";
7257     case QImode:
7258       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7259         return \"ldx.ub %1, %2, %0\";
7260       return \"ldx.b    %1, %2, %0\";
7261     default:
7262       abort ();
7263     }
7264 }"
7265   [(set_attr "type" "load_media")])
7266
7267 (define_expand "return"
7268   [(return)]
7269   "reload_completed && ! sh_need_epilogue ()"
7270   "
7271 {
7272   if (TARGET_SHMEDIA)
7273     {
7274       emit_jump_insn (gen_return_media ());
7275       DONE;
7276     }
7277
7278   if (TARGET_SHCOMPACT
7279       && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
7280     {
7281       emit_jump_insn (gen_shcompact_return_tramp ());
7282       DONE;
7283     }
7284 }")
7285
7286 (define_insn "*return_i"
7287   [(return)]
7288   "TARGET_SH1 && ! (TARGET_SHCOMPACT
7289                     && (current_function_args_info.call_cookie
7290                         & CALL_COOKIE_RET_TRAMP (1)))
7291    && reload_completed"
7292   "%@   %#"
7293   [(set_attr "type" "return")
7294    (set_attr "needs_delay_slot" "yes")])
7295
7296 (define_expand "shcompact_return_tramp"
7297   [(return)]
7298   "TARGET_SHCOMPACT
7299    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7300   "
7301 {
7302   rtx reg = gen_rtx_REG (Pmode, R0_REG);
7303   rtx sym = function_symbol (\"__GCC_shcompact_return_trampoline\");
7304
7305   if (flag_pic)
7306     emit_insn (gen_symGOTPLT2reg (reg, sym));
7307   else
7308     emit_move_insn (reg, sym);
7309
7310   emit_jump_insn (gen_shcompact_return_tramp_i ());
7311   DONE;
7312 }")
7313
7314 (define_insn "shcompact_return_tramp_i"
7315   [(parallel [(return) (use (reg:SI R0_REG))])]
7316   "TARGET_SHCOMPACT
7317    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7318   "jmp  @r0%#"
7319   [(set_attr "type" "jump_ind")
7320    (set_attr "needs_delay_slot" "yes")])
7321
7322 (define_insn "return_media_i"
7323   [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7324   "TARGET_SHMEDIA && reload_completed"
7325   "blink        %0, r63"
7326   [(set_attr "type" "jump_media")])
7327
7328 (define_insn "return_media_rte"
7329   [(return)]
7330   "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
7331   "rte"
7332   [(set_attr "type" "jump_media")])
7333
7334 (define_expand "return_media"
7335   [(return)]
7336   "TARGET_SHMEDIA && reload_completed"
7337   "
7338 {
7339   int tr_regno = sh_media_register_for_return ();
7340   rtx tr;
7341
7342   if (current_function_interrupt)
7343     {
7344       emit_jump_insn (gen_return_media_rte ());
7345       DONE;
7346     }
7347   if (tr_regno < 0)
7348     {
7349       rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7350
7351       if (! call_really_used_regs[TR0_REG] || fixed_regs[TR0_REG])
7352         abort ();
7353       tr_regno = TR0_REG;
7354       tr = gen_rtx_REG (DImode, tr_regno);
7355       emit_move_insn (tr, r18);
7356     }
7357   else
7358     tr = gen_rtx_REG (DImode, tr_regno);
7359
7360   emit_jump_insn (gen_return_media_i (tr));
7361   DONE;
7362 }")
7363
7364 (define_insn "shcompact_preserve_incoming_args"
7365   [(set (match_operand:SI 0 "register_operand" "+r")
7366         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
7367   "TARGET_SHCOMPACT"
7368   ""
7369   [(set_attr "length" "0")])
7370
7371 (define_insn "shcompact_incoming_args"
7372   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7373    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7374    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7375    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7376    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7377    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7378    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7379    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
7380    (set (mem:BLK (reg:SI MACL_REG))
7381         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
7382    (use (reg:SI R0_REG))
7383    (clobber (reg:SI R0_REG))
7384    (clobber (reg:SI MACL_REG))
7385    (clobber (reg:SI MACH_REG))
7386    (clobber (reg:SI PR_REG))]
7387   "TARGET_SHCOMPACT"
7388   "jsr  @r0%#"
7389   [(set_attr "needs_delay_slot" "yes")])
7390
7391 (define_insn "shmedia_save_restore_regs_compact"
7392   [(set (reg:SI SP_REG)
7393         (plus:SI (reg:SI SP_REG)
7394                  (match_operand:SI 0 "immediate_operand" "i")))
7395    (use (reg:SI R0_REG))
7396    (clobber (reg:SI PR_REG))]
7397   "TARGET_SHCOMPACT
7398    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7399        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7400   "jsr @r0%#"
7401   [(set_attr "needs_delay_slot" "yes")])
7402
7403 (define_expand "prologue"
7404   [(const_int 0)]
7405   ""
7406   "sh_expand_prologue (); DONE;")
7407
7408 (define_expand "epilogue"
7409   [(return)]
7410   ""
7411   "
7412 {
7413   sh_expand_epilogue (0);
7414   emit_jump_insn (gen_return ());
7415   DONE;
7416 }")
7417
7418 (define_expand "eh_return"
7419   [(use (match_operand 0 "register_operand" ""))]
7420   ""
7421 {
7422   rtx ra = operands[0];
7423
7424   if (TARGET_SHMEDIA64)
7425     emit_insn (gen_eh_set_ra_di (ra));
7426   else
7427     emit_insn (gen_eh_set_ra_si (ra));
7428
7429   DONE;
7430 })
7431
7432 ;; Clobber the return address on the stack.  We can't expand this
7433 ;; until we know where it will be put in the stack frame.
7434
7435 (define_insn "eh_set_ra_si"
7436   [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7437    (clobber (match_scratch:SI 1 "=&r"))]
7438   "! TARGET_SHMEDIA64"
7439   "#")
7440
7441 (define_insn "eh_set_ra_di"
7442   [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7443    (clobber (match_scratch:DI 1 "=&r"))]
7444   "TARGET_SHMEDIA64"
7445   "#")
7446
7447 (define_split
7448   [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
7449    (clobber (match_scratch 1 ""))]
7450   "reload_completed"
7451   [(const_int 0)]
7452   "
7453 {
7454   sh_set_return_address (operands[0], operands[1]);
7455   DONE;
7456 }")
7457
7458 (define_insn "blockage"
7459   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7460   ""
7461   ""
7462   [(set_attr "length" "0")])
7463 \f
7464 ;; ------------------------------------------------------------------------
7465 ;; Scc instructions
7466 ;; ------------------------------------------------------------------------
7467
7468 (define_insn "movt"
7469   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7470         (eq:SI (reg:SI T_REG) (const_int 1)))]
7471   "TARGET_SH1"
7472   "movt %0"
7473   [(set_attr "type" "arith")])
7474
7475 (define_expand "seq"
7476   [(set (match_operand:SI 0 "arith_reg_operand" "")
7477         (match_dup 1))]
7478   ""
7479   "
7480 {
7481   if (TARGET_SHMEDIA)
7482     {
7483       if (GET_MODE (operands[0]) != DImode)
7484         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7485       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7486       if (sh_compare_op1 != const0_rtx)
7487         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7488                                     ? GET_MODE (sh_compare_op0)
7489                                     : GET_MODE (sh_compare_op1),
7490                                     sh_compare_op1);
7491
7492       switch (GET_MODE (sh_compare_op0))
7493         {
7494         case DImode:
7495           emit_insn (gen_cmpeqdi_media (operands[0],
7496                                         sh_compare_op0, sh_compare_op1));
7497           break;
7498
7499         case SFmode:
7500           if (! TARGET_SHMEDIA_FPU)
7501             FAIL;
7502           emit_insn (gen_cmpeqsf_media (operands[0],
7503                                         sh_compare_op0, sh_compare_op1));
7504           break;
7505
7506         case DFmode:
7507           if (! TARGET_SHMEDIA_FPU)
7508             FAIL;
7509           emit_insn (gen_cmpeqdf_media (operands[0],
7510                                         sh_compare_op0, sh_compare_op1));
7511           break;
7512
7513         default:
7514           FAIL;
7515         }
7516       DONE;
7517     }
7518   if (sh_expand_t_scc (EQ, operands[0]))
7519     DONE;
7520   if (! currently_expanding_to_rtl)
7521     FAIL;
7522   operands[1] = prepare_scc_operands (EQ);
7523 }")
7524
7525 (define_expand "slt"
7526   [(set (match_operand:SI 0 "arith_reg_operand" "")
7527         (match_dup 1))]
7528   ""
7529   "
7530 {
7531   if (TARGET_SHMEDIA)
7532     {
7533       if (GET_MODE (operands[0]) != DImode)
7534         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7535       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7536       if (sh_compare_op1 != const0_rtx)
7537         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7538                                     ? GET_MODE (sh_compare_op0)
7539                                     : GET_MODE (sh_compare_op1),
7540                                     sh_compare_op1);
7541
7542       switch (GET_MODE (sh_compare_op0))
7543         {
7544         case DImode:
7545           emit_insn (gen_cmpgtdi_media (operands[0],
7546                                         sh_compare_op1, sh_compare_op0));
7547           break;
7548
7549         case SFmode:
7550           if (! TARGET_SHMEDIA_FPU)
7551             FAIL;
7552           emit_insn (gen_cmpgtsf_media (operands[0],
7553                                         sh_compare_op1, sh_compare_op0));
7554           break;
7555
7556         case DFmode:
7557           if (! TARGET_SHMEDIA_FPU)
7558             FAIL;
7559           emit_insn (gen_cmpgtdf_media (operands[0],
7560                                         sh_compare_op1, sh_compare_op0));
7561           break;
7562
7563         default:
7564           FAIL;
7565         }
7566       DONE;
7567     }
7568   if (! currently_expanding_to_rtl)
7569     FAIL;
7570   operands[1] = prepare_scc_operands (LT);
7571 }")
7572
7573 (define_expand "sle"
7574   [(match_operand:SI 0 "arith_reg_operand" "")]
7575   ""
7576   "
7577 {
7578   rtx tmp = sh_compare_op0;
7579
7580   if (TARGET_SHMEDIA)
7581     {
7582       if (GET_MODE (operands[0]) != DImode)
7583         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7584       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7585       if (sh_compare_op1 != const0_rtx)
7586         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7587                                     ? GET_MODE (sh_compare_op0)
7588                                     : GET_MODE (sh_compare_op1),
7589                                     sh_compare_op1);
7590
7591       switch (GET_MODE (sh_compare_op0))
7592         {
7593         case DImode:
7594           {
7595             tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7596
7597             emit_insn (gen_cmpgtdi_media (tmp,
7598                                           sh_compare_op0, sh_compare_op1));
7599             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7600             break;
7601           }
7602
7603         case SFmode:
7604           if (! TARGET_SHMEDIA_FPU)
7605             FAIL;
7606           emit_insn (gen_cmpgesf_media (operands[0],
7607                                         sh_compare_op1, sh_compare_op0));
7608           break;
7609
7610         case DFmode:
7611           if (! TARGET_SHMEDIA_FPU)
7612             FAIL;
7613           emit_insn (gen_cmpgedf_media (operands[0],
7614                                         sh_compare_op1, sh_compare_op0));
7615           break;
7616
7617         default:
7618           FAIL;
7619         }
7620       DONE;
7621     }
7622
7623   sh_compare_op0 = sh_compare_op1;
7624   sh_compare_op1 = tmp;
7625   emit_insn (gen_sge (operands[0]));
7626   DONE;
7627 }")
7628
7629 (define_expand "sgt"
7630   [(set (match_operand:SI 0 "arith_reg_operand" "")
7631         (match_dup 1))]
7632   ""
7633   "
7634 {
7635   if (TARGET_SHMEDIA)
7636     {
7637       if (GET_MODE (operands[0]) != DImode)
7638         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7639       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7640       if (sh_compare_op1 != const0_rtx)
7641         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7642                                     ? GET_MODE (sh_compare_op0)
7643                                     : GET_MODE (sh_compare_op1),
7644                                     sh_compare_op1);
7645
7646       switch (GET_MODE (sh_compare_op0))
7647         {
7648         case DImode:
7649           emit_insn (gen_cmpgtdi_media (operands[0],
7650                                         sh_compare_op0, sh_compare_op1));
7651           break;
7652
7653         case SFmode:
7654           if (! TARGET_SHMEDIA_FPU)
7655             FAIL;
7656           emit_insn (gen_cmpgtsf_media (operands[0],
7657                                         sh_compare_op0, sh_compare_op1));
7658           break;
7659
7660         case DFmode:
7661           if (! TARGET_SHMEDIA_FPU)
7662             FAIL;
7663           emit_insn (gen_cmpgtdf_media (operands[0],
7664                                         sh_compare_op0, sh_compare_op1));
7665           break;
7666
7667         default:
7668           FAIL;
7669         }
7670       DONE;
7671     }
7672   if (! currently_expanding_to_rtl)
7673     FAIL;
7674   operands[1] = prepare_scc_operands (GT);
7675 }")
7676
7677 (define_expand "sge"
7678   [(set (match_operand:SI 0 "arith_reg_operand" "")
7679         (match_dup 1))]
7680   ""
7681   "
7682 {
7683   if (TARGET_SHMEDIA)
7684     {
7685       if (GET_MODE (operands[0]) != DImode)
7686         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7687       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7688       if (sh_compare_op1 != const0_rtx)
7689         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7690                                     ? GET_MODE (sh_compare_op0)
7691                                     : GET_MODE (sh_compare_op1),
7692                                     sh_compare_op1);
7693
7694       switch (GET_MODE (sh_compare_op0))
7695         {
7696         case DImode:
7697           {
7698             rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7699
7700             emit_insn (gen_cmpgtdi_media (tmp,
7701                                           sh_compare_op1, sh_compare_op0));
7702             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7703             break;
7704           }
7705
7706         case SFmode:
7707           if (! TARGET_SHMEDIA_FPU)
7708             FAIL;
7709           emit_insn (gen_cmpgesf_media (operands[0],
7710                                         sh_compare_op0, sh_compare_op1));
7711           break;
7712
7713         case DFmode:
7714           if (! TARGET_SHMEDIA_FPU)
7715             FAIL;
7716           emit_insn (gen_cmpgedf_media (operands[0],
7717                                         sh_compare_op0, sh_compare_op1));
7718           break;
7719
7720         default:
7721           FAIL;
7722         }
7723       DONE;
7724     }
7725
7726   if (! currently_expanding_to_rtl)
7727     FAIL;
7728   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7729     {
7730       if (TARGET_IEEE)
7731         {
7732           rtx lab = gen_label_rtx ();
7733           prepare_scc_operands (EQ);
7734           emit_jump_insn (gen_branch_true (lab));
7735           prepare_scc_operands (GT);
7736           emit_label (lab);
7737           emit_insn (gen_movt (operands[0]));
7738         }
7739       else
7740         emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
7741       DONE;
7742     }
7743   operands[1] = prepare_scc_operands (GE);
7744 }")
7745
7746 (define_expand "sgtu"
7747   [(set (match_operand:SI 0 "arith_reg_operand" "")
7748         (match_dup 1))]
7749   ""
7750   "
7751 {
7752   if (TARGET_SHMEDIA)
7753     {
7754       if (GET_MODE (operands[0]) != DImode)
7755         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7756       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7757       if (sh_compare_op1 != const0_rtx)
7758         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7759                                     ? GET_MODE (sh_compare_op0)
7760                                     : GET_MODE (sh_compare_op1),
7761                                     sh_compare_op1);
7762
7763       emit_insn (gen_cmpgtudi_media (operands[0],
7764                                      sh_compare_op0, sh_compare_op1));
7765       DONE;
7766     }
7767   if (! currently_expanding_to_rtl)
7768     FAIL;
7769   operands[1] = prepare_scc_operands (GTU);
7770 }")
7771
7772 (define_expand "sltu"
7773   [(set (match_operand:SI 0 "arith_reg_operand" "")
7774         (match_dup 1))]
7775   ""
7776   "
7777 {
7778   if (TARGET_SHMEDIA)
7779     {
7780       if (GET_MODE (operands[0]) != DImode)
7781         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7782       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7783       if (sh_compare_op1 != const0_rtx)
7784         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7785                                     ? GET_MODE (sh_compare_op0)
7786                                     : GET_MODE (sh_compare_op1),
7787                                     sh_compare_op1);
7788
7789       emit_insn (gen_cmpgtudi_media (operands[0],
7790                                      sh_compare_op1, sh_compare_op0));
7791       DONE;
7792     }
7793   if (! currently_expanding_to_rtl)
7794     FAIL;
7795   operands[1] = prepare_scc_operands (LTU);
7796 }")
7797
7798 (define_expand "sleu"
7799   [(set (match_operand:SI 0 "arith_reg_operand" "")
7800         (match_dup 1))]
7801   ""
7802   "
7803 {
7804   if (TARGET_SHMEDIA)
7805     {
7806       rtx tmp;
7807
7808       if (GET_MODE (operands[0]) != DImode)
7809         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7810       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7811       if (sh_compare_op1 != const0_rtx)
7812         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7813                                     ? GET_MODE (sh_compare_op0)
7814                                     : GET_MODE (sh_compare_op1),
7815                                     sh_compare_op1);
7816
7817       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7818
7819       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7820       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7821
7822       DONE;
7823     }
7824   if (! currently_expanding_to_rtl)
7825     FAIL;
7826   operands[1] = prepare_scc_operands (LEU);
7827 }")
7828
7829 (define_expand "sgeu"
7830   [(set (match_operand:SI 0 "arith_reg_operand" "")
7831         (match_dup 1))]
7832   ""
7833   "
7834 {
7835   if (TARGET_SHMEDIA)
7836     {
7837       rtx tmp;
7838
7839       if (GET_MODE (operands[0]) != DImode)
7840         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7841       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7842       if (sh_compare_op1 != const0_rtx)
7843         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7844                                     ? GET_MODE (sh_compare_op0)
7845                                     : GET_MODE (sh_compare_op1),
7846                                     sh_compare_op1);
7847
7848       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7849
7850       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7851       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7852
7853       DONE;
7854     }
7855
7856   if (! currently_expanding_to_rtl)
7857     FAIL;
7858   operands[1] = prepare_scc_operands (GEU);
7859 }")
7860
7861 ;; sne moves the complement of the T reg to DEST like this:
7862 ;;      cmp/eq ...
7863 ;;      mov    #-1,temp
7864 ;;      negc   temp,dest
7865 ;;   This is better than xoring compare result with 1 because it does
7866 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
7867 ;;   loop.
7868
7869 (define_expand "sne"
7870   [(set (match_dup 2) (const_int -1))
7871    (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7872                    (neg:SI (plus:SI (match_dup 1)
7873                                     (match_dup 2))))
7874               (set (reg:SI T_REG)
7875                    (ne:SI (ior:SI (match_dup 1) (match_dup 2))
7876                           (const_int 0)))])]
7877   ""
7878   "
7879 {
7880   if (TARGET_SHMEDIA)
7881     {
7882       rtx tmp;
7883
7884       if (GET_MODE (operands[0]) != DImode)
7885         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7886
7887       if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7888         FAIL;
7889
7890       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7891       if (sh_compare_op1 != const0_rtx)
7892         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7893                                     ? GET_MODE (sh_compare_op0)
7894                                     : GET_MODE (sh_compare_op1),
7895                                     sh_compare_op1);
7896
7897       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7898
7899       emit_insn (gen_seq (tmp));
7900       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7901
7902       DONE;
7903     }
7904
7905   if (sh_expand_t_scc (NE, operands[0]))
7906     DONE;
7907   if (! currently_expanding_to_rtl)
7908     FAIL;
7909   operands[1] = prepare_scc_operands (EQ);
7910   operands[2] = gen_reg_rtx (SImode);
7911 }")
7912
7913 (define_expand "sunordered"
7914   [(set (match_operand:DI 0 "arith_reg_operand" "")
7915         (unordered:DI (match_dup 1) (match_dup 2)))]
7916   "TARGET_SHMEDIA_FPU"
7917   "
7918 {
7919   operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7920   operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7921 }")
7922
7923 ;; Use the same trick for FP sle / sge
7924 (define_expand "movnegt"
7925   [(set (match_dup 2) (const_int -1))
7926    (parallel [(set (match_operand 0 "" "")
7927                    (neg:SI (plus:SI (match_dup 1)
7928                                     (match_dup 2))))
7929               (set (reg:SI T_REG)
7930                    (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
7931                           (const_int 0)))])]
7932   "TARGET_SH1"
7933   "operands[2] = gen_reg_rtx (SImode);")
7934
7935 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
7936 ;; This prevents a regression that occurred when we switched from xor to
7937 ;; mov/neg for sne.
7938
7939 (define_split
7940   [(set (match_operand:SI 0 "arith_reg_operand" "")
7941         (plus:SI (reg:SI T_REG)
7942                  (const_int -1)))]
7943   "TARGET_SH1"
7944   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
7945    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7946   "")
7947
7948 ;; -------------------------------------------------------------------------
7949 ;; Instructions to cope with inline literal tables
7950 ;; -------------------------------------------------------------------------
7951
7952 ; 2 byte integer in line
7953
7954 (define_insn "consttable_2"
7955  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7956                     (match_operand 1 "" "")]
7957                    UNSPECV_CONST2)]
7958  ""
7959  "*
7960 {
7961   if (operands[1] != const0_rtx)
7962     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
7963   return \"\";
7964 }"
7965  [(set_attr "length" "2")
7966  (set_attr "in_delay_slot" "no")])
7967
7968 ; 4 byte integer in line
7969
7970 (define_insn "consttable_4"
7971  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7972                     (match_operand 1 "" "")]
7973                    UNSPECV_CONST4)]
7974  ""
7975  "*
7976 {
7977   if (operands[1] != const0_rtx)
7978     assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
7979   return \"\";
7980 }"
7981  [(set_attr "length" "4")
7982   (set_attr "in_delay_slot" "no")])
7983
7984 ; 8 byte integer in line
7985
7986 (define_insn "consttable_8"
7987  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7988                     (match_operand 1 "" "")]
7989                    UNSPECV_CONST8)]
7990  ""
7991  "*
7992 {
7993   if (operands[1] != const0_rtx)
7994     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
7995   return \"\";
7996 }"
7997  [(set_attr "length" "8")
7998   (set_attr "in_delay_slot" "no")])
7999
8000 ; 4 byte floating point
8001
8002 (define_insn "consttable_sf"
8003  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
8004                     (match_operand 1 "" "")]
8005                    UNSPECV_CONST4)]
8006  ""
8007  "*
8008 {
8009   if (operands[1] != const0_rtx)
8010     {
8011       REAL_VALUE_TYPE d;
8012       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
8013       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
8014     }
8015   return \"\";
8016 }"
8017  [(set_attr "length" "4")
8018   (set_attr "in_delay_slot" "no")])
8019
8020 ; 8 byte floating point
8021
8022 (define_insn "consttable_df"
8023  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
8024                     (match_operand 1 "" "")]
8025                    UNSPECV_CONST8)]
8026  ""
8027  "*
8028 {
8029   if (operands[1] != const0_rtx)
8030     {
8031       REAL_VALUE_TYPE d;
8032       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
8033       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
8034     }
8035   return \"\";
8036 }"
8037  [(set_attr "length" "8")
8038   (set_attr "in_delay_slot" "no")])
8039
8040 ;; Alignment is needed for some constant tables; it may also be added for
8041 ;; Instructions at the start of loops, or after unconditional branches.
8042 ;; ??? We would get more accurate lengths if we did instruction
8043 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
8044 ;; here is too conservative.
8045
8046 ; align to a two byte boundary
8047
8048 (define_expand "align_2"
8049  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
8050  ""
8051  "")
8052
8053 ; align to a four byte boundary
8054 ;; align_4 and align_log are instructions for the starts of loops, or
8055 ;; after unconditional branches, which may take up extra room.
8056
8057 (define_expand "align_4"
8058  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
8059  ""
8060  "")
8061
8062 ; align to a cache line boundary
8063
8064 (define_insn "align_log"
8065  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
8066  ""
8067  ""
8068  [(set_attr "length" "0")
8069   (set_attr "in_delay_slot" "no")])
8070
8071 ; emitted at the end of the literal table, used to emit the
8072 ; 32bit branch labels if needed.
8073
8074 (define_insn "consttable_end"
8075   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
8076   ""
8077   "* return output_jump_label_table ();"
8078   [(set_attr "in_delay_slot" "no")])
8079
8080 ; emitted at the end of the window in the literal table.
8081
8082 (define_insn "consttable_window_end"
8083   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
8084   ""
8085   ""
8086   [(set_attr "length" "0")
8087    (set_attr "in_delay_slot" "no")])
8088
8089 ;; -------------------------------------------------------------------------
8090 ;; Misc
8091 ;; -------------------------------------------------------------------------
8092
8093 ;; String/block move insn.
8094
8095 (define_expand "movmemsi"
8096   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
8097                    (mem:BLK (match_operand:BLK 1 "" "")))
8098               (use (match_operand:SI 2 "nonmemory_operand" ""))
8099               (use (match_operand:SI 3 "immediate_operand" ""))
8100               (clobber (reg:SI PR_REG))
8101               (clobber (reg:SI R4_REG))
8102               (clobber (reg:SI R5_REG))
8103               (clobber (reg:SI R0_REG))])]
8104   "TARGET_SH1 && ! TARGET_SH5"
8105   "
8106 {
8107   if(expand_block_move (operands))
8108      DONE;
8109   else FAIL;
8110 }")
8111
8112 (define_insn "block_move_real"
8113   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8114                    (mem:BLK (reg:SI R5_REG)))
8115               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8116               (clobber (reg:SI PR_REG))
8117               (clobber (reg:SI R0_REG))])]
8118   "TARGET_SH1 && ! TARGET_HARD_SH4"
8119   "jsr  @%0%#"
8120   [(set_attr "type" "sfunc")
8121    (set_attr "needs_delay_slot" "yes")])
8122
8123 (define_insn "block_lump_real"
8124   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8125                    (mem:BLK (reg:SI R5_REG)))
8126               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8127               (use (reg:SI R6_REG))
8128               (clobber (reg:SI PR_REG))
8129               (clobber (reg:SI T_REG))
8130               (clobber (reg:SI R4_REG))
8131               (clobber (reg:SI R5_REG))
8132               (clobber (reg:SI R6_REG))
8133               (clobber (reg:SI R0_REG))])]
8134   "TARGET_SH1 && ! TARGET_HARD_SH4"
8135   "jsr  @%0%#"
8136   [(set_attr "type" "sfunc")
8137    (set_attr "needs_delay_slot" "yes")])
8138
8139 (define_insn "block_move_real_i4"
8140   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8141                    (mem:BLK (reg:SI R5_REG)))
8142               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8143               (clobber (reg:SI PR_REG))
8144               (clobber (reg:SI R0_REG))
8145               (clobber (reg:SI R1_REG))
8146               (clobber (reg:SI R2_REG))])]
8147   "TARGET_HARD_SH4"
8148   "jsr  @%0%#"
8149   [(set_attr "type" "sfunc")
8150    (set_attr "needs_delay_slot" "yes")])
8151
8152 (define_insn "block_lump_real_i4"
8153   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8154                    (mem:BLK (reg:SI R5_REG)))
8155               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8156               (use (reg:SI R6_REG))
8157               (clobber (reg:SI PR_REG))
8158               (clobber (reg:SI T_REG))
8159               (clobber (reg:SI R4_REG))
8160               (clobber (reg:SI R5_REG))
8161               (clobber (reg:SI R6_REG))
8162               (clobber (reg:SI R0_REG))
8163               (clobber (reg:SI R1_REG))
8164               (clobber (reg:SI R2_REG))
8165               (clobber (reg:SI R3_REG))])]
8166   "TARGET_HARD_SH4"
8167   "jsr  @%0%#"
8168   [(set_attr "type" "sfunc")
8169    (set_attr "needs_delay_slot" "yes")])
8170 \f
8171 ;; -------------------------------------------------------------------------
8172 ;; Floating point instructions.
8173 ;; -------------------------------------------------------------------------
8174
8175 ;; ??? All patterns should have a type attribute.
8176
8177 (define_expand "fpu_switch0"
8178   [(set (match_operand:SI 0 "" "") (match_dup 2))
8179    (set (match_dup 1) (mem:PSI (match_dup 0)))]
8180   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8181   "
8182 {
8183   operands[1] = get_fpscr_rtx ();
8184   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8185   if (flag_pic)
8186     operands[2] = legitimize_pic_address (operands[2], SImode,
8187                                           no_new_pseudos ? operands[0] : 0);
8188 }")
8189
8190 (define_expand "fpu_switch1"
8191   [(set (match_operand:SI 0 "" "") (match_dup 2))
8192    (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
8193    (set (match_dup 1) (mem:PSI (match_dup 3)))]
8194   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8195   "
8196 {
8197   operands[1] = get_fpscr_rtx ();
8198   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8199   if (flag_pic)
8200     operands[2] = legitimize_pic_address (operands[2], SImode,
8201                                           no_new_pseudos ? operands[0] : 0);
8202   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
8203 }")
8204
8205 (define_expand "movpsi"
8206   [(set (match_operand:PSI 0 "register_operand" "")
8207         (match_operand:PSI 1 "general_movsrc_operand" ""))]
8208   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8209   "")
8210
8211 ;; The c / m alternative is a fake to guide reload to load directly into
8212 ;; fpscr, since reload doesn't know how to use post-increment.
8213 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
8214 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
8215 ;; predicate after reload.
8216 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
8217 ;; like a mac -> gpr move.
8218 (define_insn "fpu_switch"
8219   [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
8220         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
8221   "TARGET_SH2E
8222    && (! reload_completed
8223        || true_regnum (operands[0]) != FPSCR_REG
8224        || GET_CODE (operands[1]) != MEM
8225        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
8226   "@
8227         ! precision stays the same
8228         lds.l   %1,fpscr
8229         mov.l   %1,%0
8230         #
8231         lds     %1,fpscr
8232         mov     %1,%0
8233         mov.l   %1,%0
8234         sts     fpscr,%0
8235         sts.l   fpscr,%0"
8236   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
8237    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
8238
8239 (define_split
8240   [(set (reg:PSI FPSCR_REG)
8241         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8242   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
8243   [(set (match_dup 0) (match_dup 0))]
8244   "
8245 {
8246   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8247                                         gen_rtx_MEM (PSImode,
8248                                                  gen_rtx_POST_INC (Pmode,
8249                                                           operands[0]))));
8250   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
8251 }")
8252
8253 (define_split
8254   [(set (reg:PSI FPSCR_REG)
8255         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8256   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8257   [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
8258   "
8259 {
8260   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8261                                         gen_rtx_MEM (PSImode,
8262                                                  gen_rtx_POST_INC (Pmode,
8263                                                           operands[0]))));
8264   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
8265 }")
8266
8267 ;; ??? This uses the fp unit, but has no type indicating that.
8268 ;; If we did that, this would either give a bogus latency or introduce
8269 ;; a bogus FIFO constraint.
8270 ;; Since this insn is currently only used for prologues/epilogues,
8271 ;; it is probably best to claim no function unit, which matches the
8272 ;; current setting.
8273 (define_insn "toggle_sz"
8274   [(set (reg:PSI FPSCR_REG)
8275         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
8276   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8277   "fschg"
8278   [(set_attr "type" "fp") (set_attr "fp_set" "unknown")])
8279
8280 ;; There's no way we can use it today, since optimize mode switching
8281 ;; doesn't enable us to know from which mode we're switching to the
8282 ;; mode it requests, to tell whether we can use a relative mode switch
8283 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
8284 ;; memory).
8285 (define_insn "toggle_pr"
8286   [(set (reg:PSI FPSCR_REG)
8287         (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
8288   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
8289   "fpchg"
8290   [(set_attr "type" "fp")])
8291
8292 (define_expand "addsf3"
8293   [(set (match_operand:SF 0 "arith_reg_operand" "")
8294         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
8295                  (match_operand:SF 2 "arith_reg_operand" "")))]
8296   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8297   "
8298 {
8299   if (TARGET_SH2E)
8300     {
8301       expand_sf_binop (&gen_addsf3_i, operands);
8302       DONE;
8303     }
8304 }")
8305
8306 (define_insn "*addsf3_media"
8307   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8308         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8309                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8310   "TARGET_SHMEDIA_FPU"
8311   "fadd.s       %1, %2, %0"
8312   [(set_attr "type" "fparith_media")])
8313
8314 (define_insn_and_split "unary_sf_op"
8315   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8316         (vec_select:V2SF
8317          (vec_concat:V2SF
8318           (vec_select:SF
8319            (match_dup 0)
8320            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
8321           (match_operator:SF 2 "unary_float_operator"
8322             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8323                             (parallel [(match_operand 4
8324                                         "const_int_operand" "n")]))]))
8325          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
8326   "TARGET_SHMEDIA_FPU"
8327   "#"
8328   "TARGET_SHMEDIA_FPU && reload_completed"
8329   [(set (match_dup 5) (match_dup 6))]
8330   "
8331 {
8332   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8333   rtx op1 = gen_rtx_REG (SFmode,
8334                          (true_regnum (operands[1])
8335                           + (INTVAL (operands[4]) ^ endian)));
8336
8337   operands[7] = gen_rtx_REG (SFmode,
8338                              (true_regnum (operands[0])
8339                               + (INTVAL (operands[3]) ^ endian)));
8340   operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
8341 }"
8342   [(set_attr "type" "fparith_media")])
8343
8344 (define_insn_and_split "binary_sf_op"
8345   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8346         (vec_select:V2SF
8347          (vec_concat:V2SF
8348           (vec_select:SF
8349            (match_dup 0)
8350            (parallel [(match_operand 7 "const_int_operand" "n")]))
8351           (match_operator:SF 3 "binary_float_operator"
8352             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8353                             (parallel [(match_operand 5
8354                                         "const_int_operand" "n")]))
8355              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
8356                             (parallel [(match_operand 6
8357                                         "const_int_operand" "n")]))]))
8358          (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
8359   "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
8360   "#"
8361   "&& reload_completed"
8362   [(set (match_dup 8) (match_dup 9))]
8363   "
8364 {
8365   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8366   rtx op1 = gen_rtx_REG (SFmode,
8367                          (true_regnum (operands[1])
8368                           + (INTVAL (operands[5]) ^ endian)));
8369   rtx op2 = gen_rtx_REG (SFmode,
8370                          (true_regnum (operands[2])
8371                           + (INTVAL (operands[6]) ^ endian)));
8372
8373   operands[8] = gen_rtx_REG (SFmode,
8374                              (true_regnum (operands[0])
8375                               + (INTVAL (operands[4]) ^ endian)));
8376   operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
8377 }"
8378   [(set_attr "type" "fparith_media")])
8379
8380 (define_insn "addsf3_i"
8381   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8382         (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
8383                  (match_operand:SF 2 "arith_reg_operand" "f")))
8384    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8385   "TARGET_SH2E"
8386   "fadd %2,%0"
8387   [(set_attr "type" "fp")
8388    (set_attr "fp_mode" "single")])
8389
8390 (define_expand "subsf3"
8391   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8392         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8393                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8394   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8395   "
8396 {
8397   if (TARGET_SH2E)
8398     {
8399       expand_sf_binop (&gen_subsf3_i, operands);
8400       DONE;
8401     }
8402 }")
8403
8404 (define_insn "*subsf3_media"
8405   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8406         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8407                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8408   "TARGET_SHMEDIA_FPU"
8409   "fsub.s       %1, %2, %0"
8410   [(set_attr "type" "fparith_media")])
8411
8412 (define_insn "subsf3_i"
8413   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8414         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8415                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8416    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8417   "TARGET_SH2E"
8418   "fsub %2,%0"
8419   [(set_attr "type" "fp")
8420    (set_attr "fp_mode" "single")])
8421
8422 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8423 ;; register in feeding fp instructions.  Thus, we cannot generate fmac for
8424 ;; mixed-precision SH4 targets.  To allow it to be still generated for the
8425 ;; SH3E, we use a separate insn for SH3E mulsf3.
8426
8427 (define_expand "mulsf3"
8428   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8429         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8430                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8431   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8432   "
8433 {
8434   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
8435     expand_sf_binop (&gen_mulsf3_i4, operands);
8436   else if (TARGET_SH2E)
8437     emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
8438   if (! TARGET_SHMEDIA)
8439     DONE;
8440 }")
8441
8442 (define_insn "*mulsf3_media"
8443   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8444         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8445                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8446   "TARGET_SHMEDIA_FPU"
8447   "fmul.s       %1, %2, %0"
8448   [(set_attr "type" "fparith_media")])
8449
8450 (define_insn "mulsf3_i4"
8451   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8452         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8453                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8454    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8455   "TARGET_SH2E"
8456   "fmul %2,%0"
8457   [(set_attr "type" "fp")
8458    (set_attr "fp_mode" "single")])
8459
8460 (define_insn "mulsf3_ie"
8461   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8462         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8463                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8464   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8465   "fmul %2,%0"
8466   [(set_attr "type" "fp")])
8467
8468 (define_insn "*mac_media"
8469   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8470         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8471                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8472                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8473   "TARGET_SHMEDIA_FPU"
8474   "fmac.s %1, %2, %0"
8475   [(set_attr "type" "fparith_media")])
8476
8477 (define_insn "*macsf3"
8478   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8479         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8480                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8481                  (match_operand:SF 3 "arith_reg_operand" "0")))
8482    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
8483   "TARGET_SH2E && ! TARGET_SH4"
8484   "fmac fr0,%2,%0"
8485   [(set_attr "type" "fp")
8486    (set_attr "fp_mode" "single")])
8487
8488 (define_expand "divsf3"
8489   [(set (match_operand:SF 0 "arith_reg_operand" "")
8490         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8491                 (match_operand:SF 2 "arith_reg_operand" "")))]
8492   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8493   "
8494 {
8495   if (TARGET_SH2E)
8496     {
8497       expand_sf_binop (&gen_divsf3_i, operands);
8498       DONE;
8499     }
8500 }")
8501
8502 (define_insn "*divsf3_media"
8503   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8504         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8505                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8506   "TARGET_SHMEDIA_FPU"
8507   "fdiv.s       %1, %2, %0"
8508   [(set_attr "type" "fdiv_media")])
8509
8510 (define_insn "divsf3_i"
8511   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8512         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
8513                  (match_operand:SF 2 "arith_reg_operand" "f")))
8514    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8515   "TARGET_SH2E"
8516   "fdiv %2,%0"
8517   [(set_attr "type" "fdiv")
8518    (set_attr "fp_mode" "single")])
8519
8520 (define_insn "floatdisf2"
8521   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8522         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8523   "TARGET_SHMEDIA_FPU"
8524   "float.qs %1, %0"
8525   [(set_attr "type" "fpconv_media")])
8526
8527 (define_expand "floatsisf2"
8528   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8529         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
8530   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8531   "
8532 {
8533   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
8534     {
8535       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8536       DONE;
8537     }
8538 }")
8539
8540 (define_insn "*floatsisf2_media"
8541   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8542         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8543   "TARGET_SHMEDIA_FPU"
8544   "float.ls     %1, %0"
8545   [(set_attr "type" "fpconv_media")])
8546
8547 (define_insn "floatsisf2_i4"
8548   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8549         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
8550    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8551   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
8552   "float        %1,%0"
8553   [(set_attr "type" "fp")
8554    (set_attr "fp_mode" "single")])
8555
8556 (define_insn "*floatsisf2_ie"
8557   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8558         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
8559   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8560   "float        %1,%0"
8561   [(set_attr "type" "fp")])
8562
8563 (define_insn "fix_truncsfdi2"
8564   [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8565         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8566   "TARGET_SHMEDIA_FPU"
8567   "ftrc.sq %1, %0"
8568   [(set_attr "type" "fpconv_media")])
8569
8570 (define_expand "fix_truncsfsi2"
8571   [(set (match_operand:SI 0 "fpul_operand" "=y")
8572         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8573   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8574   "
8575 {
8576   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
8577     {
8578       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8579       DONE;
8580     }
8581 }")
8582
8583 (define_insn "*fix_truncsfsi2_media"
8584   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8585         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8586   "TARGET_SHMEDIA_FPU"
8587   "ftrc.sl      %1, %0"
8588   [(set_attr "type" "fpconv_media")])
8589
8590 (define_insn "fix_truncsfsi2_i4"
8591   [(set (match_operand:SI 0 "fpul_operand" "=y")
8592         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8593    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8594   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
8595   "ftrc %1,%0"
8596   [(set_attr "type" "ftrc_s")
8597    (set_attr "fp_mode" "single")])
8598
8599 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
8600 ;; fix_truncsfsi2_i4.
8601 ;; (define_insn "fix_truncsfsi2_i4_2"
8602 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8603 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8604 ;;   (use (reg:PSI FPSCR_REG))
8605 ;;   (clobber (reg:SI FPUL_REG))]
8606 ;;  "TARGET_SH4"
8607 ;;  "#"
8608 ;;  [(set_attr "length" "4")
8609 ;;   (set_attr "fp_mode" "single")])
8610
8611 ;;(define_split
8612 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8613 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8614 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
8615 ;;   (clobber (reg:SI FPUL_REG))]
8616 ;;  "TARGET_SH4"
8617 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8618 ;;            (use (match_dup 2))])
8619 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
8620
8621 (define_insn "*fixsfsi"
8622   [(set (match_operand:SI 0 "fpul_operand" "=y")
8623         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8624   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8625   "ftrc %1,%0"
8626   [(set_attr "type" "fp")])
8627
8628 (define_insn "cmpgtsf_t"
8629   [(set (reg:SI T_REG)
8630         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8631                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8632   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8633   "fcmp/gt      %1,%0"
8634   [(set_attr "type" "fp")
8635    (set_attr "fp_mode" "single")])
8636
8637 (define_insn "cmpeqsf_t"
8638   [(set (reg:SI T_REG)
8639         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8640                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8641   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8642   "fcmp/eq      %1,%0"
8643   [(set_attr "type" "fp")
8644    (set_attr "fp_mode" "single")])
8645
8646 (define_insn "ieee_ccmpeqsf_t"
8647   [(set (reg:SI T_REG)
8648         (ior:SI (reg:SI T_REG)
8649                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8650                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
8651   "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8652   "* return output_ieee_ccmpeq (insn, operands);"
8653   [(set_attr "length" "4")])
8654
8655
8656 (define_insn "cmpgtsf_t_i4"
8657   [(set (reg:SI T_REG)
8658         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8659                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8660    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8661   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
8662   "fcmp/gt      %1,%0"
8663   [(set_attr "type" "fp")
8664    (set_attr "fp_mode" "single")])
8665
8666 (define_insn "cmpeqsf_t_i4"
8667   [(set (reg:SI T_REG)
8668         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8669                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8670    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8671   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
8672   "fcmp/eq      %1,%0"
8673   [(set_attr "type" "fp")
8674    (set_attr "fp_mode" "single")])
8675
8676 (define_insn "*ieee_ccmpeqsf_t_4"
8677   [(set (reg:SI T_REG)
8678         (ior:SI (reg:SI T_REG)
8679                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8680                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
8681    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8682   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8683   "* return output_ieee_ccmpeq (insn, operands);"
8684   [(set_attr "length" "4")
8685    (set_attr "fp_mode" "single")])
8686
8687 (define_insn "cmpeqsf_media"
8688   [(set (match_operand:DI 0 "register_operand" "=r")
8689         (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8690                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8691   "TARGET_SHMEDIA_FPU"
8692   "fcmpeq.s     %1, %2, %0"
8693   [(set_attr "type" "fcmp_media")])
8694
8695 (define_insn "cmpgtsf_media"
8696   [(set (match_operand:DI 0 "register_operand" "=r")
8697         (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8698                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8699   "TARGET_SHMEDIA_FPU"
8700   "fcmpgt.s     %1, %2, %0"
8701   [(set_attr "type" "fcmp_media")])
8702
8703 (define_insn "cmpgesf_media"
8704   [(set (match_operand:DI 0 "register_operand" "=r")
8705         (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8706                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8707   "TARGET_SHMEDIA_FPU"
8708   "fcmpge.s     %1, %2, %0"
8709   [(set_attr "type" "fcmp_media")])
8710
8711 (define_insn "cmpunsf_media"
8712   [(set (match_operand:DI 0 "register_operand" "=r")
8713         (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8714                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8715   "TARGET_SHMEDIA_FPU"
8716   "fcmpun.s     %1, %2, %0"
8717   [(set_attr "type" "fcmp_media")])
8718
8719 (define_expand "cmpsf"
8720   [(set (reg:SI T_REG)
8721         (compare (match_operand:SF 0 "arith_operand" "")
8722                  (match_operand:SF 1 "arith_operand" "")))]
8723   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8724   "
8725 {
8726   sh_compare_op0 = operands[0];
8727   sh_compare_op1 = operands[1];
8728   DONE;
8729 }")
8730
8731 (define_expand "negsf2"
8732   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8733         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8734   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8735   "
8736 {
8737   if (TARGET_SH2E)
8738     {
8739       expand_sf_unop (&gen_negsf2_i, operands);
8740       DONE;
8741     }
8742 }")
8743
8744 (define_insn "*negsf2_media"
8745   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8746         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8747   "TARGET_SHMEDIA_FPU"
8748   "fneg.s       %1, %0"
8749   [(set_attr "type" "fmove_media")])
8750
8751 (define_insn "negsf2_i"
8752   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8753         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8754    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8755   "TARGET_SH2E"
8756   "fneg %0"
8757   [(set_attr "type" "fmove")
8758    (set_attr "fp_mode" "single")])
8759
8760 (define_expand "sqrtsf2"
8761   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8762         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8763   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8764   "
8765 {
8766   if (TARGET_SH3E)
8767     {
8768       expand_sf_unop (&gen_sqrtsf2_i, operands);
8769       DONE;
8770     }
8771 }")
8772
8773 (define_insn "*sqrtsf2_media"
8774   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8775         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8776   "TARGET_SHMEDIA_FPU"
8777   "fsqrt.s      %1, %0"
8778   [(set_attr "type" "fdiv_media")])
8779
8780 (define_insn "sqrtsf2_i"
8781   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8782         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8783    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8784   "TARGET_SH3E"
8785   "fsqrt        %0"
8786   [(set_attr "type" "fdiv")
8787    (set_attr "fp_mode" "single")])
8788
8789 (define_insn "rsqrtsf2"
8790   [(set (match_operand:SF 0 "register_operand" "=f")
8791         (div:SF (match_operand:SF 1 "immediate_operand" "i")
8792                 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
8793    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8794   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
8795    && operands[1] == CONST1_RTX (SFmode)"
8796   "fsrra        %0"
8797   [(set_attr "type" "fsrra")
8798    (set_attr "fp_mode" "single")])
8799
8800 (define_insn "fsca"
8801   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8802         (vec_concat:V2SF
8803          (unspec:SF [(mult:SF
8804                       (float:SF (match_operand:SI 1 "fpul_operand" "y"))
8805                       (match_operand:SF 2 "immediate_operand" "i"))
8806                     ] UNSPEC_FSINA)
8807          (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
8808                     ] UNSPEC_FCOSA)))
8809    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8810   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
8811    && operands[2] == sh_fsca_int2sf ()"
8812   "fsca fpul,%d0"
8813   [(set_attr "type" "fsca")
8814    (set_attr "fp_mode" "single")])
8815
8816 (define_expand "sinsf2"
8817   [(set (match_operand:SF 0 "nonimmediate_operand" "")
8818         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
8819                    UNSPEC_FSINA))]
8820   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
8821   "
8822 {
8823   rtx scaled = gen_reg_rtx (SFmode);
8824   rtx truncated = gen_reg_rtx (SImode);
8825   rtx fsca = gen_reg_rtx (V2SFmode);
8826   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
8827
8828   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
8829   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
8830   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8831                           get_fpscr_rtx ()));
8832   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
8833   DONE;
8834 }")
8835
8836 (define_expand "cossf2"
8837   [(set (match_operand:SF 0 "nonimmediate_operand" "")
8838         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
8839                    UNSPEC_FCOSA))]
8840   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
8841   "
8842 {
8843   rtx scaled = gen_reg_rtx (SFmode);
8844   rtx truncated = gen_reg_rtx (SImode);
8845   rtx fsca = gen_reg_rtx (V2SFmode);
8846   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
8847
8848   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
8849   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
8850   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8851                           get_fpscr_rtx ()));
8852   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
8853   DONE;
8854 }")
8855
8856 (define_expand "sindf2"
8857   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8858         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
8859                    UNSPEC_FSINA))]
8860   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
8861   "
8862 {
8863   rtx scaled = gen_reg_rtx (DFmode);
8864   rtx truncated = gen_reg_rtx (SImode);
8865   rtx fsca = gen_reg_rtx (V2SFmode);
8866   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
8867   rtx sfresult = gen_reg_rtx (SFmode);
8868
8869   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
8870   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
8871   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8872                           get_fpscr_rtx ()));
8873   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
8874   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
8875   DONE;
8876 }")
8877
8878 (define_expand "cosdf2"
8879   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8880         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
8881                    UNSPEC_FCOSA))]
8882   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
8883   "
8884 {
8885   rtx scaled = gen_reg_rtx (DFmode);
8886   rtx truncated = gen_reg_rtx (SImode);
8887   rtx fsca = gen_reg_rtx (V2SFmode);
8888   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
8889   rtx sfresult = gen_reg_rtx (SFmode);
8890
8891   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
8892   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
8893   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8894                           get_fpscr_rtx ()));
8895   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
8896   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
8897   DONE;
8898 }")
8899
8900 (define_expand "abssf2"
8901   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8902         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8903   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8904   "
8905 {
8906   if (TARGET_SH2E)
8907     {
8908       expand_sf_unop (&gen_abssf2_i, operands);
8909       DONE;
8910     }
8911 }")
8912
8913 (define_insn "*abssf2_media"
8914   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8915         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8916   "TARGET_SHMEDIA_FPU"
8917   "fabs.s       %1, %0"
8918   [(set_attr "type" "fmove_media")])
8919
8920 (define_insn "abssf2_i"
8921   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8922         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8923    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8924   "TARGET_SH2E"
8925   "fabs %0"
8926   [(set_attr "type" "fmove")
8927    (set_attr "fp_mode" "single")])
8928
8929 (define_expand "adddf3"
8930   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8931         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8932                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8933   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
8934   "
8935 {
8936   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
8937     {
8938       expand_df_binop (&gen_adddf3_i, operands);
8939       DONE;
8940     }
8941 }")
8942
8943 (define_insn "*adddf3_media"
8944   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8945         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8946                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8947   "TARGET_SHMEDIA_FPU"
8948   "fadd.d       %1, %2, %0"
8949   [(set_attr "type" "dfparith_media")])
8950
8951 (define_insn "adddf3_i"
8952   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8953         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8954                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8955    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8956   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8957   "fadd %2,%0"
8958   [(set_attr "type" "dfp_arith")
8959    (set_attr "fp_mode" "double")])
8960
8961 (define_expand "subdf3"
8962   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8963         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8964                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8965   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
8966   "
8967 {
8968   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
8969     {
8970       expand_df_binop (&gen_subdf3_i, operands);
8971       DONE;
8972     }
8973 }")
8974
8975 (define_insn "*subdf3_media"
8976   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8977         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8978                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8979   "TARGET_SHMEDIA_FPU"
8980   "fsub.d       %1, %2, %0"
8981   [(set_attr "type" "dfparith_media")])
8982
8983 (define_insn "subdf3_i"
8984   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8985         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8986                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8987    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8988   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8989   "fsub %2,%0"
8990   [(set_attr "type" "dfp_arith")
8991    (set_attr "fp_mode" "double")])
8992
8993 (define_expand "muldf3"
8994   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8995         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8996                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8997   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
8998   "
8999 {
9000   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9001     {
9002       expand_df_binop (&gen_muldf3_i, operands);
9003       DONE;
9004     }
9005 }")
9006
9007 (define_insn "*muldf3_media"
9008   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9009         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
9010                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9011   "TARGET_SHMEDIA_FPU"
9012   "fmul.d       %1, %2, %0"
9013   [(set_attr "type" "dfmul_media")])
9014
9015 (define_insn "muldf3_i"
9016   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9017         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
9018                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
9019    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9020   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9021   "fmul %2,%0"
9022   [(set_attr "type" "dfp_arith")
9023    (set_attr "fp_mode" "double")])
9024
9025 (define_expand "divdf3"
9026   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
9027         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
9028                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
9029   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9030   "
9031 {
9032   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9033     {
9034       expand_df_binop (&gen_divdf3_i, operands);
9035       DONE;
9036     }
9037 }")
9038
9039 (define_insn "*divdf3_media"
9040   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9041         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
9042                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9043   "TARGET_SHMEDIA_FPU"
9044   "fdiv.d       %1, %2, %0"
9045   [(set_attr "type" "dfdiv_media")])
9046
9047 (define_insn "divdf3_i"
9048   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9049         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
9050                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
9051    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9052   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9053   "fdiv %2,%0"
9054   [(set_attr "type" "dfdiv")
9055    (set_attr "fp_mode" "double")])
9056
9057 (define_insn "floatdidf2"
9058   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9059         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
9060   "TARGET_SHMEDIA_FPU"
9061   "float.qd     %1, %0"
9062   [(set_attr "type" "dfpconv_media")])
9063
9064 (define_expand "floatsidf2"
9065   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
9066         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
9067   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9068   "
9069 {
9070   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9071     {
9072       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
9073                                       get_fpscr_rtx ()));
9074       DONE;
9075     }
9076 }")
9077
9078 (define_insn "*floatsidf2_media"
9079   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9080         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
9081   "TARGET_SHMEDIA_FPU"
9082   "float.ld     %1, %0"
9083   [(set_attr "type" "dfpconv_media")])
9084
9085 (define_insn "floatsidf2_i"
9086   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9087         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
9088    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9089   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9090   "float        %1,%0"
9091   [(set_attr "type" "dfp_conv")
9092    (set_attr "fp_mode" "double")])
9093
9094 (define_insn "fix_truncdfdi2"
9095   [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
9096         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9097   "TARGET_SHMEDIA_FPU"
9098   "ftrc.dq      %1, %0"
9099   [(set_attr "type" "dfpconv_media")])
9100
9101 (define_expand "fix_truncdfsi2"
9102   [(set (match_operand:SI 0 "fpul_operand" "")
9103         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
9104   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9105   "
9106 {
9107   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9108     {
9109       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
9110                                           get_fpscr_rtx ()));
9111       DONE;
9112     }
9113 }")
9114
9115 (define_insn "*fix_truncdfsi2_media"
9116   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
9117         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9118   "TARGET_SHMEDIA_FPU"
9119   "ftrc.dl      %1, %0"
9120   [(set_attr "type" "dfpconv_media")])
9121
9122 (define_insn "fix_truncdfsi2_i"
9123   [(set (match_operand:SI 0 "fpul_operand" "=y")
9124         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
9125    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9126   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9127   "ftrc %1,%0"
9128   [(set_attr "type" "dfp_conv")
9129    (set_attr "dfp_comp" "no")
9130    (set_attr "fp_mode" "double")])
9131
9132 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
9133 ;; fix_truncdfsi2_i.
9134 ;; (define_insn "fix_truncdfsi2_i4"
9135 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9136 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
9137 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
9138 ;;    (clobber (reg:SI FPUL_REG))]
9139 ;;   "TARGET_SH4"
9140 ;;   "#"
9141 ;;   [(set_attr "length" "4")
9142 ;;    (set_attr "fp_mode" "double")])
9143 ;;
9144 ;; (define_split
9145 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9146 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
9147 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
9148 ;;    (clobber (reg:SI FPUL_REG))]
9149 ;;   "TARGET_SH4"
9150 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
9151 ;;            (use (match_dup 2))])
9152 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
9153
9154 (define_insn "cmpgtdf_t"
9155   [(set (reg:SI T_REG)
9156         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
9157                (match_operand:DF 1 "arith_reg_operand" "f")))
9158    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9159   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9160   "fcmp/gt      %1,%0"
9161   [(set_attr "type" "dfp_cmp")
9162    (set_attr "fp_mode" "double")])
9163
9164 (define_insn "cmpeqdf_t"
9165   [(set (reg:SI T_REG)
9166         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
9167                (match_operand:DF 1 "arith_reg_operand" "f")))
9168    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9169   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9170   "fcmp/eq      %1,%0"
9171   [(set_attr "type" "dfp_cmp")
9172    (set_attr "fp_mode" "double")])
9173
9174 (define_insn "*ieee_ccmpeqdf_t"
9175   [(set (reg:SI T_REG)
9176         (ior:SI (reg:SI T_REG)
9177                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
9178                        (match_operand:DF 1 "arith_reg_operand" "f"))))
9179    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9180   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9181   "* return output_ieee_ccmpeq (insn, operands);"
9182   [(set_attr "length" "4")
9183    (set_attr "fp_mode" "double")])
9184
9185 (define_insn "cmpeqdf_media"
9186   [(set (match_operand:DI 0 "register_operand" "=r")
9187         (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9188                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9189   "TARGET_SHMEDIA_FPU"
9190   "fcmpeq.d     %1,%2,%0"
9191   [(set_attr "type" "fcmp_media")])
9192
9193 (define_insn "cmpgtdf_media"
9194   [(set (match_operand:DI 0 "register_operand" "=r")
9195         (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9196                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9197   "TARGET_SHMEDIA_FPU"
9198   "fcmpgt.d     %1,%2,%0"
9199   [(set_attr "type" "fcmp_media")])
9200
9201 (define_insn "cmpgedf_media"
9202   [(set (match_operand:DI 0 "register_operand" "=r")
9203         (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9204                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9205   "TARGET_SHMEDIA_FPU"
9206   "fcmpge.d     %1,%2,%0"
9207   [(set_attr "type" "fcmp_media")])
9208
9209 (define_insn "cmpundf_media"
9210   [(set (match_operand:DI 0 "register_operand" "=r")
9211         (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9212                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9213   "TARGET_SHMEDIA_FPU"
9214   "fcmpun.d     %1,%2,%0"
9215   [(set_attr "type" "fcmp_media")])
9216
9217 (define_expand "cmpdf"
9218   [(set (reg:SI T_REG)
9219         (compare (match_operand:DF 0 "arith_operand" "")
9220                  (match_operand:DF 1 "arith_operand" "")))]
9221   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9222   "
9223 {
9224   sh_compare_op0 = operands[0];
9225   sh_compare_op1 = operands[1];
9226   DONE;
9227 }")
9228
9229 (define_expand "negdf2"
9230   [(set (match_operand:DF 0 "arith_reg_operand" "")
9231         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9232   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9233   "
9234 {
9235   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9236     {
9237       expand_df_unop (&gen_negdf2_i, operands);
9238       DONE;
9239     }
9240 }")
9241
9242 (define_insn "*negdf2_media"
9243   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9244         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9245   "TARGET_SHMEDIA_FPU"
9246   "fneg.d       %1, %0"
9247   [(set_attr "type" "fmove_media")])
9248
9249 (define_insn "negdf2_i"
9250   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9251         (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9252    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9253   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9254   "fneg %0"
9255   [(set_attr "type" "fmove")
9256    (set_attr "fp_mode" "double")])
9257
9258 (define_expand "sqrtdf2"
9259   [(set (match_operand:DF 0 "arith_reg_operand" "")
9260         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9261   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9262   "
9263 {
9264   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9265     {
9266       expand_df_unop (&gen_sqrtdf2_i, operands);
9267       DONE;
9268     }
9269 }")
9270
9271 (define_insn "*sqrtdf2_media"
9272   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9273         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9274   "TARGET_SHMEDIA_FPU"
9275   "fsqrt.d      %1, %0"
9276   [(set_attr "type" "dfdiv_media")])
9277
9278 (define_insn "sqrtdf2_i"
9279   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9280         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9281    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9282   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9283   "fsqrt        %0"
9284   [(set_attr "type" "dfdiv")
9285    (set_attr "fp_mode" "double")])
9286
9287 (define_expand "absdf2"
9288   [(set (match_operand:DF 0 "arith_reg_operand" "")
9289         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9290   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9291   "
9292 {
9293   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9294     {
9295       expand_df_unop (&gen_absdf2_i, operands);
9296       DONE;
9297     }
9298 }")
9299
9300 (define_insn "*absdf2_media"
9301   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9302         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9303   "TARGET_SHMEDIA_FPU"
9304   "fabs.d       %1, %0"
9305   [(set_attr "type" "fmove_media")])
9306
9307 (define_insn "absdf2_i"
9308   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9309         (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9310    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9311   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9312   "fabs %0"
9313   [(set_attr "type" "fmove")
9314    (set_attr "fp_mode" "double")])
9315
9316 (define_expand "extendsfdf2"
9317   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
9318         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
9319   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9320   "
9321 {
9322   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9323     {
9324       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
9325                                         get_fpscr_rtx ()));
9326       DONE;
9327     }
9328 }")
9329
9330 (define_insn "*extendsfdf2_media"
9331   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9332         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
9333   "TARGET_SHMEDIA_FPU"
9334   "fcnv.sd      %1, %0"
9335   [(set_attr "type" "dfpconv_media")])
9336
9337 (define_insn "extendsfdf2_i4"
9338   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9339         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
9340    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9341   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9342   "fcnvsd  %1,%0"
9343   [(set_attr "type" "fp")
9344    (set_attr "fp_mode" "double")])
9345
9346 (define_expand "truncdfsf2"
9347   [(set (match_operand:SF 0 "fpul_operand" "")
9348         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
9349   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9350   "
9351 {
9352   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9353     {
9354       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
9355                                        get_fpscr_rtx ()));
9356       DONE;
9357     }
9358 }")
9359
9360 (define_insn "*truncdfsf2_media"
9361   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9362         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9363   "TARGET_SHMEDIA_FPU"
9364   "fcnv.ds      %1, %0"
9365   [(set_attr "type" "dfpconv_media")])
9366
9367 (define_insn "truncdfsf2_i4"
9368   [(set (match_operand:SF 0 "fpul_operand" "=y")
9369         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
9370    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9371   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9372   "fcnvds  %1,%0"
9373   [(set_attr "type" "fp")
9374    (set_attr "fp_mode" "double")])
9375 \f
9376 ;; Bit field extract patterns.  These give better code for packed bitfields,
9377 ;; because they allow auto-increment addresses to be generated.
9378
9379 (define_expand "insv"
9380   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
9381                          (match_operand:SI 1 "immediate_operand" "")
9382                          (match_operand:SI 2 "immediate_operand" ""))
9383         (match_operand:SI 3 "general_operand" ""))]
9384   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
9385   "
9386 {
9387   rtx addr_target, orig_address, shift_reg, qi_val;
9388   HOST_WIDE_INT bitsize, size, v = 0;
9389   rtx x = operands[3];
9390
9391   /* ??? expmed doesn't care for non-register predicates.  */
9392   if (! memory_operand (operands[0], VOIDmode)
9393       || ! immediate_operand (operands[1], VOIDmode)
9394       || ! immediate_operand (operands[2], VOIDmode)
9395       || ! general_operand (x, VOIDmode))
9396     FAIL;
9397   /* If this isn't a 16 / 24 / 32 bit field, or if
9398      it doesn't start on a byte boundary, then fail.  */
9399   bitsize = INTVAL (operands[1]);
9400   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
9401       || (INTVAL (operands[2]) % 8) != 0)
9402     FAIL;
9403
9404   size = bitsize / 8;
9405   orig_address = XEXP (operands[0], 0);
9406   shift_reg = gen_reg_rtx (SImode);
9407   if (GET_CODE (x) == CONST_INT)
9408     {
9409       v = INTVAL (x);
9410       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
9411     }
9412   else
9413     {
9414       emit_insn (gen_movsi (shift_reg, operands[3]));
9415       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9416     }
9417   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
9418
9419   operands[0] = replace_equiv_address (operands[0], addr_target);
9420   emit_insn (gen_movqi (operands[0], qi_val));
9421
9422   while (size -= 1)
9423     {
9424       if (GET_CODE (x) == CONST_INT)
9425         qi_val
9426           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
9427       else
9428         {
9429           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
9430           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9431         }
9432       emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
9433       emit_insn (gen_movqi (operands[0], qi_val));
9434     }
9435
9436   DONE;
9437 }")
9438
9439 (define_insn "movua"
9440   [(set (match_operand:SI 0 "register_operand" "=z")
9441         (sign_extract:SI (match_operand:SI 1 "unaligned_load_operand" "Sua>")
9442                          (const_int 32) (const_int 0)))]
9443   "TARGET_SH4A_ARCH"
9444   "movua.l      %1,%0"
9445   [(set_attr "type" "movua")])
9446
9447 ;; We shouldn't need this, but cse replaces increments with references
9448 ;; to other regs before flow has a chance to create post_inc
9449 ;; addressing modes, and only postreload's cse_move2add brings the
9450 ;; increments back to a usable form.
9451 (define_peephole2
9452   [(set (match_operand:SI 0 "register_operand" "")
9453         (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
9454                          (const_int 32) (const_int 0)))
9455    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9456   "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
9457   [(set (match_operand:SI 0 "register_operand" "")
9458         (sign_extract:SI (mem:SI (post_inc:SI
9459                                   (match_operand:SI 1 "register_operand" "")))
9460                          (const_int 32) (const_int 0)))]
9461   "")
9462
9463 (define_expand "extv"
9464   [(set (match_operand:SI 0 "register_operand" "")
9465         (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
9466                          (match_operand 2 "const_int_operand" "")
9467                          (match_operand 3 "const_int_operand" "")))]
9468   "TARGET_SH4A_ARCH"
9469 {
9470   if (TARGET_SH4A_ARCH
9471       && INTVAL (operands[2]) == 32
9472       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
9473       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
9474     {
9475       emit_insn (gen_movua (operands[0],
9476                             adjust_address (operands[1], SImode, 0)));
9477       DONE;
9478     }
9479
9480   FAIL;
9481 })
9482
9483 (define_expand "extzv"
9484   [(set (match_operand:SI 0 "register_operand" "")
9485         (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
9486                          (match_operand 2 "const_int_operand" "")
9487                          (match_operand 3 "const_int_operand" "")))]
9488   "TARGET_SH4A_ARCH"
9489 {
9490   if (TARGET_SH4A_ARCH
9491       && INTVAL (operands[2]) == 32
9492       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
9493       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
9494     {
9495       emit_insn (gen_movua (operands[0],
9496                             adjust_address (operands[1], SImode, 0)));
9497       DONE;
9498     }
9499
9500   FAIL;
9501 })
9502
9503 \f
9504 ;; -------------------------------------------------------------------------
9505 ;; Peepholes
9506 ;; -------------------------------------------------------------------------
9507
9508 ;; This matches cases where a stack pointer increment at the start of the
9509 ;; epilogue combines with a stack slot read loading the return value.
9510
9511 (define_peephole
9512   [(set (match_operand:SI 0 "arith_reg_operand" "")
9513         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
9514    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9515   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
9516   "mov.l        @%1+,%0")
9517
9518 ;; See the comment on the dt combiner pattern above.
9519
9520 (define_peephole
9521   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9522         (plus:SI (match_dup 0)
9523                  (const_int -1)))
9524    (set (reg:SI T_REG)
9525         (eq:SI (match_dup 0)
9526                (const_int 0)))]
9527   "TARGET_SH2"
9528   "dt   %0")
9529
9530 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
9531 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
9532 ;; reload when the constant is too large for a reg+offset address.
9533
9534 ;; ??? We would get much better code if this was done in reload.  This would
9535 ;; require modifying find_reloads_address to recognize that if the constant
9536 ;; is out-of-range for an immediate add, then we get better code by reloading
9537 ;; the constant into a register than by reloading the sum into a register,
9538 ;; since the former is one instruction shorter if the address does not need
9539 ;; to be offsettable.  Unfortunately this does not work, because there is
9540 ;; only one register, r0, that can be used as an index register.  This register
9541 ;; is also the function return value register.  So, if we try to force reload
9542 ;; to use double-reg addresses, then we end up with some instructions that
9543 ;; need to use r0 twice.  The only way to fix this is to change the calling
9544 ;; convention so that r0 is not used to return values.
9545
9546 (define_peephole
9547   [(set (match_operand:SI 0 "register_operand" "=r")
9548         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9549    (set (mem:SI (match_dup 0))
9550         (match_operand:SI 2 "general_movsrc_operand" ""))]
9551   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9552   "mov.l        %2,@(%0,%1)")
9553
9554 (define_peephole
9555   [(set (match_operand:SI 0 "register_operand" "=r")
9556         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9557    (set (match_operand:SI 2 "general_movdst_operand" "")
9558         (mem:SI (match_dup 0)))]
9559   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9560   "mov.l        @(%0,%1),%2")
9561
9562 (define_peephole
9563   [(set (match_operand:SI 0 "register_operand" "=r")
9564         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9565    (set (mem:HI (match_dup 0))
9566         (match_operand:HI 2 "general_movsrc_operand" ""))]
9567   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9568   "mov.w        %2,@(%0,%1)")
9569
9570 (define_peephole
9571   [(set (match_operand:SI 0 "register_operand" "=r")
9572         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9573    (set (match_operand:HI 2 "general_movdst_operand" "")
9574         (mem:HI (match_dup 0)))]
9575   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9576   "mov.w        @(%0,%1),%2")
9577
9578 (define_peephole
9579   [(set (match_operand:SI 0 "register_operand" "=r")
9580         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9581    (set (mem:QI (match_dup 0))
9582         (match_operand:QI 2 "general_movsrc_operand" ""))]
9583   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9584   "mov.b        %2,@(%0,%1)")
9585
9586 (define_peephole
9587   [(set (match_operand:SI 0 "register_operand" "=r")
9588         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9589    (set (match_operand:QI 2 "general_movdst_operand" "")
9590         (mem:QI (match_dup 0)))]
9591   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9592   "mov.b        @(%0,%1),%2")
9593
9594 (define_peephole
9595   [(set (match_operand:SI 0 "register_operand" "=r")
9596         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9597    (set (mem:SF (match_dup 0))
9598         (match_operand:SF 2 "general_movsrc_operand" ""))]
9599   "TARGET_SH1 && REGNO (operands[0]) == 0
9600    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9601        || (GET_CODE (operands[2]) == SUBREG
9602            && REGNO (SUBREG_REG (operands[2])) < 16))
9603    && reg_unused_after (operands[0], insn)"
9604   "mov.l        %2,@(%0,%1)")
9605
9606 (define_peephole
9607   [(set (match_operand:SI 0 "register_operand" "=r")
9608         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9609    (set (match_operand:SF 2 "general_movdst_operand" "")
9610
9611         (mem:SF (match_dup 0)))]
9612   "TARGET_SH1 && REGNO (operands[0]) == 0
9613    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9614        || (GET_CODE (operands[2]) == SUBREG
9615            && REGNO (SUBREG_REG (operands[2])) < 16))
9616    && reg_unused_after (operands[0], insn)"
9617   "mov.l        @(%0,%1),%2")
9618
9619 (define_peephole
9620   [(set (match_operand:SI 0 "register_operand" "=r")
9621         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9622    (set (mem:SF (match_dup 0))
9623         (match_operand:SF 2 "general_movsrc_operand" ""))]
9624   "TARGET_SH2E && REGNO (operands[0]) == 0
9625    && ((GET_CODE (operands[2]) == REG
9626         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9627        || (GET_CODE (operands[2]) == SUBREG
9628            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9629    && reg_unused_after (operands[0], insn)"
9630   "fmov{.s|}    %2,@(%0,%1)")
9631
9632 (define_peephole
9633   [(set (match_operand:SI 0 "register_operand" "=r")
9634         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9635    (set (match_operand:SF 2 "general_movdst_operand" "")
9636
9637         (mem:SF (match_dup 0)))]
9638   "TARGET_SH2E && REGNO (operands[0]) == 0
9639    && ((GET_CODE (operands[2]) == REG
9640         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9641        || (GET_CODE (operands[2]) == SUBREG
9642            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9643    && reg_unused_after (operands[0], insn)"
9644   "fmov{.s|}    @(%0,%1),%2")
9645
9646 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
9647 (define_insn "sp_switch_1"
9648   [(const_int 1)]
9649   "TARGET_SH1"
9650   "*
9651 {
9652   rtx xoperands[1];
9653
9654   xoperands[0] = sp_switch;
9655   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9656   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9657   return \"mov r0,r15\";
9658 }"
9659   [(set_attr "length" "10")])
9660
9661 ;; Switch back to the original stack for interrupt functions with the
9662 ;; sp_switch attribute.  */
9663 (define_insn "sp_switch_2"
9664   [(const_int 2)]
9665   "TARGET_SH1"
9666   "mov.l @r15+,r15\;mov.l @r15+,r0"
9667   [(set_attr "length" "4")])
9668
9669 ;; Integer vector moves
9670
9671 (define_expand "movv8qi"
9672   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9673         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9674   "TARGET_SHMEDIA"
9675   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9676
9677 (define_insn "movv8qi_i"
9678   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
9679         (match_operand:V8QI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9680   "TARGET_SHMEDIA
9681    && (register_operand (operands[0], V8QImode)
9682        || sh_register_operand (operands[1], V8QImode))"
9683   "@
9684         add     %1, r63, %0
9685         movi    %1, %0
9686         #
9687         ld%M1.q %m1, %0
9688         st%M0.q %m0, %N1"
9689   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9690    (set_attr "length" "4,4,16,4,4")])
9691
9692 (define_split
9693   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9694         (subreg:V8QI (const_int 0) 0))]
9695   "TARGET_SHMEDIA"
9696   [(set (match_dup 0)
9697         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9698                             (const_int 0) (const_int 0) (const_int 0)
9699                             (const_int 0) (const_int 0)]))])
9700
9701 (define_split
9702   [(set (match_operand 0 "arith_reg_dest" "")
9703         (match_operand 1 "sh_rep_vec" ""))]
9704   "TARGET_SHMEDIA && reload_completed
9705    && GET_MODE (operands[0]) == GET_MODE (operands[1])
9706    && sh_vector_mode_supported_p (GET_MODE (operands[0]))
9707    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9708    && (XVECEXP (operands[1], 0, 0) != const0_rtx
9709        || XVECEXP (operands[1], 0, 1) != const0_rtx)
9710    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
9711        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
9712   [(set (match_dup 0) (match_dup 1))
9713    (match_dup 2)]
9714   "
9715 {
9716   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9717   rtx elt1 = XVECEXP (operands[1], 0, 1);
9718
9719   if (unit_size > 2)
9720     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9721   else
9722     {
9723       if (unit_size < 2)
9724         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
9725       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9726     }
9727   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9728   operands[1] = XVECEXP (operands[1], 0, 0);
9729   if (unit_size < 2)
9730     {
9731       if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
9732         operands[1]
9733           = GEN_INT (TARGET_LITTLE_ENDIAN
9734                      ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
9735                      : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
9736       else
9737         {
9738           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9739           operands[1]
9740             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9741         }
9742     }
9743 }")
9744
9745 (define_split
9746   [(set (match_operand 0 "arith_reg_dest" "")
9747         (match_operand 1 "sh_const_vec" ""))]
9748   "TARGET_SHMEDIA && reload_completed
9749    && GET_MODE (operands[0]) == GET_MODE (operands[1])
9750    && sh_vector_mode_supported_p (GET_MODE (operands[0]))
9751    && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
9752   [(set (match_dup 0) (match_dup 1))]
9753   "
9754 {
9755   rtx v = operands[1];
9756   enum machine_mode new_mode
9757     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9758
9759   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9760   operands[1]
9761     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
9762 }")
9763
9764 (define_expand "movv2hi"
9765   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9766         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9767   "TARGET_SHMEDIA"
9768   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9769
9770 (define_insn "movv2hi_i"
9771   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9772         (match_operand:V2HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9773   "TARGET_SHMEDIA
9774    && (register_operand (operands[0], V2HImode)
9775        || sh_register_operand (operands[1], V2HImode))"
9776   "@
9777         addz.l  %1, r63, %0
9778         movi    %1, %0
9779         #
9780         ld%M1.l %m1, %0
9781         st%M0.l %m0, %N1"
9782   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9783    (set_attr "length" "4,4,16,4,4")])
9784
9785 (define_expand "movv4hi"
9786   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9787         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9788   "TARGET_SHMEDIA"
9789   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9790
9791 (define_insn "movv4hi_i"
9792   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9793         (match_operand:V4HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9794   "TARGET_SHMEDIA
9795    && (register_operand (operands[0], V4HImode)
9796        || sh_register_operand (operands[1], V4HImode))"
9797   "@
9798         add     %1, r63, %0
9799         movi    %1, %0
9800         #
9801         ld%M1.q %m1, %0
9802         st%M0.q %m0, %N1"
9803   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9804    (set_attr "length" "4,4,16,4,4")])
9805
9806 (define_expand "movv2si"
9807   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9808         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9809   "TARGET_SHMEDIA"
9810   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9811
9812 (define_insn "movv2si_i"
9813   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
9814         (match_operand:V2SI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9815   "TARGET_SHMEDIA
9816    && (register_operand (operands[0], V2SImode)
9817        || sh_register_operand (operands[1], V2SImode))"
9818   "@
9819         add     %1, r63, %0
9820         #
9821         #
9822         ld%M1.q %m1, %0
9823         st%M0.q %m0, %N1"
9824   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9825    (set_attr "length" "4,4,16,4,4")])
9826
9827 ;; Multimedia Intrinsics
9828
9829 (define_insn "absv2si2"
9830   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9831         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9832   "TARGET_SHMEDIA"
9833   "mabs.l       %1, %0"
9834   [(set_attr "type" "mcmp_media")])
9835
9836 (define_insn "absv4hi2"
9837   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9838         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9839   "TARGET_SHMEDIA"
9840   "mabs.w       %1, %0"
9841   [(set_attr "type" "mcmp_media")])
9842
9843 (define_insn "addv2si3"
9844   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9845         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9846                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9847   "TARGET_SHMEDIA"
9848   "madd.l       %1, %2, %0"
9849   [(set_attr "type" "arith_media")])
9850
9851 (define_insn "addv4hi3"
9852   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9853         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9854                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9855   "TARGET_SHMEDIA"
9856   "madd.w       %1, %2, %0"
9857   [(set_attr "type" "arith_media")])
9858
9859 (define_insn "ssaddv2si3"
9860   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9861         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9862                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9863   "TARGET_SHMEDIA"
9864   "madds.l      %1, %2, %0"
9865   [(set_attr "type" "mcmp_media")])
9866
9867 (define_insn "usaddv8qi3"
9868   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9869         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9870                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9871   "TARGET_SHMEDIA"
9872   "madds.ub     %1, %2, %0"
9873   [(set_attr "type" "mcmp_media")])
9874
9875 (define_insn "ssaddv4hi3"
9876   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9877         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9878                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9879   "TARGET_SHMEDIA"
9880   "madds.w      %1, %2, %0"
9881   [(set_attr "type" "mcmp_media")])
9882
9883 (define_insn "negcmpeqv8qi"
9884   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9885         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9886                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9887   "TARGET_SHMEDIA"
9888   "mcmpeq.b     %N1, %N2, %0"
9889   [(set_attr "type" "mcmp_media")])
9890
9891 (define_insn "negcmpeqv2si"
9892   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9893         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9894                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9895   "TARGET_SHMEDIA"
9896   "mcmpeq.l     %N1, %N2, %0"
9897   [(set_attr "type" "mcmp_media")])
9898
9899 (define_insn "negcmpeqv4hi"
9900   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9901         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9902                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9903   "TARGET_SHMEDIA"
9904   "mcmpeq.w     %N1, %N2, %0"
9905   [(set_attr "type" "mcmp_media")])
9906
9907 (define_insn "negcmpgtuv8qi"
9908   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9909         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9910                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9911   "TARGET_SHMEDIA"
9912   "mcmpgt.ub    %N1, %N2, %0"
9913   [(set_attr "type" "mcmp_media")])
9914
9915 (define_insn "negcmpgtv2si"
9916   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9917         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9918                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9919   "TARGET_SHMEDIA"
9920   "mcmpgt.l     %N1, %N2, %0"
9921   [(set_attr "type" "mcmp_media")])
9922
9923 (define_insn "negcmpgtv4hi"
9924   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9925         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9926                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9927   "TARGET_SHMEDIA"
9928   "mcmpgt.w     %N1, %N2, %0"
9929   [(set_attr "type" "mcmp_media")])
9930
9931 (define_insn "mcmv"
9932   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9933         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9934                         (match_operand:DI 2 "arith_reg_operand" "r"))
9935                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9936                         (not:DI (match_dup 2)))))]
9937   "TARGET_SHMEDIA"
9938   "mcmv %N1, %2, %0"
9939   [(set_attr "type" "arith_media")])
9940
9941 (define_insn "mcnvs_lw"
9942   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9943         (vec_concat:V4HI
9944          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
9945          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9946   "TARGET_SHMEDIA"
9947   "mcnvs.lw     %N1, %N2, %0"
9948   [(set_attr "type" "mcmp_media")])
9949
9950 (define_insn "mcnvs_wb"
9951   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9952         (vec_concat:V8QI
9953          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9954          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9955   "TARGET_SHMEDIA"
9956   "mcnvs.wb     %N1, %N2, %0"
9957   [(set_attr "type" "mcmp_media")])
9958
9959 (define_insn "mcnvs_wub"
9960   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9961         (vec_concat:V8QI
9962          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9963          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9964   "TARGET_SHMEDIA"
9965   "mcnvs.wub    %N1, %N2, %0"
9966   [(set_attr "type" "mcmp_media")])
9967
9968 (define_insn "mextr_rl"
9969   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9970         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9971                              (match_operand:HI 3 "mextr_bit_offset" "i"))
9972                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9973                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9974   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9975   "*
9976 {
9977   static char templ[16];
9978
9979   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9980            (int) INTVAL (operands[3]) >> 3);
9981   return templ;
9982 }"
9983   [(set_attr "type" "arith_media")])
9984
9985 (define_insn "*mextr_lr"
9986   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9987         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9988                            (match_operand:HI 3 "mextr_bit_offset" "i"))
9989                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9990                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9991   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9992   "*
9993 {
9994   static char templ[16];
9995
9996   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9997            (int) INTVAL (operands[4]) >> 3);
9998   return templ;
9999 }"
10000   [(set_attr "type" "arith_media")])
10001
10002 ; mextrN can be modelled with vec_select / vec_concat, but the selection
10003 ; vector then varies depending on endianness.
10004 (define_expand "mextr1"
10005   [(match_operand:DI 0 "arith_reg_dest" "")
10006    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10007    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10008   "TARGET_SHMEDIA"
10009   "
10010 {
10011   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10012                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
10013   DONE;
10014 }")
10015
10016 (define_expand "mextr2"
10017   [(match_operand:DI 0 "arith_reg_dest" "")
10018    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10019    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10020   "TARGET_SHMEDIA"
10021   "
10022 {
10023   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10024                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
10025   DONE;
10026 }")
10027
10028 (define_expand "mextr3"
10029   [(match_operand:DI 0 "arith_reg_dest" "")
10030    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10031    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10032   "TARGET_SHMEDIA"
10033   "
10034 {
10035   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10036                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
10037   DONE;
10038 }")
10039
10040 (define_expand "mextr4"
10041   [(match_operand:DI 0 "arith_reg_dest" "")
10042    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10043    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10044   "TARGET_SHMEDIA"
10045   "
10046 {
10047   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10048                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
10049   DONE;
10050 }")
10051
10052 (define_expand "mextr5"
10053   [(match_operand:DI 0 "arith_reg_dest" "")
10054    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10055    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10056   "TARGET_SHMEDIA"
10057   "
10058 {
10059   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10060                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
10061   DONE;
10062 }")
10063
10064 (define_expand "mextr6"
10065   [(match_operand:DI 0 "arith_reg_dest" "")
10066    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10067    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10068   "TARGET_SHMEDIA"
10069   "
10070 {
10071   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10072                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
10073   DONE;
10074 }")
10075
10076 (define_expand "mextr7"
10077   [(match_operand:DI 0 "arith_reg_dest" "")
10078    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10079    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10080   "TARGET_SHMEDIA"
10081   "
10082 {
10083   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10084                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
10085   DONE;
10086 }")
10087
10088 (define_expand "mmacfx_wl"
10089   [(match_operand:V2SI 0 "arith_reg_dest" "")
10090    (match_operand:V2HI 1 "extend_reg_operand" "")
10091    (match_operand:V2HI 2 "extend_reg_operand" "")
10092    (match_operand:V2SI 3 "arith_reg_operand" "")]
10093   "TARGET_SHMEDIA"
10094   "
10095 {
10096   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
10097                               operands[1], operands[2]));
10098   DONE;
10099 }")
10100
10101 (define_insn "mmacfx_wl_i"
10102   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10103         (ss_plus:V2SI
10104          (match_operand:V2SI 1 "arith_reg_operand" "0")
10105          (ss_truncate:V2SI
10106           (ashift:V2DI
10107            (sign_extend:V2DI
10108             (mult:V2SI
10109              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
10110              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
10111            (const_int 1)))))]
10112   "TARGET_SHMEDIA"
10113   "mmacfx.wl    %2, %3, %0"
10114   [(set_attr "type" "mac_media")])
10115
10116 (define_expand "mmacnfx_wl"
10117   [(match_operand:V2SI 0 "arith_reg_dest" "")
10118    (match_operand:V2HI 1 "extend_reg_operand" "")
10119    (match_operand:V2HI 2 "extend_reg_operand" "")
10120    (match_operand:V2SI 3 "arith_reg_operand" "")]
10121   "TARGET_SHMEDIA"
10122   "
10123 {
10124   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
10125                                operands[1], operands[2]));
10126   DONE;
10127 }")
10128
10129 (define_insn "mmacnfx_wl_i"
10130   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10131         (ss_minus:V2SI
10132          (match_operand:V2SI 1 "arith_reg_operand" "0")
10133          (ss_truncate:V2SI
10134           (ashift:V2DI
10135            (sign_extend:V2DI
10136             (mult:V2SI
10137              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
10138              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
10139            (const_int 1)))))]
10140   "TARGET_SHMEDIA"
10141   "mmacnfx.wl   %2, %3, %0"
10142   [(set_attr "type" "mac_media")])
10143
10144 (define_insn "mulv2si3"
10145   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10146         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10147                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10148   "TARGET_SHMEDIA"
10149   "mmul.l       %1, %2, %0"
10150   [(set_attr "type" "d2mpy_media")])
10151
10152 (define_insn "mulv4hi3"
10153   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10154         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10155                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10156   "TARGET_SHMEDIA"
10157   "mmul.w       %1, %2, %0"
10158   [(set_attr "type" "dmpy_media")])
10159
10160 (define_insn "mmulfx_l"
10161   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10162         (ss_truncate:V2SI
10163          (ashiftrt:V2DI
10164           (mult:V2DI
10165            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
10166            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
10167           (const_int 31))))]
10168   "TARGET_SHMEDIA"
10169   "mmulfx.l     %1, %2, %0"
10170   [(set_attr "type" "d2mpy_media")])
10171
10172 (define_insn "mmulfx_w"
10173   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10174         (ss_truncate:V4HI
10175          (ashiftrt:V4SI
10176           (mult:V4SI
10177            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10178            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10179           (const_int 15))))]
10180   "TARGET_SHMEDIA"
10181   "mmulfx.w     %1, %2, %0"
10182   [(set_attr "type" "dmpy_media")])
10183
10184 (define_insn "mmulfxrp_w"
10185   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10186         (ss_truncate:V4HI
10187          (ashiftrt:V4SI
10188           (plus:V4SI
10189            (mult:V4SI
10190             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10191             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10192            (const_int 16384))
10193           (const_int 15))))]
10194   "TARGET_SHMEDIA"
10195   "mmulfxrp.w   %1, %2, %0"
10196   [(set_attr "type" "dmpy_media")])
10197
10198 (define_expand "mmulhi_wl"
10199   [(match_operand:V2SI 0 "arith_reg_dest" "")
10200    (match_operand:V4HI 1 "arith_reg_operand" "")
10201    (match_operand:V4HI 2 "arith_reg_operand" "")]
10202   "TARGET_SHMEDIA"
10203   "
10204 {
10205   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
10206              (operands[0], operands[1], operands[2]));
10207   DONE;
10208 }")
10209
10210 (define_expand "mmullo_wl"
10211   [(match_operand:V2SI 0 "arith_reg_dest" "")
10212    (match_operand:V4HI 1 "arith_reg_operand" "")
10213    (match_operand:V4HI 2 "arith_reg_operand" "")]
10214   "TARGET_SHMEDIA"
10215   "
10216 {
10217   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
10218              (operands[0], operands[1], operands[2]));
10219   DONE;
10220 }")
10221
10222 (define_insn "mmul23_wl"
10223   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10224         (vec_select:V2SI
10225          (mult:V4SI
10226           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10227           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10228          (parallel [(const_int 2) (const_int 3)])))]
10229   "TARGET_SHMEDIA"
10230   "* return (TARGET_LITTLE_ENDIAN
10231              ? \"mmulhi.wl      %1, %2, %0\"
10232              : \"mmullo.wl      %1, %2, %0\");"
10233   [(set_attr "type" "dmpy_media")])
10234
10235 (define_insn "mmul01_wl"
10236   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10237         (vec_select:V2SI
10238          (mult:V4SI
10239           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10240           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10241          (parallel [(const_int 0) (const_int 1)])))]
10242   "TARGET_SHMEDIA"
10243   "* return (TARGET_LITTLE_ENDIAN
10244              ? \"mmullo.wl      %1, %2, %0\"
10245              : \"mmulhi.wl      %1, %2, %0\");"
10246   [(set_attr "type" "dmpy_media")])
10247
10248 (define_expand "mmulsum_wq"
10249   [(match_operand:DI 0 "arith_reg_dest" "")
10250    (match_operand:V4HI 1 "arith_reg_operand" "")
10251    (match_operand:V4HI 2 "arith_reg_operand" "")
10252    (match_operand:DI 3 "arith_reg_operand" "")]
10253   "TARGET_SHMEDIA"
10254   "
10255 {
10256   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
10257                                operands[1], operands[2]));
10258   DONE;
10259 }")
10260
10261 (define_insn "mmulsum_wq_i"
10262   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10263         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
10264          (plus:DI
10265           (plus:DI
10266            (vec_select:DI
10267             (mult:V4DI
10268              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
10269              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
10270             (parallel [(const_int 0)]))
10271            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10272                                      (sign_extend:V4DI (match_dup 3)))
10273                           (parallel [(const_int 1)])))
10274           (plus:DI
10275            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10276                                      (sign_extend:V4DI (match_dup 3)))
10277                           (parallel [(const_int 2)]))
10278            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10279                                      (sign_extend:V4DI (match_dup 3)))
10280                           (parallel [(const_int 3)]))))))]
10281   "TARGET_SHMEDIA"
10282   "mmulsum.wq   %2, %3, %0"
10283   [(set_attr "type" "mac_media")])
10284
10285 (define_expand "mperm_w"
10286   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
10287    (match_operand:V4HI 1 "arith_reg_operand" "r")
10288    (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
10289   "TARGET_SHMEDIA"
10290   "
10291 {
10292   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
10293              (operands[0], operands[1], operands[2]));
10294   DONE;
10295 }")
10296
10297 ; This use of vec_select isn't exactly correct according to rtl.texi
10298 ; (because not constant), but it seems a straightforward extension.
10299 (define_insn "mperm_w_little"
10300   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10301         (vec_select:V4HI
10302          (match_operand:V4HI 1 "arith_reg_operand" "r")
10303          (parallel
10304           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
10305                             (const_int 2) (const_int 0))
10306            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
10307            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
10308            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
10309   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
10310   "mperm.w      %1, %N2, %0"
10311   [(set_attr "type" "arith_media")])
10312
10313 (define_insn "mperm_w_big"
10314   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10315         (vec_select:V4HI
10316          (match_operand:V4HI 1 "arith_reg_operand" "r")
10317          (parallel
10318           [(zero_extract:QI (not:QI (match_operand:QI 2
10319                                      "extend_reg_or_0_operand" "rZ"))
10320                             (const_int 2) (const_int 0))
10321            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
10322            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
10323            (zero_extract:QI (not:QI (match_dup 2))
10324                             (const_int 2) (const_int 6))])))]
10325   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
10326   "mperm.w      %1, %N2, %0"
10327   [(set_attr "type" "arith_media")])
10328
10329 (define_insn "mperm_w0"
10330   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10331         (vec_duplicate:V4HI (truncate:HI (match_operand 1
10332                                           "trunc_hi_operand" "r"))))]
10333   "TARGET_SHMEDIA"
10334   "mperm.w      %1, r63, %0"
10335   [(set_attr "type" "arith_media")])
10336
10337 (define_expand "msad_ubq"
10338   [(match_operand:DI 0 "arith_reg_dest" "")
10339    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
10340    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
10341    (match_operand:DI 3 "arith_reg_operand" "")]
10342   "TARGET_SHMEDIA"
10343   "
10344 {
10345   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
10346                              operands[1], operands[2]));
10347   DONE;
10348 }")
10349
10350 (define_insn "msad_ubq_i"
10351   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10352         (plus:DI
10353          (plus:DI
10354           (plus:DI
10355            (plus:DI
10356             (match_operand:DI 1 "arith_reg_operand" "0")
10357             (abs:DI (vec_select:DI
10358                      (minus:V8DI
10359                       (zero_extend:V8DI
10360                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10361                       (zero_extend:V8DI
10362                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
10363                      (parallel [(const_int 0)]))))
10364            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10365                                               (zero_extend:V8DI (match_dup 3)))
10366                                   (parallel [(const_int 1)]))))
10367           (plus:DI
10368            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10369                                               (zero_extend:V8DI (match_dup 3)))
10370                                   (parallel [(const_int 2)])))
10371            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10372                                               (zero_extend:V8DI (match_dup 3)))
10373                                   (parallel [(const_int 3)])))))
10374          (plus:DI
10375           (plus:DI
10376            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10377                                               (zero_extend:V8DI (match_dup 3)))
10378                                   (parallel [(const_int 4)])))
10379            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10380                                               (zero_extend:V8DI (match_dup 3)))
10381                                   (parallel [(const_int 5)]))))
10382           (plus:DI
10383            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10384                                               (zero_extend:V8DI (match_dup 3)))
10385                                   (parallel [(const_int 6)])))
10386            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10387                                               (zero_extend:V8DI (match_dup 3)))
10388                                   (parallel [(const_int 7)])))))))]
10389   "TARGET_SHMEDIA"
10390   "msad.ubq     %N2, %N3, %0"
10391   [(set_attr "type" "mac_media")])
10392
10393 (define_insn "mshalds_l"
10394   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10395         (ss_truncate:V2SI
10396          (ashift:V2DI
10397           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
10398           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10399                   (const_int 31)))))]
10400   "TARGET_SHMEDIA"
10401   "mshalds.l    %1, %2, %0"
10402   [(set_attr "type" "mcmp_media")])
10403
10404 (define_insn "mshalds_w"
10405   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10406         (ss_truncate:V4HI
10407          (ashift:V4SI
10408           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10409           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10410                   (const_int 15)))))]
10411   "TARGET_SHMEDIA"
10412   "mshalds.w    %1, %2, %0"
10413   [(set_attr "type" "mcmp_media")])
10414
10415 (define_insn "ashrv2si3"
10416   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10417         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10418                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10419   "TARGET_SHMEDIA"
10420   "mshard.l     %1, %2, %0"
10421   [(set_attr "type" "arith_media")])
10422
10423 (define_insn "ashrv4hi3"
10424   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10425         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10426                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10427   "TARGET_SHMEDIA"
10428   "mshard.w     %1, %2, %0"
10429   [(set_attr "type" "arith_media")])
10430
10431 (define_insn "mshards_q"
10432   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
10433         (ss_truncate:HI
10434          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
10435                       (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
10436   "TARGET_SHMEDIA"
10437   "mshards.q    %1, %N2, %0"
10438   [(set_attr "type" "mcmp_media")])
10439
10440 (define_expand "mshfhi_b"
10441   [(match_operand:V8QI 0 "arith_reg_dest" "")
10442    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10443    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10444   "TARGET_SHMEDIA"
10445   "
10446 {
10447   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
10448              (operands[0], operands[1], operands[2]));
10449   DONE;
10450 }")
10451
10452 (define_expand "mshflo_b"
10453   [(match_operand:V8QI 0 "arith_reg_dest" "")
10454    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10455    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10456   "TARGET_SHMEDIA"
10457   "
10458 {
10459   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
10460              (operands[0], operands[1], operands[2]));
10461   DONE;
10462 }")
10463
10464 (define_insn "mshf4_b"
10465   [(set
10466     (match_operand:V8QI 0 "arith_reg_dest" "=r")
10467     (vec_select:V8QI
10468      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10469                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10470      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
10471                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
10472   "TARGET_SHMEDIA"
10473   "* return (TARGET_LITTLE_ENDIAN
10474              ? \"mshfhi.b       %N1, %N2, %0\"
10475              : \"mshflo.b       %N1, %N2, %0\");"
10476   [(set_attr "type" "arith_media")])
10477
10478 (define_insn "mshf0_b"
10479   [(set
10480     (match_operand:V8QI 0 "arith_reg_dest" "=r")
10481     (vec_select:V8QI
10482      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10483                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10484      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
10485                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
10486   "TARGET_SHMEDIA"
10487   "* return (TARGET_LITTLE_ENDIAN
10488              ? \"mshflo.b       %N1, %N2, %0\"
10489              : \"mshfhi.b       %N1, %N2, %0\");"
10490   [(set_attr "type" "arith_media")])
10491
10492 (define_expand "mshfhi_l"
10493   [(match_operand:V2SI 0 "arith_reg_dest" "")
10494    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10495    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10496   "TARGET_SHMEDIA"
10497   "
10498 {
10499   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
10500              (operands[0], operands[1], operands[2]));
10501   DONE;
10502 }")
10503
10504 (define_expand "mshflo_l"
10505   [(match_operand:V2SI 0 "arith_reg_dest" "")
10506    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10507    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10508   "TARGET_SHMEDIA"
10509   "
10510 {
10511   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
10512              (operands[0], operands[1], operands[2]));
10513   DONE;
10514 }")
10515
10516 (define_insn "mshf4_l"
10517   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10518         (vec_select:V2SI
10519          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10520                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10521          (parallel [(const_int 1) (const_int 3)])))]
10522   "TARGET_SHMEDIA"
10523   "* return (TARGET_LITTLE_ENDIAN
10524              ? \"mshfhi.l       %N1, %N2, %0\"
10525              : \"mshflo.l       %N1, %N2, %0\");"
10526   [(set_attr "type" "arith_media")])
10527
10528 (define_insn "mshf0_l"
10529   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10530         (vec_select:V2SI
10531          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10532                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10533          (parallel [(const_int 0) (const_int 2)])))]
10534   "TARGET_SHMEDIA"
10535   "* return (TARGET_LITTLE_ENDIAN
10536              ? \"mshflo.l       %N1, %N2, %0\"
10537              : \"mshfhi.l       %N1, %N2, %0\");"
10538   [(set_attr "type" "arith_media")])
10539
10540 (define_expand "mshfhi_w"
10541   [(match_operand:V4HI 0 "arith_reg_dest" "")
10542    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10543    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10544   "TARGET_SHMEDIA"
10545   "
10546 {
10547   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
10548              (operands[0], operands[1], operands[2]));
10549   DONE;
10550 }")
10551
10552 (define_expand "mshflo_w"
10553   [(match_operand:V4HI 0 "arith_reg_dest" "")
10554    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10555    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10556   "TARGET_SHMEDIA"
10557   "
10558 {
10559   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
10560              (operands[0], operands[1], operands[2]));
10561   DONE;
10562 }")
10563
10564 (define_insn "mshf4_w"
10565   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10566         (vec_select:V4HI
10567          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10568                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10569          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
10570   "TARGET_SHMEDIA"
10571   "* return (TARGET_LITTLE_ENDIAN
10572              ? \"mshfhi.w       %N1, %N2, %0\"
10573              : \"mshflo.w       %N1, %N2, %0\");"
10574   [(set_attr "type" "arith_media")])
10575
10576 (define_insn "mshf0_w"
10577   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10578         (vec_select:V4HI
10579          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10580                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10581          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
10582   "TARGET_SHMEDIA"
10583   "* return (TARGET_LITTLE_ENDIAN
10584              ? \"mshflo.w       %N1, %N2, %0\"
10585              : \"mshfhi.w       %N1, %N2, %0\");"
10586   [(set_attr "type" "arith_media")])
10587
10588 (define_insn "mshflo_w_x"
10589   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10590         (vec_select:V4HI
10591          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
10592                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
10593          (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
10594   "TARGET_SHMEDIA"
10595   "mshflo.w     %N1, %N2, %0"
10596   [(set_attr "type" "arith_media")])
10597
10598 /* These are useful to expand ANDs and as combiner patterns.  */
10599 (define_insn_and_split "mshfhi_l_di"
10600   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
10601         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
10602                              (const_int 32))
10603                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
10604                         (const_int -4294967296))))]
10605   "TARGET_SHMEDIA"
10606   "@
10607         mshfhi.l        %N1, %N2, %0
10608         #"
10609   "TARGET_SHMEDIA && reload_completed
10610    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10611   [(set (match_dup 3) (match_dup 4))
10612    (set (match_dup 5) (match_dup 6))]
10613   "
10614 {
10615   operands[3] = gen_lowpart (SImode, operands[0]);
10616   operands[4] = gen_highpart (SImode, operands[1]);
10617   operands[5] = gen_highpart (SImode, operands[0]);
10618   operands[6] = gen_highpart (SImode, operands[2]);
10619 }"
10620   [(set_attr "type" "arith_media")])
10621
10622 (define_insn "*mshfhi_l_di_rev"
10623   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10624         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10625                         (const_int -4294967296))
10626                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10627                              (const_int 32))))]
10628   "TARGET_SHMEDIA"
10629   "mshfhi.l     %N2, %N1, %0"
10630   [(set_attr "type" "arith_media")])
10631
10632 (define_split
10633   [(set (match_operand:DI 0 "arith_reg_dest" "")
10634         (ior:DI (zero_extend:DI (match_operand:SI 1
10635                                               "extend_reg_or_0_operand" ""))
10636                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10637                         (const_int -4294967296))))
10638    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10639   "TARGET_SHMEDIA"
10640   [(const_int 0)]
10641   "
10642 {
10643   emit_insn (gen_ashldi3_media (operands[3],
10644                                 simplify_gen_subreg (DImode, operands[1],
10645                                                      SImode, 0),
10646                                 GEN_INT (32)));
10647   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10648   DONE;
10649 }")
10650
10651 (define_insn "mshflo_l_di"
10652   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10653         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10654                         (const_int 4294967295))
10655                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10656                            (const_int 32))))]
10657
10658   "TARGET_SHMEDIA"
10659   "mshflo.l     %N1, %N2, %0"
10660   [(set_attr "type" "arith_media")])
10661
10662 (define_insn "*mshflo_l_di_rev"
10663   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10664         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10665                            (const_int 32))
10666                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10667                         (const_int 4294967295))))]
10668
10669   "TARGET_SHMEDIA"
10670   "mshflo.l     %N2, %N1, %0"
10671   [(set_attr "type" "arith_media")])
10672
10673 ;; Combiner pattern for trampoline initialization.
10674 (define_insn_and_split "*double_shori"
10675   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10676         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10677                            (const_int 32))
10678                 (match_operand:DI 2 "const_int_operand" "n")))]
10679   "TARGET_SHMEDIA
10680    && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10681   "#"
10682   "rtx_equal_p (operands[0], operands[1])"
10683   [(const_int 0)]
10684   "
10685 {
10686   HOST_WIDE_INT v = INTVAL (operands[2]);
10687
10688   emit_insn (gen_shori_media (operands[0], operands[0],
10689              gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10690   emit_insn (gen_shori_media (operands[0], operands[0],
10691                               gen_int_mode (v, HImode)));
10692   DONE;
10693 }")
10694
10695
10696 (define_insn "*mshflo_l_di_x"
10697   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10698         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
10699                                  "rZ"))
10700                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10701                            (const_int 32))))]
10702
10703   "TARGET_SHMEDIA"
10704   "mshflo.l     %N1, %N2, %0"
10705   [(set_attr "type" "arith_media")])
10706
10707 (define_insn_and_split "concat_v2sf"
10708   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
10709 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
10710         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
10711                          (match_operand:SF 2 "register_operand" "rZ,f,f")))]
10712
10713   "TARGET_SHMEDIA"
10714   "@
10715         mshflo.l        %N1, %N2, %0
10716         #
10717         #"
10718   "TARGET_SHMEDIA && reload_completed
10719    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10720   [(set (match_dup 3) (match_dup 1))
10721    (set (match_dup 4) (match_dup 2))]
10722   "
10723 {
10724   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10725   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10726 }"
10727   [(set_attr "type" "arith_media")])
10728
10729 (define_insn "*mshflo_l_di_x_rev"
10730   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10731         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10732                            (const_int 32))
10733                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
10734
10735   "TARGET_SHMEDIA"
10736   "mshflo.l     %N2, %N1, %0"
10737   [(set_attr "type" "arith_media")])
10738
10739 (define_insn "ashlv2si3"
10740   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10741         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10742                      (match_operand:DI 2 "arith_reg_operand" "r")))]
10743   "TARGET_SHMEDIA"
10744   "mshlld.l     %1, %2, %0"
10745   [(set_attr "type" "arith_media")])
10746
10747 (define_insn "ashlv4hi3"
10748   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10749         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10750                      (match_operand:DI 2 "arith_reg_operand" "r")))]
10751   "TARGET_SHMEDIA"
10752   "mshlld.w     %1, %2, %0"
10753   [(set_attr "type" "arith_media")])
10754
10755 (define_insn "lshrv2si3"
10756   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10757         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10758                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10759   "TARGET_SHMEDIA"
10760   "mshlrd.l     %1, %2, %0"
10761   [(set_attr "type" "arith_media")])
10762
10763 (define_insn "lshrv4hi3"
10764   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10765         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10766                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10767   "TARGET_SHMEDIA"
10768   "mshlrd.w     %1, %2, %0"
10769   [(set_attr "type" "arith_media")])
10770
10771 (define_insn "subv2si3"
10772   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10773         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10774                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10775   "TARGET_SHMEDIA"
10776   "msub.l       %N1, %2, %0"
10777   [(set_attr "type" "arith_media")])
10778
10779 (define_insn "subv4hi3"
10780   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10781         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10782                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10783   "TARGET_SHMEDIA"
10784   "msub.w       %N1, %2, %0"
10785   [(set_attr "type" "arith_media")])
10786
10787 (define_insn "sssubv2si3"
10788   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10789         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10790                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10791   "TARGET_SHMEDIA"
10792   "msubs.l      %N1, %2, %0"
10793   [(set_attr "type" "mcmp_media")])
10794
10795 (define_insn "ussubv8qi3"
10796   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10797         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10798                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10799   "TARGET_SHMEDIA"
10800   "msubs.ub     %1, %2, %0"
10801   [(set_attr "type" "mcmp_media")])
10802
10803 (define_insn "sssubv4hi3"
10804   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10805         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10806                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10807   "TARGET_SHMEDIA"
10808   "msubs.w      %N1, %2, %0"
10809   [(set_attr "type" "mcmp_media")])
10810
10811 ;; Floating Point Intrinsics
10812
10813 (define_insn "fcosa_s"
10814   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10815         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10816                    UNSPEC_FCOSA))]
10817   "TARGET_SHMEDIA"
10818   "fcosa.s      %1, %0"
10819   [(set_attr "type" "atrans_media")])
10820
10821 (define_insn "fsina_s"
10822   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10823         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10824                    UNSPEC_FSINA))]
10825   "TARGET_SHMEDIA"
10826   "fsina.s      %1, %0"
10827   [(set_attr "type" "atrans_media")])
10828
10829 (define_insn "fipr"
10830   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10831         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10832                                                     "fp_arith_reg_operand" "f")
10833                                                    (match_operand:V4SF 2
10834                                                     "fp_arith_reg_operand" "f"))
10835                                          (parallel [(const_int 0)]))
10836                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10837                                          (parallel [(const_int 1)])))
10838                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10839                                          (parallel [(const_int 2)]))
10840                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10841                                          (parallel [(const_int 3)])))))]
10842   "TARGET_SHMEDIA"
10843   "fipr.s       %1, %2, %0"
10844   [(set_attr "type" "fparith_media")])
10845
10846 (define_insn "fsrra_s"
10847   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10848         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10849                    UNSPEC_FSRRA))]
10850   "TARGET_SHMEDIA"
10851   "fsrra.s      %1, %0"
10852   [(set_attr "type" "atrans_media")])
10853
10854 (define_insn "ftrv"
10855   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10856         (plus:V4SF
10857          (plus:V4SF
10858           (mult:V4SF
10859            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
10860                             (parallel [(const_int 0) (const_int 5)
10861                                        (const_int 10) (const_int 15)]))
10862            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10863           (mult:V4SF
10864            (vec_select:V4SF (match_dup 1)
10865                             (parallel [(const_int 4) (const_int 9)
10866                                        (const_int 14) (const_int 3)]))
10867            (vec_select:V4SF (match_dup 2)
10868                             (parallel [(const_int 1) (const_int 2)
10869                                        (const_int 3) (const_int 0)]))))
10870          (plus:V4SF
10871           (mult:V4SF
10872            (vec_select:V4SF (match_dup 1)
10873                             (parallel [(const_int 8) (const_int 13)
10874                                        (const_int 2) (const_int 7)]))
10875            (vec_select:V4SF (match_dup 2)
10876                             (parallel [(const_int 2) (const_int 3)
10877                                        (const_int 0) (const_int 1)])))
10878           (mult:V4SF
10879            (vec_select:V4SF (match_dup 1)
10880                             (parallel [(const_int 12) (const_int 1)
10881                                        (const_int 6) (const_int 11)]))
10882            (vec_select:V4SF (match_dup 2)
10883                             (parallel [(const_int 3) (const_int 0)
10884                                        (const_int 1) (const_int 2)]))))))]
10885   "TARGET_SHMEDIA"
10886   "ftrv.s %1, %2, %0"
10887   [(set_attr "type" "fparith_media")])
10888
10889 (define_insn "nsb"
10890   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10891         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10892                    UNSPEC_NSB))]
10893   "TARGET_SHMEDIA"
10894   "nsb  %1, %0"
10895   [(set_attr "type" "arith_media")])
10896
10897 (define_insn "nsbsi"
10898   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10899         (zero_extend:SI
10900          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10901                     UNSPEC_NSB)))]
10902   "TARGET_SHMEDIA"
10903   "nsb  %1, %0"
10904   [(set_attr "type" "arith_media")])
10905
10906 (define_insn "nsbdi"
10907   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10908         (zero_extend:DI
10909          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10910                     UNSPEC_NSB)))]
10911   "TARGET_SHMEDIA"
10912   "nsb  %1, %0"
10913   [(set_attr "type" "arith_media")])
10914
10915 (define_expand "ffsdi2"
10916   [(set (match_operand:DI 0 "arith_reg_dest" "")
10917         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10918   "TARGET_SHMEDIA"
10919   "
10920 {
10921   rtx scratch = gen_reg_rtx (DImode);
10922   rtx last;
10923
10924   emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
10925   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10926   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10927   emit_insn (gen_nsbdi (scratch, scratch));
10928   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10929   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10930   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10931   REG_NOTES (last)
10932     = gen_rtx_EXPR_LIST (REG_EQUAL,
10933                          gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10934   DONE;
10935 }")
10936
10937 (define_expand "ffssi2"
10938   [(set (match_operand:SI 0 "arith_reg_dest" "")
10939         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10940   "TARGET_SHMEDIA"
10941   "
10942 {
10943   rtx scratch = gen_reg_rtx (SImode);
10944   rtx discratch = gen_reg_rtx (DImode);
10945   rtx last;
10946
10947   emit_insn (gen_adddi3 (discratch,
10948                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
10949                          constm1_rtx));
10950   emit_insn (gen_andcdi3 (discratch,
10951                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
10952                           discratch));
10953   emit_insn (gen_nsbsi (scratch, discratch));
10954   last = emit_insn (gen_subsi3 (operands[0],
10955                                 force_reg (SImode, GEN_INT (63)), scratch));
10956   REG_NOTES (last)
10957     = gen_rtx_EXPR_LIST (REG_EQUAL,
10958                          gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10959   DONE;
10960 }")
10961
10962 (define_insn "byterev"
10963   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10964         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10965                          (parallel [(const_int 7) (const_int 6) (const_int 5)
10966                                     (const_int 4) (const_int 3) (const_int 2)
10967                                     (const_int 1) (const_int 0)])))]
10968   "TARGET_SHMEDIA"
10969   "byterev      %1, %0"
10970   [(set_attr "type" "arith_media")])
10971
10972 (define_insn "prefetch_media"
10973   [(prefetch (match_operand:QI 0 "address_operand" "p")
10974              (match_operand:SI 1 "const_int_operand" "n")
10975              (match_operand:SI 2 "const_int_operand" "n"))]
10976   "TARGET_SHMEDIA"
10977   "*
10978 {
10979   operands[0] = gen_rtx_MEM (QImode, operands[0]);
10980   output_asm_insn (\"ld%M0.b    %m0,r63\", operands);
10981   return \"\";
10982 }"
10983   [(set_attr "type" "other")])
10984
10985 (define_insn "prefetch_i4"
10986   [(prefetch (match_operand:SI 0 "register_operand" "r")
10987              (match_operand:SI 1 "const_int_operand" "n")
10988              (match_operand:SI 2 "const_int_operand" "n"))]
10989   "TARGET_HARD_SH4"
10990   "*
10991 {
10992   return \"pref @%0\";
10993 }"
10994   [(set_attr "type" "other")])
10995
10996 (define_expand "prefetch"
10997   [(prefetch (match_operand:QI 0 "address_operand" "p")
10998              (match_operand:SI 1 "const_int_operand" "n")
10999              (match_operand:SI 2 "const_int_operand" "n"))]
11000   "TARGET_SHMEDIA || TARGET_HARD_SH4"
11001   "
11002 {
11003   if (TARGET_HARD_SH4 && ! register_operand (operands[0], SImode))
11004     {
11005       rtx reg = gen_reg_rtx (SImode);
11006       emit_move_insn (reg, operands[0]);
11007       operands[0] = reg;
11008     }
11009
11010   emit_insn ((TARGET_SHMEDIA ? gen_prefetch_media : gen_prefetch_i4)
11011              (operands[0], operands[1], operands[2]));
11012   DONE;
11013 }")