OSDN Git Service

0186ba5b30e4fab0f390255987ec5c3bc29093e4
[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, 2006 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, 51 Franklin Street, Fifth Floor,
22 ;; Boston, MA 02110-1301, 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   (UNSPEC_DIV_INV_M0    30)
147   (UNSPEC_DIV_INV_M1    31)
148   (UNSPEC_DIV_INV_M2    32)
149   (UNSPEC_DIV_INV_M3    33)
150   (UNSPEC_DIV_INV20     34)
151   (UNSPEC_DIV_INV_TABLE 37)
152   (UNSPEC_ASHIFTRT      35)
153   (UNSPEC_THUNK         36)
154   (UNSPEC_SP_SET        40)
155   (UNSPEC_SP_TEST       41)
156   (UNSPEC_MOVUA         42)
157
158   ;; These are used with unspec_volatile.
159   (UNSPECV_BLOCKAGE     0)
160   (UNSPECV_ALIGN        1)
161   (UNSPECV_CONST2       2)
162   (UNSPECV_CONST4       4)
163   (UNSPECV_CONST8       6)
164   (UNSPECV_WINDOW_END   10)
165   (UNSPECV_CONST_END    11)
166 ])
167
168 ;; -------------------------------------------------------------------------
169 ;; Attributes
170 ;; -------------------------------------------------------------------------
171
172 ;; Target CPU.
173
174 (define_attr "cpu"
175  "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
176   (const (symbol_ref "sh_cpu_attr")))
177
178 (define_attr "endian" "big,little"
179  (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
180                       (const_string "little") (const_string "big"))))
181
182 ;; Indicate if the default fpu mode is single precision.
183 (define_attr "fpu_single" "yes,no"
184   (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
185                          (const_string "yes") (const_string "no"))))
186
187 (define_attr "fmovd" "yes,no"
188   (const (if_then_else (symbol_ref "TARGET_FMOVD")
189                        (const_string "yes") (const_string "no"))))
190 ;; pipeline model
191 (define_attr "pipe_model" "sh1,sh4,sh5media"
192   (const
193    (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
194           (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
195          (const_string "sh1"))))
196
197 ;; cbranch      conditional branch instructions
198 ;; jump         unconditional jumps
199 ;; arith        ordinary arithmetic
200 ;; arith3       a compound insn that behaves similarly to a sequence of
201 ;;              three insns of type arith
202 ;; arith3b      like above, but might end with a redirected branch
203 ;; load         from memory
204 ;; load_si      Likewise, SImode variant for general register.
205 ;; fload        Likewise, but load to fp register.
206 ;; store        to memory
207 ;; fstore       floating point register to memory
208 ;; move         general purpose register to register
209 ;; movi8        8 bit immediate to general purpose register
210 ;; mt_group     other sh4 mt instructions
211 ;; fmove        register to register, floating point
212 ;; smpy         word precision integer multiply
213 ;; dmpy         longword or doublelongword precision integer multiply
214 ;; return       rts
215 ;; pload        load of pr reg, which can't be put into delay slot of rts
216 ;; prset        copy register to pr reg, ditto
217 ;; pstore       store of pr reg, which can't be put into delay slot of jsr
218 ;; prget        copy pr to register, ditto
219 ;; pcload       pc relative load of constant value
220 ;; pcfload      Likewise, but load to fp register.
221 ;; pcload_si    Likewise, SImode variant for general register.
222 ;; rte          return from exception
223 ;; sfunc        special function call with known used registers
224 ;; call         function call
225 ;; fp           floating point
226 ;; fpscr_toggle toggle a bit in the fpscr
227 ;; fdiv         floating point divide (or square root)
228 ;; gp_fpul      move from general purpose register to fpul
229 ;; fpul_gp      move from fpul to general purpose register
230 ;; mac_gp       move from mac[lh] to general purpose register
231 ;; gp_mac       move from general purpose register to mac[lh]
232 ;; mac_mem      move from mac[lh] to memory
233 ;; mem_mac      move from memory to mac[lh]
234 ;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
235 ;; ftrc_s       fix_truncsfsi2_i4
236 ;; dfdiv        double precision floating point divide (or square root)
237 ;; cwb          ic_invalidate_line_i
238 ;; movua        SH4a unaligned load
239 ;; fsrra        square root reciprocal approximate
240 ;; fsca         sine and cosine approximate
241 ;; tls_load     load TLS related address
242 ;; arith_media  SHmedia arithmetic, logical, and shift instructions
243 ;; cbranch_media SHmedia conditional branch instructions
244 ;; cmp_media    SHmedia compare instructions
245 ;; dfdiv_media  SHmedia double precision divide and square root
246 ;; dfmul_media  SHmedia double precision multiply instruction
247 ;; dfparith_media SHmedia double precision floating point arithmetic
248 ;; dfpconv_media SHmedia double precision floating point conversions
249 ;; dmpy_media   SHmedia longword multiply
250 ;; fcmp_media   SHmedia floating point compare instructions
251 ;; fdiv_media   SHmedia single precision divide and square root
252 ;; fload_media  SHmedia floating point register load instructions
253 ;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
254 ;; fparith_media SHmedia single precision floating point arithmetic
255 ;; fpconv_media SHmedia single precision floating point conversions
256 ;; fstore_media SHmedia floating point register store instructions
257 ;; gettr_media  SHmedia gettr instruction
258 ;; invalidate_line_media SHmedia invalidate_line sequence
259 ;; jump_media   SHmedia unconditional branch instructions
260 ;; load_media   SHmedia general register load instructions
261 ;; pt_media     SHmedia pt instruction (expanded by assembler)
262 ;; ptabs_media  SHmedia ptabs instruction
263 ;; store_media  SHmedia general register store instructions
264 ;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
265 ;; mac_media    SHmedia mac-style fixed point operations
266 ;; d2mpy_media  SHmedia: two 32 bit integer multiplies
267 ;; atrans_media SHmedia approximate transcendental functions
268 ;; ustore_media SHmedia unaligned stores
269 ;; nil          no-op move, will be deleted.
270
271 (define_attr "type"
272  "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,fstore,move,movi8,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fpscr_toggle,fdiv,ftrc_s,dfp_arith,dfp_mul,fp_cmp,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,gp_mac,mac_mem,mem_mac,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"
273   (const_string "other"))
274
275 ;; We define a new attribute namely "insn_class".We use
276 ;; this for the DFA based pipeline description.
277 ;;
278 ;; mt_group      SH4 "mt" group instructions.
279 ;;
280 ;; ex_group      SH4 "ex" group instructions.
281 ;;
282 ;; ls_group      SH4 "ls" group instructions.
283 ;;
284
285 (define_attr "insn_class"
286   "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
287   (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
288          (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
289          (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
290          (eq_attr "type" "cbranch,jump") (const_string "br_group")
291          (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
292            (const_string "fe_group")
293          (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb,gp_mac,mac_mem,mem_mac") (const_string "co_group")]
294         (const_string "none")))
295 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
296 ;; so these do not belong in an insn group, although they are modeled
297 ;; with their own define_insn_reservations.
298
299 ;; Indicate what precision must be selected in fpscr for this insn, if any.
300
301 (define_attr "fp_mode" "single,double,none" (const_string "none"))
302
303 ;; Indicate if the fpu mode is set by this instruction
304 ;; "unknown" must have the value as "none" in fp_mode, and means
305 ;; that the instruction/abi has left the processor in an unknown
306 ;; state.
307 ;; "none" means that nothing has changed and no mode is set.
308 ;; This attribute is only used for the Renesas ABI.
309 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
310
311 ; If a conditional branch destination is within -252..258 bytes away
312 ; from the instruction it can be 2 bytes long.  Something in the
313 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
314 ; branches are initially assumed to be 16 bytes long.
315 ; In machine_dependent_reorg, we split all branches that are longer than
316 ; 2 bytes.
317
318 ;; The maximum range used for SImode constant pool entries is 1018.  A final
319 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
320 ;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
321 ;; instruction around the pool table, 2 bytes of alignment before the table,
322 ;; and 30 bytes of alignment after the table.  That gives a maximum total
323 ;; pool size of 1058 bytes.
324 ;; Worst case code/pool content size ratio is 1:2 (using asms).
325 ;; Thus, in the worst case, there is one instruction in front of a maximum
326 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
327 ;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
328 ;; If we have a forward branch, the initial table will be put after the
329 ;; unconditional branch.
330 ;;
331 ;; ??? We could do much better by keeping track of the actual pcloads within
332 ;; the branch range and in the pcload range in front of the branch range.
333
334 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
335 ;; inside an le.
336 (define_attr "short_cbranch_p" "no,yes"
337   (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
338          (const_string "no")
339          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
340          (const_string "yes")
341          (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
342          (const_string "no")
343          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
344          (const_string "yes")
345          ] (const_string "no")))
346
347 (define_attr "med_branch_p" "no,yes"
348   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
349               (const_int 1988))
350          (const_string "yes")
351          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
352          (const_string "no")
353          (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
354               (const_int 8186))
355          (const_string "yes")
356          ] (const_string "no")))
357
358 (define_attr "med_cbranch_p" "no,yes"
359   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
360               (const_int 1986))
361          (const_string "yes")
362          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
363          (const_string "no")
364          (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
365                (const_int 8184))
366          (const_string "yes")
367          ] (const_string "no")))
368
369 (define_attr "braf_branch_p" "no,yes"
370   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
371          (const_string "no")
372          (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
373               (const_int 20660))
374          (const_string "yes")
375          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
376          (const_string "no")
377          (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
378               (const_int 65530))
379          (const_string "yes")
380          ] (const_string "no")))
381
382 (define_attr "braf_cbranch_p" "no,yes"
383   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
384          (const_string "no")
385          (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
386               (const_int 20658))
387          (const_string "yes")
388          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
389          (const_string "no")
390          (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
391               (const_int 65528))
392          (const_string "yes")
393          ] (const_string "no")))
394
395 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
396 ; For wider ranges, we need a combination of a code and a data part.
397 ; If we can get a scratch register for a long range jump, the code
398 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
399 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
400 ; long; otherwise, it must be 6 bytes long.
401
402 ; All other instructions are two bytes long by default.
403
404 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
405 ;; but getattrtab doesn't understand this.
406 (define_attr "length" ""
407   (cond [(eq_attr "type" "cbranch")
408          (cond [(eq_attr "short_cbranch_p" "yes")
409                 (const_int 2)
410                 (eq_attr "med_cbranch_p" "yes")
411                 (const_int 6)
412                 (eq_attr "braf_cbranch_p" "yes")
413                 (const_int 12)
414 ;; ??? using pc is not computed transitively.
415                 (ne (match_dup 0) (match_dup 0))
416                 (const_int 14)
417                 (ne (symbol_ref ("flag_pic")) (const_int 0))
418                 (const_int 24)
419                 ] (const_int 16))
420          (eq_attr "type" "jump")
421          (cond [(eq_attr "med_branch_p" "yes")
422                 (const_int 2)
423                 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
424                          (symbol_ref "INSN"))
425                      (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
426                          (symbol_ref "code_for_indirect_jump_scratch")))
427                 (cond [(eq_attr "braf_branch_p" "yes")
428                        (const_int 6)
429                        (eq (symbol_ref "flag_pic") (const_int 0))
430                        (const_int 10)
431                        (ne (symbol_ref "TARGET_SH2") (const_int 0))
432                        (const_int 10)] (const_int 18))
433                 (eq_attr "braf_branch_p" "yes")
434                 (const_int 10)
435 ;; ??? using pc is not computed transitively.
436                 (ne (match_dup 0) (match_dup 0))
437                 (const_int 12)
438                 (ne (symbol_ref ("flag_pic")) (const_int 0))
439                 (const_int 22)
440                 ] (const_int 14))
441          (eq_attr "type" "pt_media")
442          (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
443                        (const_int 20) (const_int 12))
444          (and (eq_attr "type" "jump_media")
445               (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
446          (const_int 8)
447          ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
448                          (const_int 4)
449                          (const_int 2))))
450
451 ;; DFA descriptions for the pipelines
452
453 (include "sh1.md")
454 (include "shmedia.md")
455 (include "sh4.md")
456
457 (include "predicates.md")
458
459 ;; Definitions for filling delay slots
460
461 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
462
463 ;; ??? This should be (nil) instead of (const_int 0)
464 (define_attr "hit_stack" "yes,no"
465         (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
466                    (const_int 0))
467                (const_string "no")]
468               (const_string "yes")))
469
470 (define_attr "interrupt_function" "no,yes"
471   (const (symbol_ref "current_function_interrupt")))
472
473 (define_attr "in_delay_slot" "yes,no"
474   (cond [(eq_attr "type" "cbranch") (const_string "no")
475          (eq_attr "type" "pcload,pcload_si") (const_string "no")
476          (eq_attr "needs_delay_slot" "yes") (const_string "no")
477          (eq_attr "length" "2") (const_string "yes")
478          ] (const_string "no")))
479
480 (define_attr "cond_delay_slot" "yes,no"
481   (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
482          ] (const_string "no")))
483
484 (define_attr "is_sfunc" ""
485   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
486
487 (define_attr "is_mac_media" ""
488   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
489
490 (define_attr "branch_zero" "yes,no"
491   (cond [(eq_attr "type" "!cbranch") (const_string "no")
492          (ne (symbol_ref "(next_active_insn (insn)\
493                            == (prev_active_insn\
494                                (XEXP (SET_SRC (PATTERN (insn)), 1))))\
495                           && get_attr_length (next_active_insn (insn)) == 2")
496              (const_int 0))
497          (const_string "yes")]
498         (const_string "no")))
499
500 ;; SH4 Double-precision computation with double-precision result -
501 ;; the two halves are ready at different times.
502 (define_attr "dfp_comp" "yes,no"
503   (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
504         (const_string "no")))
505
506 ;; Insns for which the latency of a preceding fp insn is decreased by one.
507 (define_attr "late_fp_use" "yes,no" (const_string "no"))
508 ;; And feeding insns for which this relevant.
509 (define_attr "any_fp_comp" "yes,no"
510   (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
511          (const_string "yes")]
512         (const_string "no")))
513
514 (define_attr "any_int_load" "yes,no"
515   (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
516          (const_string "yes")]
517         (const_string "no")))
518
519 (define_attr "highpart" "user, ignore, extend, depend, must_split"
520   (const_string "user"))
521
522 (define_delay
523   (eq_attr "needs_delay_slot" "yes")
524   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
525
526 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
527 ;; and thus we can't put a pop instruction in its delay slot.
528 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
529 ;; instruction can go in the delay slot.
530
531 ;; Since a normal return (rts) implicitly uses the PR register,
532 ;; we can't allow PR register loads in an rts delay slot.
533
534 (define_delay
535   (eq_attr "type" "return")
536   [(and (eq_attr "in_delay_slot" "yes")
537         (ior (and (eq_attr "interrupt_function" "no")
538                   (eq_attr "type" "!pload,prset"))
539              (and (eq_attr "interrupt_function" "yes")
540                   (ior
541                    (ne (symbol_ref "TARGET_SH3") (const_int 0))
542                    (eq_attr "hit_stack" "no"))))) (nil) (nil)])
543
544 ;; Since a call implicitly uses the PR register, we can't allow
545 ;; a PR register store in a jsr delay slot.
546
547 (define_delay
548   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
549   [(and (eq_attr "in_delay_slot" "yes")
550         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
551
552 ;; Say that we have annulled true branches, since this gives smaller and
553 ;; faster code when branches are predicted as not taken.
554
555 ;; ??? The non-annulled condition should really be "in_delay_slot",
556 ;; but insns that can be filled in non-annulled get priority over insns
557 ;; that can only be filled in anulled.
558
559 (define_delay
560   (and (eq_attr "type" "cbranch")
561        (ne (symbol_ref "TARGET_SH2") (const_int 0)))
562   ;; SH2e has a hardware bug that pretty much prohibits the use of
563   ;; annuled delay slots.
564   [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
565                                           (not (eq_attr "cpu" "sh2e"))) (nil)])
566 \f
567 ;; -------------------------------------------------------------------------
568 ;; SImode signed integer comparisons
569 ;; -------------------------------------------------------------------------
570
571 (define_insn ""
572   [(set (reg:SI T_REG)
573         (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
574                        (match_operand:SI 1 "arith_operand" "K08,r"))
575                (const_int 0)))]
576   "TARGET_SH1"
577   "tst  %1,%0"
578   [(set_attr "type" "mt_group")])
579
580 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
581 ;; That would still allow reload to create cmpi instructions, but would
582 ;; perhaps allow forcing the constant into a register when that is better.
583 ;; Probably should use r0 for mem/imm compares, but force constant into a
584 ;; register for pseudo/imm compares.
585
586 (define_insn "cmpeqsi_t"
587   [(set (reg:SI T_REG)
588         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
589                (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
590   "TARGET_SH1"
591   "@
592         tst     %0,%0
593         cmp/eq  %1,%0
594         cmp/eq  %1,%0"
595    [(set_attr "type" "mt_group")])
596
597 (define_insn "cmpgtsi_t"
598   [(set (reg:SI T_REG)
599         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
600                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
601   "TARGET_SH1"
602   "@
603         cmp/gt  %1,%0
604         cmp/pl  %0"
605    [(set_attr "type" "mt_group")])
606
607 (define_insn "cmpgesi_t"
608   [(set (reg:SI T_REG)
609         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
610                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
611   "TARGET_SH1"
612   "@
613         cmp/ge  %1,%0
614         cmp/pz  %0"
615    [(set_attr "type" "mt_group")])
616
617 ;; -------------------------------------------------------------------------
618 ;; SImode compare and branch
619 ;; -------------------------------------------------------------------------
620
621 (define_expand "cbranchsi4"
622   [(set (pc)
623         (if_then_else (match_operator 0 "comparison_operator"
624                         [(match_operand:SI 1 "arith_operand" "")
625                          (match_operand:SI 2 "arith_operand" "")])
626                       (label_ref (match_operand 3 "" ""))
627                       (pc)))
628    (clobber (reg:SI T_REG))]
629   "TARGET_CBRANCHDI4"
630   "expand_cbranchsi4 (operands, CODE_FOR_nothing, -1); DONE;")
631
632 ;; -------------------------------------------------------------------------
633 ;; SImode unsigned integer comparisons
634 ;; -------------------------------------------------------------------------
635
636 (define_insn_and_split "cmpgeusi_t"
637   [(set (reg:SI T_REG)
638         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
639                 (match_operand:SI 1 "arith_reg_or_0_operand" "rN")))]
640   "TARGET_SH1"
641   "cmp/hs       %1,%0"
642   "&& operands[0] == CONST0_RTX (SImode)"
643   [(pc)]
644   "
645 {
646   emit_insn (gen_sett ());
647   DONE;
648 }"
649    [(set_attr "type" "mt_group")])
650
651 (define_insn "cmpgtusi_t"
652   [(set (reg:SI T_REG)
653         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
654                 (match_operand:SI 1 "arith_reg_operand" "r")))]
655   "TARGET_SH1"
656   "cmp/hi       %1,%0"
657    [(set_attr "type" "mt_group")])
658
659 ;; We save the compare operands in the cmpxx patterns and use them when
660 ;; we generate the branch.
661
662 (define_expand "cmpsi"
663   [(set (reg:SI T_REG)
664         (compare (match_operand:SI 0 "cmpsi_operand" "")
665                  (match_operand:SI 1 "arith_operand" "")))]
666   "TARGET_SH1 || TARGET_SHMEDIA"
667   "
668 {
669   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
670       && GET_CODE (operands[1]) != CONST_INT)
671     operands[0] = copy_to_mode_reg (SImode, operands[0]);
672   sh_compare_op0 = operands[0];
673   sh_compare_op1 = operands[1];
674   DONE;
675 }")
676 \f
677 ;; -------------------------------------------------------------------------
678 ;; DImode compare and branch
679 ;; -------------------------------------------------------------------------
680
681
682 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
683 ;; Therefore, we aim to have a set of three branches that go straight to the
684 ;; destination, i.e. only one of them is taken at any one time.
685 ;; This mechanism should also be slightly better for the sh4-200.
686
687 (define_expand "cbranchdi4"
688   [(set (pc)
689         (if_then_else (match_operator 0 "comparison_operator"
690                         [(match_operand:DI 1 "arith_operand" "")
691                          (match_operand:DI 2 "arith_operand" "")])
692                       (label_ref (match_operand 3 "" ""))
693                       (pc)))
694    (clobber (match_dup 4))
695    (clobber (reg:SI T_REG))]
696   "TARGET_CBRANCHDI4"
697   "
698 {
699   enum rtx_code comparison;
700
701   if (TARGET_EXPAND_CBRANCHDI4)
702     {
703       if (expand_cbranchdi4 (operands, CODE_FOR_nothing))
704         DONE;
705     }
706   comparison = prepare_cbranch_operands (operands, DImode, CODE_FOR_nothing);
707   if (comparison != GET_CODE (operands[0]))
708     operands[0]
709       = gen_rtx_fmt_ee (VOIDmode, comparison, operands[1], operands[2]);
710    operands[4] = gen_rtx_SCRATCH (SImode);
711 }")
712
713 (define_insn_and_split "cbranchdi4_i"
714   [(set (pc)
715         (if_then_else (match_operator 0 "comparison_operator"
716                         [(match_operand:DI 1 "arith_operand" "r,r")
717                          (match_operand:DI 2 "arith_operand" "rN,i")])
718                       (label_ref (match_operand 3 "" ""))
719                       (pc)))
720    (clobber (match_scratch:SI 4 "=X,&r"))
721    (clobber (reg:SI T_REG))]
722   "TARGET_CBRANCHDI4"
723   "#"
724   "&& reload_completed"
725   [(pc)]
726   "
727 {
728   if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
729     FAIL;
730   DONE;
731 }")
732
733 ;; -------------------------------------------------------------------------
734 ;; DImode signed integer comparisons
735 ;; -------------------------------------------------------------------------
736
737 (define_insn ""
738   [(set (reg:SI T_REG)
739         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
740                        (match_operand:DI 1 "arith_operand" "r"))
741                (const_int 0)))]
742   "TARGET_SH1"
743   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
744                                  insn, operands);"
745   [(set_attr "length" "6")
746    (set_attr "type" "arith3b")])
747
748 (define_insn "cmpeqdi_t"
749   [(set (reg:SI T_REG)
750         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
751                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
752   "TARGET_SH1"
753   "@
754         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
755         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
756   [(set_attr "length" "6")
757    (set_attr "type" "arith3b")])
758
759 (define_split
760   [(set (reg:SI T_REG)
761         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
762                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
763 ;; If we applied this split when not optimizing, it would only be
764 ;; applied during the machine-dependent reorg, when no new basic blocks
765 ;; may be created.
766   "TARGET_SH1 && reload_completed && optimize"
767   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
768    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
769                            (label_ref (match_dup 6))
770                            (pc)))
771    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
772    (match_dup 6)]
773   "
774 {
775   operands[2]
776     = gen_rtx_REG (SImode,
777                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
778   operands[3]
779     = (operands[1] == const0_rtx
780        ? const0_rtx
781        : gen_rtx_REG (SImode,
782                       true_regnum (operands[1])
783                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
784   operands[4] = gen_lowpart (SImode, operands[0]);
785   operands[5] = gen_lowpart (SImode, operands[1]);
786   operands[6] = gen_label_rtx ();
787 }")
788
789 (define_insn "cmpgtdi_t"
790   [(set (reg:SI T_REG)
791         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
792                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
793   "TARGET_SH2"
794   "@
795         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
796         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
797   [(set_attr "length" "8")
798    (set_attr "type" "arith3")])
799
800 (define_insn "cmpgedi_t"
801   [(set (reg:SI T_REG)
802         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
803                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
804   "TARGET_SH2"
805   "@
806         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
807         cmp/pz\\t%S0"
808   [(set_attr "length" "8,2")
809    (set_attr "type" "arith3,mt_group")])
810 \f
811 ;; -------------------------------------------------------------------------
812 ;; DImode unsigned integer comparisons
813 ;; -------------------------------------------------------------------------
814
815 (define_insn "cmpgeudi_t"
816   [(set (reg:SI T_REG)
817         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
818                 (match_operand:DI 1 "arith_reg_operand" "r")))]
819   "TARGET_SH2"
820   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
821   [(set_attr "length" "8")
822    (set_attr "type" "arith3")])
823
824 (define_insn "cmpgtudi_t"
825   [(set (reg:SI T_REG)
826         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
827                 (match_operand:DI 1 "arith_reg_operand" "r")))]
828   "TARGET_SH2"
829   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
830   [(set_attr "length" "8")
831    (set_attr "type" "arith3")])
832
833 (define_insn "cmpeqsi_media"
834   [(set (match_operand:SI 0 "register_operand" "=r")
835         (eq:SI (match_operand:SI 1 "logical_operand" "%r")
836                (match_operand:SI 2 "cmp_operand" "Nr")))]
837   "TARGET_SHMEDIA"
838   "cmpeq        %1, %N2, %0"
839   [(set_attr "type" "cmp_media")])
840
841 (define_insn "cmpeqdi_media"
842   [(set (match_operand:SI 0 "register_operand" "=r")
843         (eq:SI (match_operand:DI 1 "register_operand" "%r")
844                (match_operand:DI 2 "cmp_operand" "Nr")))]
845   "TARGET_SHMEDIA"
846   "cmpeq        %1, %N2, %0"
847   [(set_attr "type" "cmp_media")])
848
849 (define_insn "cmpgtsi_media"
850   [(set (match_operand:SI 0 "register_operand" "=r")
851         (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
852                (match_operand:SI 2 "cmp_operand" "rN")))]
853   "TARGET_SHMEDIA"
854   "cmpgt        %N1, %N2, %0"
855   [(set_attr "type" "cmp_media")])
856
857 (define_insn "cmpgtdi_media"
858   [(set (match_operand:SI 0 "register_operand" "=r")
859         (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
860                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
861   "TARGET_SHMEDIA"
862   "cmpgt        %N1, %N2, %0"
863   [(set_attr "type" "cmp_media")])
864
865 (define_insn "cmpgtusi_media"
866   [(set (match_operand:SI 0 "register_operand" "=r")
867         (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
868                 (match_operand:SI 2 "cmp_operand" "rN")))]
869   "TARGET_SHMEDIA"
870   "cmpgtu       %N1, %N2, %0"
871   [(set_attr "type" "cmp_media")])
872
873 (define_insn "cmpgtudi_media"
874   [(set (match_operand:SI 0 "register_operand" "=r")
875         (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
876                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
877   "TARGET_SHMEDIA"
878   "cmpgtu       %N1, %N2, %0"
879   [(set_attr "type" "cmp_media")])
880
881 ; These two patterns are for combine.
882 (define_insn "*cmpne0sisi_media"
883   [(set (match_operand:SI 0 "register_operand" "=r")
884         (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
885   "TARGET_SHMEDIA"
886   "cmpgtu       %1,r63,%0"
887   [(set_attr "type" "cmp_media")])
888
889 ;; We save the compare operands in the cmpxx patterns and use them when
890 ;; we generate the branch.
891
892 (define_expand "cmpdi"
893   [(set (reg:SI T_REG)
894         (compare (match_operand:DI 0 "arith_operand" "")
895                  (match_operand:DI 1 "arith_operand" "")))]
896   "TARGET_SH2 || TARGET_SHMEDIA"
897   "
898 {
899   sh_compare_op0 = operands[0];
900   sh_compare_op1 = operands[1];
901   DONE;
902 }")
903 ;; -------------------------------------------------------------------------
904 ;; Conditional move instructions
905 ;; -------------------------------------------------------------------------
906
907 ;; The insn names may seem reversed, but note that cmveq performs the move
908 ;; if op1 == 0, and cmvne does it if op1 != 0.
909
910 (define_insn "movdicc_false"
911   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
912         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
913                              (const_int 0))
914          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
915          (match_operand:DI 3 "arith_reg_operand" "0")))]
916   "TARGET_SHMEDIA"
917   "cmveq        %1, %N2, %0"
918   [(set_attr "type" "arith_media")])
919
920 (define_insn "movdicc_true"
921   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
922         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
923                              (const_int 0))
924          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
925          (match_operand:DI 3 "arith_reg_operand" "0")))]
926   "TARGET_SHMEDIA"
927   "cmvne        %1, %N2, %0"
928   [(set_attr "type" "arith_media")])
929
930 (define_peephole2
931   [(set (match_operand:DI 0 "arith_reg_dest" "")
932         (if_then_else:DI (match_operator 3 "equality_comparison_operator"
933                            [(match_operand:DI 1 "arith_reg_operand" "")
934                             (const_int 0)])
935          (match_operand:DI 2 "arith_reg_dest" "")
936          (match_dup 0)))
937    (set (match_dup 2) (match_dup 0))]
938   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
939   [(set (match_dup 2)
940         (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
941   "
942 {
943   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
944                                 VOIDmode, operands[1], CONST0_RTX (DImode));
945 }")
946
947 (define_peephole2
948   [(set (match_operand:DI 0 "general_movdst_operand" "")
949         (match_operand:DI 1 "arith_reg_or_0_operand" ""))
950    (set (match_operand:DI 2 "arith_reg_dest" "")
951         (if_then_else:DI (match_operator 4 "equality_comparison_operator"
952                            [(match_operand:DI 3 "arith_reg_operand" "")
953                             (const_int 0)])
954          (match_dup 0)
955          (match_dup 2)))]
956   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
957   [(set (match_dup 2)
958         (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
959   "")
960
961 (define_expand "movdicc"
962   [(set (match_operand:DI 0 "register_operand" "")
963         (if_then_else:DI (match_operand 1 "comparison_operator" "")
964                          (match_operand:DI 2 "register_operand" "")
965                          (match_operand:DI 3 "register_operand" "")))]
966   "TARGET_SHMEDIA"
967   "
968 {
969   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
970       && GET_MODE (sh_compare_op0) == DImode
971       && sh_compare_op1 == const0_rtx)
972     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
973                                   sh_compare_op0, sh_compare_op1);
974   else
975     {
976       rtx tmp;
977
978       if (no_new_pseudos)
979         FAIL;
980
981       tmp = gen_reg_rtx (DImode);
982
983       switch (GET_CODE (operands[1]))
984         {
985         case EQ:
986           emit_insn (gen_seq (tmp));
987           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
988           break;
989
990         case NE:
991           emit_insn (gen_seq (tmp));
992           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
993           break;
994
995         case GT:
996           emit_insn (gen_sgt (tmp));
997           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
998           break;
999
1000         case LT:
1001           emit_insn (gen_slt (tmp));
1002           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1003           break;
1004
1005         case GE:
1006           emit_insn (gen_slt (tmp));
1007           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1008           break;
1009
1010         case LE:
1011           emit_insn (gen_sgt (tmp));
1012           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1013           break;
1014
1015         case GTU:
1016           emit_insn (gen_sgtu (tmp));
1017           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1018           break;
1019
1020         case LTU:
1021           emit_insn (gen_sltu (tmp));
1022           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1023           break;
1024
1025         case GEU:
1026           emit_insn (gen_sltu (tmp));
1027           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1028           break;
1029
1030         case LEU:
1031           emit_insn (gen_sgtu (tmp));
1032           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1033           break;
1034
1035         case UNORDERED:
1036           emit_insn (gen_sunordered (tmp));
1037           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1038           break;
1039
1040         case ORDERED:
1041           emit_insn (gen_sunordered (tmp));
1042           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1043           break;
1044
1045         case UNEQ:
1046         case UNGE:
1047         case UNGT:
1048         case UNLE:
1049         case UNLT:
1050         case LTGT:
1051           FAIL;
1052
1053         default:
1054           gcc_unreachable ();
1055         }
1056     }
1057 }")
1058
1059 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1060 ;; SImode to DImode.
1061 (define_insn "movsicc_false"
1062   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1063         (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1064                           (const_int 0))
1065          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1066          (match_operand:SI 3 "arith_reg_operand" "0")))]
1067   "TARGET_SHMEDIA"
1068   "cmveq        %1, %N2, %0"
1069   [(set_attr "type" "arith_media")])
1070
1071 (define_insn "movsicc_true"
1072   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1073         (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1074                           (const_int 0))
1075          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1076          (match_operand:SI 3 "arith_reg_operand" "0")))]
1077   "TARGET_SHMEDIA"
1078   "cmvne        %1, %N2, %0"
1079   [(set_attr "type" "arith_media")])
1080
1081 (define_peephole2
1082   [(set (match_operand:SI 0 "arith_reg_dest" "")
1083         (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1084                            [(match_operand:SI 1 "arith_reg_operand" "")
1085                             (const_int 0)])
1086          (match_operand:SI 2 "arith_reg_dest" "")
1087          (match_dup 0)))
1088    (set (match_dup 2) (match_dup 0))]
1089   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1090   [(set (match_dup 2)
1091         (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1092   "
1093 {
1094   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1095                                 VOIDmode, operands[1], CONST0_RTX (SImode));
1096 }")
1097
1098 (define_peephole2
1099   [(set (match_operand:SI 0 "general_movdst_operand" "")
1100         (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1101    (set (match_operand:SI 2 "arith_reg_dest" "")
1102         (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1103                            [(match_operand:SI 3 "arith_reg_operand" "")
1104                             (const_int 0)])
1105          (match_dup 0)
1106          (match_dup 2)))]
1107   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1108    && (GET_CODE (operands[1]) != REG || GENERAL_REGISTER_P (REGNO (operands[1])))"
1109   [(set (match_dup 2)
1110         (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1111   "
1112 {
1113   replace_rtx (operands[4], operands[0], operands[1]);
1114 }")
1115
1116 (define_peephole2
1117   [(set (match_operand 0 "any_register_operand" "")
1118         (match_operand 1 "any_register_operand" ""))
1119    (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1120    (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1121   "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1122     <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1123    && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1124    && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1125    && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1126    && ! reg_overlap_mentioned_p (operands[0], operands[3])
1127    && ! reg_overlap_mentioned_p (operands[2], operands[0])
1128    && ! reg_overlap_mentioned_p (operands[0], operands[1])
1129    && (REGNO_REG_CLASS (REGNO (operands[0]))
1130        == REGNO_REG_CLASS (REGNO (operands[2])))
1131    && (REGNO_REG_CLASS (REGNO (operands[1]))
1132        == REGNO_REG_CLASS (REGNO (operands[0])))"
1133   [(set (match_dup 0) (match_dup 3))
1134    (set (match_dup 4) (match_dup 5))]
1135   "
1136 {
1137   rtx set1, set2;
1138   rtx replacements[4];
1139
1140   /* We want to replace occurrences of operands[0] with operands[1] and
1141      operands[2] with operands[0] in operands[4]/operands[5].
1142      Doing just two replace_rtx calls naively would result in the second
1143      replacement undoing all that the first did if operands[1] and operands[2]
1144      are identical, so we must do this simultaneously.  */
1145   replacements[0] = operands[0];
1146   replacements[1] = operands[1];
1147   replacements[2] = operands[2];
1148   replacements[3] = operands[0];
1149   if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1150       || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1151       || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1152     FAIL;
1153
1154   operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1155   replace_n_hard_rtx (operands[4], replacements, 2, 1);
1156   operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1157   /* The operands array is aliased to recog_data.operand, which gets
1158      clobbered by extract_insn, so finish with it now.  */
1159   set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1160   set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1161   /* ??? The last insn might be a jump insn, but the generic peephole2 code
1162      always uses emit_insn.  */
1163   /* Check that we don't violate matching constraints or earlyclobbers.  */
1164   extract_insn (emit_insn (set1));
1165   if (! constrain_operands (1))
1166     goto failure;
1167   extract_insn (emit (set2));
1168   if (! constrain_operands (1))
1169     {
1170       rtx tmp;
1171     failure:
1172       tmp = replacements[0];
1173       replacements[0] = replacements[1];
1174       replacements[1] = tmp;
1175       tmp = replacements[2];
1176       replacements[2] = replacements[3];
1177       replacements[3] = tmp;
1178       replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1179       replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1180       replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1181       FAIL;
1182     }
1183   DONE;
1184 }")
1185
1186 ;; The register allocator is rather clumsy in handling multi-way conditional
1187 ;; moves, so allow the combiner to make them, and we split them up after
1188 ;; reload.  */
1189 (define_insn_and_split "*movsicc_umin"
1190   [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1191         (umin:SI (if_then_else:SI
1192                    (eq (match_operand:SI 1 "arith_reg_operand" "r")
1193                        (const_int 0))
1194                    (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1195                    (match_operand:SI 3 "register_operand" "0"))
1196                  (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1197    (clobber (match_scratch:SI 5 "=&r"))]
1198   "TARGET_SHMEDIA && no_new_pseudos"
1199   "#"
1200   "TARGET_SHMEDIA && reload_completed"
1201   [(pc)]
1202   "
1203 {
1204   emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1205                                 operands[3]));
1206   emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1207   emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1208                                 operands[0]));
1209   DONE;
1210 }")
1211
1212 (define_insn "*movsicc_t_false"
1213   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1214         (if_then_else (eq (reg:SI T_REG) (const_int 0))
1215                       (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1216                       (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1217   "TARGET_PRETEND_CMOVE
1218    && (arith_reg_operand (operands[1], SImode)
1219        || (immediate_operand (operands[1], SImode)
1220            && CONST_OK_FOR_I08 (INTVAL (operands[1]))))"
1221   "bt 0f\;mov %1,%0\\n0:"
1222   [(set_attr "type" "mt_group,arith") ;; poor approximation
1223    (set_attr "length" "4")])
1224
1225 (define_insn "*movsicc_t_true"
1226   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1227         (if_then_else (ne (reg:SI T_REG) (const_int 0))
1228                       (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1229                       (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1230   "TARGET_PRETEND_CMOVE
1231    && (arith_reg_operand (operands[1], SImode)
1232        || (immediate_operand (operands[1], SImode)
1233            && CONST_OK_FOR_I08 (INTVAL (operands[1]))))"
1234   "bf 0f\;mov %1,%0\\n0:"
1235   [(set_attr "type" "mt_group,arith") ;; poor approximation
1236    (set_attr "length" "4")])
1237
1238 (define_expand "movsicc"
1239   [(set (match_operand:SI 0 "arith_reg_dest" "")
1240         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1241                          (match_operand:SI 2 "arith_reg_or_0_operand" "")
1242                          (match_operand:SI 3 "arith_reg_operand" "")))]
1243   "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1244   "
1245 {
1246   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1247       && GET_MODE (sh_compare_op0) == SImode
1248       && (TARGET_SHMEDIA
1249           || (REG_P (sh_compare_op0) && REGNO (sh_compare_op0) == T_REG))
1250       && sh_compare_op1 == const0_rtx)
1251     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
1252                                   sh_compare_op0, sh_compare_op1);
1253   else if (TARGET_PRETEND_CMOVE)
1254     {
1255       enum rtx_code code = GET_CODE (operands[1]);
1256       enum rtx_code new_code = code;
1257       rtx tmp;
1258
1259       if (! currently_expanding_to_rtl)
1260         FAIL;
1261       switch (code)
1262         {
1263         case LT: case LE: case LEU: case LTU:
1264           if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) != MODE_INT)
1265             break;
1266         case NE:
1267           new_code = reverse_condition (code);
1268           break;
1269         case EQ: case GT: case GE: case GEU: case GTU:
1270           break;
1271         default:
1272           FAIL;
1273         }
1274       tmp = prepare_scc_operands (new_code);
1275       operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1276                                     tmp, const0_rtx);
1277     }
1278   else
1279     {
1280       rtx tmp;
1281
1282       if (no_new_pseudos)
1283         FAIL;
1284
1285       tmp = gen_reg_rtx (SImode);
1286
1287       switch (GET_CODE (operands[1]))
1288         {
1289         case EQ:
1290           emit_insn (gen_seq (tmp));
1291           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1292           break;
1293
1294         case NE:
1295           emit_insn (gen_seq (tmp));
1296           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1297           break;
1298
1299         case GT:
1300           emit_insn (gen_sgt (tmp));
1301           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1302           break;
1303
1304         case LT:
1305           emit_insn (gen_slt (tmp));
1306           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1307           break;
1308
1309         case GE:
1310           emit_insn (gen_slt (tmp));
1311           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1312           break;
1313
1314         case LE:
1315           emit_insn (gen_sgt (tmp));
1316           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1317           break;
1318
1319         case GTU:
1320           emit_insn (gen_sgtu (tmp));
1321           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1322           break;
1323
1324         case LTU:
1325           emit_insn (gen_sltu (tmp));
1326           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1327           break;
1328
1329         case GEU:
1330           emit_insn (gen_sltu (tmp));
1331           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1332           break;
1333
1334         case LEU:
1335           emit_insn (gen_sgtu (tmp));
1336           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1337           break;
1338
1339         case UNORDERED:
1340           emit_insn (gen_sunordered (tmp));
1341           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1342           break;
1343
1344         case ORDERED:
1345           emit_insn (gen_sunordered (tmp));
1346           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1347           break;
1348
1349         case UNEQ:
1350         case UNGE:
1351         case UNGT:
1352         case UNLE:
1353         case UNLT:
1354         case LTGT:
1355           FAIL;
1356
1357         default:
1358           abort ();
1359         }
1360     }
1361 }")
1362
1363 (define_expand "movqicc"
1364   [(set (match_operand:QI 0 "register_operand" "")
1365         (if_then_else:QI (match_operand 1 "comparison_operator" "")
1366                          (match_operand:QI 2 "register_operand" "")
1367                          (match_operand:QI 3 "register_operand" "")))]
1368   "TARGET_SHMEDIA"
1369   "
1370 {
1371   operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1372   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1373   operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1374   emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1375   DONE;
1376 }")
1377 \f
1378 ;; -------------------------------------------------------------------------
1379 ;; Addition instructions
1380 ;; -------------------------------------------------------------------------
1381
1382 (define_expand "adddi3"
1383   [(set (match_operand:DI 0 "arith_reg_operand" "")
1384         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1385                  (match_operand:DI 2 "arith_operand" "")))]
1386   ""
1387   "
1388 {
1389   if (TARGET_SH1)
1390     {
1391       if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
1392         FAIL;
1393       operands[2] = force_reg (DImode, operands[2]);
1394       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1395       DONE;
1396     }
1397 }")
1398
1399 (define_insn "*adddi3_media"
1400   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1401         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1402                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1403   "TARGET_SHMEDIA"
1404   "@
1405         add     %1, %2, %0
1406         addi    %1, %2, %0"
1407   [(set_attr "type" "arith_media")])
1408
1409 (define_insn "*adddisi3_media"
1410   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1411         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1412                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1413   "TARGET_SHMEDIA"
1414   "@
1415         add.l   %1, %2, %0
1416         addi.l  %1, %2, %0"
1417   [(set_attr "type" "arith_media")
1418    (set_attr "highpart" "ignore")])
1419
1420 (define_insn "adddi3z_media"
1421   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1422         (zero_extend:DI
1423          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1424                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1425   "TARGET_SHMEDIA"
1426   "addz.l       %1, %N2, %0"
1427   [(set_attr "type" "arith_media")
1428    (set_attr "highpart" "ignore")])
1429
1430 (define_insn "adddi3_compact"
1431   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1432         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1433                  (match_operand:DI 2 "arith_reg_operand" "r")))
1434    (clobber (reg:SI T_REG))]
1435   "TARGET_SH1"
1436   "#"
1437   [(set_attr "length" "6")])
1438
1439 (define_split
1440   [(set (match_operand:DI 0 "arith_reg_dest" "")
1441         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1442                  (match_operand:DI 2 "arith_reg_operand" "")))
1443    (clobber (reg:SI T_REG))]
1444   "TARGET_SH1 && reload_completed"
1445   [(const_int 0)]
1446   "
1447 {
1448   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1449   high0 = gen_rtx_REG (SImode,
1450                        true_regnum (operands[0])
1451                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1452   high2 = gen_rtx_REG (SImode,
1453                        true_regnum (operands[2])
1454                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1455   emit_insn (gen_clrt ());
1456   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1457   emit_insn (gen_addc1 (high0, high0, high2));
1458   DONE;
1459 }")
1460
1461 (define_insn "addc"
1462   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1463         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1464                           (match_operand:SI 2 "arith_reg_operand" "r"))
1465                  (reg:SI T_REG)))
1466    (set (reg:SI T_REG)
1467         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1468   "TARGET_SH1"
1469   "addc %2,%0"
1470   [(set_attr "type" "arith")])
1471
1472 (define_insn "addc1"
1473   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1474         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1475                           (match_operand:SI 2 "arith_reg_operand" "r"))
1476                  (reg:SI T_REG)))
1477    (clobber (reg:SI T_REG))]
1478   "TARGET_SH1"
1479   "addc %2,%0"
1480   [(set_attr "type" "arith")])
1481
1482 (define_expand "addsi3"
1483   [(set (match_operand:SI 0 "arith_reg_operand" "")
1484         (plus:SI (match_operand:SI 1 "arith_operand" "")
1485                  (match_operand:SI 2 "arith_operand" "")))]
1486   ""
1487   "
1488 {
1489   if (TARGET_SHMEDIA)
1490     operands[1] = force_reg (SImode, operands[1]);
1491 }")
1492
1493 (define_insn "addsi3_media"
1494   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1495         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1496                  (match_operand:SI 2 "arith_operand" "r,I10")))]
1497   "TARGET_SHMEDIA"
1498   "@
1499         add.l   %1, %2, %0
1500         addi.l  %1, %2, %0"
1501   [(set_attr "type" "arith_media")
1502    (set_attr "highpart" "ignore")])
1503
1504 (define_insn "addsidi3_media"
1505   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1506         (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1507                                   "%r,r")
1508                                  (match_operand:SI 2 "arith_operand"
1509                                   "r,I10"))))]
1510   "TARGET_SHMEDIA"
1511   "@
1512         add.l   %1, %2, %0
1513         addi.l  %1, %2, %0"
1514   [(set_attr "type" "arith_media")
1515    (set_attr "highpart" "ignore")])
1516
1517 (define_insn "*addsi3_compact"
1518   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1519         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1520                  (match_operand:SI 2 "arith_operand" "rI08")))]
1521   "TARGET_SH1"
1522   "add  %2,%0"
1523   [(set_attr "type" "arith")])
1524
1525 ;; -------------------------------------------------------------------------
1526 ;; Subtraction instructions
1527 ;; -------------------------------------------------------------------------
1528
1529 (define_expand "subdi3"
1530   [(set (match_operand:DI 0 "arith_reg_operand" "")
1531         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1532                   (match_operand:DI 2 "arith_reg_operand" "")))]
1533   ""
1534   "
1535 {
1536   if (TARGET_SH1)
1537     {
1538       operands[1] = force_reg (DImode, operands[1]);
1539       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1540       DONE;
1541     }
1542 }")
1543
1544 (define_insn "*subdi3_media"
1545   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1546         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1547                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1548   "TARGET_SHMEDIA"
1549   "sub  %N1, %2, %0"
1550   [(set_attr "type" "arith_media")])
1551   
1552 (define_insn "subdisi3_media"
1553   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1554         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1555                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1556   "TARGET_SHMEDIA"
1557   "sub.l        %N1, %2, %0"
1558   [(set_attr "type" "arith_media")
1559    (set_attr "highpart" "ignore")])
1560
1561 (define_insn "subdi3_compact"
1562   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1563         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1564                  (match_operand:DI 2 "arith_reg_operand" "r")))
1565    (clobber (reg:SI T_REG))]
1566   "TARGET_SH1"
1567   "#"
1568   [(set_attr "length" "6")])
1569
1570 (define_split
1571   [(set (match_operand:DI 0 "arith_reg_dest" "")
1572         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1573                   (match_operand:DI 2 "arith_reg_operand" "")))
1574    (clobber (reg:SI T_REG))]
1575   "TARGET_SH1 && reload_completed"
1576   [(const_int 0)]
1577   "
1578 {
1579   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1580   high0 = gen_rtx_REG (SImode,
1581                        true_regnum (operands[0])
1582                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1583   high2 = gen_rtx_REG (SImode,
1584                        true_regnum (operands[2])
1585                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1586   emit_insn (gen_clrt ());
1587   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1588   emit_insn (gen_subc1 (high0, high0, high2));
1589   DONE;
1590 }")
1591
1592 (define_insn "subc"
1593   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1594         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1595                             (match_operand:SI 2 "arith_reg_operand" "r"))
1596                   (reg:SI T_REG)))
1597    (set (reg:SI T_REG)
1598         (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1599                           (reg:SI T_REG))
1600                 (match_dup 1)))]
1601   "TARGET_SH1"
1602   "subc %2,%0"
1603   [(set_attr "type" "arith")])
1604
1605 (define_insn "subc1"
1606   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1607         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1608                             (match_operand:SI 2 "arith_reg_operand" "r"))
1609                   (reg:SI T_REG)))
1610    (clobber (reg:SI T_REG))]
1611   "TARGET_SH1"
1612   "subc %2,%0"
1613   [(set_attr "type" "arith")])
1614
1615 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1616 ;; pattern for this case.  This helps multimedia applications that compute
1617 ;; the sum of absolute differences.
1618 (define_insn "mov_neg_si_t"
1619   [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1620   "TARGET_SH1"
1621   "subc %0,%0"
1622   [(set_attr "type" "arith")])
1623
1624 (define_insn "*subsi3_internal"
1625   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1626         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1627                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1628   "TARGET_SH1"
1629   "sub  %2,%0"
1630   [(set_attr "type" "arith")])
1631
1632 (define_insn_and_split "*subsi3_media"
1633   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1634         (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1635                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1636   "TARGET_SHMEDIA
1637    && (operands[1] != constm1_rtx
1638        || (GET_CODE (operands[2]) != TRUNCATE
1639            && GET_CODE (operands[2]) != SUBREG))"
1640   "sub.l        %N1, %2, %0"
1641   "operands[1] == constm1_rtx"
1642   [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1643   ""
1644   [(set_attr "type" "arith_media")
1645    (set_attr "highpart" "ignore")])
1646
1647 (define_split
1648   [(set (match_operand:SI 0 "arith_reg_dest" "")
1649         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1650                                                        "general_extend_operand"
1651                                                        "") 0)) 0)))]
1652   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1653   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1654    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1655   "")
1656
1657 (define_split
1658   [(set (match_operand:SI 0 "arith_reg_dest" "")
1659         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1660                                                        "general_extend_operand"
1661                                                        "") 0)) 3)))]
1662   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1663   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1664    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1665   "")
1666 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1667 ;; will sometimes save one instruction.  Otherwise we might get
1668 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1669 ;; are the same.
1670
1671 (define_expand "subsi3"
1672   [(set (match_operand:SI 0 "arith_reg_operand" "")
1673         (minus:SI (match_operand:SI 1 "arith_operand" "")
1674                   (match_operand:SI 2 "arith_reg_operand" "")))]
1675   ""
1676   "
1677 {
1678   if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1679     {
1680       emit_insn (gen_negsi2 (operands[0], operands[2]));
1681       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1682       DONE;
1683     }
1684   if (TARGET_SHMEDIA)
1685     {
1686       if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1687         FAIL;
1688       if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1689         operands[1] = force_reg (SImode, operands[1]);
1690     }
1691 }")
1692 \f
1693 ;; -------------------------------------------------------------------------
1694 ;; Division instructions
1695 ;; -------------------------------------------------------------------------
1696
1697 ;; We take advantage of the library routines which don't clobber as many
1698 ;; registers as a normal function call would.
1699
1700 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1701 ;; also has an effect on the register that holds the address of the sfunc.
1702 ;; To make this work, we have an extra dummy insn that shows the use
1703 ;; of this register for reorg.
1704
1705 (define_insn "use_sfunc_addr"
1706   [(set (reg:SI PR_REG)
1707         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1708   "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1709   ""
1710   [(set_attr "length" "0")])
1711
1712 (define_insn "udivsi3_sh2a"
1713   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1714         (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1715                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1716   "TARGET_SH2A"
1717   "divu %2,%1"
1718   [(set_attr "type" "arith")
1719    (set_attr "in_delay_slot" "no")])
1720
1721 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1722 ;; hard register 0.  If we used hard register 0, then the next instruction
1723 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1724 ;; gets allocated to a stack slot that needs its address reloaded, then
1725 ;; there is nothing to prevent reload from using r0 to reload the address.
1726 ;; This reload would clobber the value in r0 we are trying to store.
1727 ;; If we let reload allocate r0, then this problem can never happen.
1728
1729 (define_insn "udivsi3_i1"
1730   [(set (match_operand:SI 0 "register_operand" "=z")
1731         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1732    (clobber (reg:SI T_REG))
1733    (clobber (reg:SI PR_REG))
1734    (clobber (reg:SI R4_REG))
1735    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1736   "TARGET_SH1 && ! TARGET_SH4"
1737   "jsr  @%1%#"
1738   [(set_attr "type" "sfunc")
1739    (set_attr "needs_delay_slot" "yes")])
1740
1741 ; Since shmedia-nofpu code could be linked against shcompact code, and
1742 ; the udivsi3 libcall has the same name, we must consider all registers
1743 ; clobbered that are in the union of the registers clobbered by the
1744 ; shmedia and the shcompact implementation.  Note, if the shcompact
1745 ; implementation actually used shcompact code, we'd need to clobber
1746 ; also r23 and fr23.
1747 (define_insn "udivsi3_i1_media"
1748   [(set (match_operand:SI 0 "register_operand" "=z")
1749         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1750    (clobber (reg:SI T_MEDIA_REG))
1751    (clobber (reg:SI PR_MEDIA_REG))
1752    (clobber (reg:SI R20_REG))
1753    (clobber (reg:SI R21_REG))
1754    (clobber (reg:SI R22_REG))
1755    (clobber (reg:DI TR0_REG))
1756    (clobber (reg:DI TR1_REG))
1757    (clobber (reg:DI TR2_REG))
1758    (use (match_operand 1 "target_operand" "b"))]
1759   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1760   "blink        %1, r18"
1761   [(set_attr "type" "sfunc")
1762    (set_attr "needs_delay_slot" "yes")])
1763
1764 (define_expand "udivsi3_i4_media"
1765   [(set (match_dup 3)
1766         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1767    (set (match_dup 4)
1768         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1769    (set (match_dup 5) (float:DF (match_dup 3)))
1770    (set (match_dup 6) (float:DF (match_dup 4)))
1771    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1772    (set (match_dup 8) (fix:DI (match_dup 7)))
1773    (set (match_operand:SI 0 "register_operand" "")
1774         (truncate:SI (match_dup 8)))]
1775   "TARGET_SHMEDIA_FPU"
1776   "
1777 {
1778   operands[3] = gen_reg_rtx (DImode);
1779   operands[4] = gen_reg_rtx (DImode);
1780   operands[5] = gen_reg_rtx (DFmode);
1781   operands[6] = gen_reg_rtx (DFmode);
1782   operands[7] = gen_reg_rtx (DFmode);
1783   operands[8] = gen_reg_rtx (DImode);
1784 }")
1785
1786 (define_insn "udivsi3_i4"
1787   [(set (match_operand:SI 0 "register_operand" "=y")
1788         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1789    (clobber (reg:SI T_REG))
1790    (clobber (reg:SI PR_REG))
1791    (clobber (reg:DF DR0_REG))
1792    (clobber (reg:DF DR2_REG))
1793    (clobber (reg:DF DR4_REG))
1794    (clobber (reg:SI R0_REG))
1795    (clobber (reg:SI R1_REG))
1796    (clobber (reg:SI R4_REG))
1797    (clobber (reg:SI R5_REG))
1798    (use (reg:PSI FPSCR_REG))
1799    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1800   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1801   "jsr  @%1%#"
1802   [(set_attr "type" "sfunc")
1803    (set_attr "fp_mode" "double")
1804    (set_attr "needs_delay_slot" "yes")])
1805
1806 (define_insn "udivsi3_i4_single"
1807   [(set (match_operand:SI 0 "register_operand" "=y")
1808         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1809    (clobber (reg:SI T_REG))
1810    (clobber (reg:SI PR_REG))
1811    (clobber (reg:DF DR0_REG))
1812    (clobber (reg:DF DR2_REG))
1813    (clobber (reg:DF DR4_REG))
1814    (clobber (reg:SI R0_REG))
1815    (clobber (reg:SI R1_REG))
1816    (clobber (reg:SI R4_REG))
1817    (clobber (reg:SI R5_REG))
1818    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1819   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1820   "jsr  @%1%#"
1821   [(set_attr "type" "sfunc")
1822    (set_attr "needs_delay_slot" "yes")])
1823
1824 (define_insn "udivsi3_i4_int"
1825   [(set (match_operand:SI 0 "register_operand" "=z")
1826         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1827    (clobber (reg:SI T_REG))
1828    (clobber (reg:SI R1_REG))
1829    (clobber (reg:SI PR_REG))
1830    (clobber (reg:SI MACH_REG))
1831    (clobber (reg:SI MACL_REG))
1832    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1833   "TARGET_SH1"
1834   "jsr  @%1%#"
1835   [(set_attr "type" "sfunc")
1836    (set_attr "needs_delay_slot" "yes")])
1837
1838
1839 (define_expand "udivsi3"
1840   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1841    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1842    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1843    (parallel [(set (match_operand:SI 0 "register_operand" "")
1844                    (udiv:SI (reg:SI R4_REG)
1845                             (reg:SI R5_REG)))
1846               (clobber (reg:SI T_REG))
1847               (clobber (reg:SI PR_REG))
1848               (clobber (reg:SI R4_REG))
1849               (use (match_dup 3))])]
1850   ""
1851   "
1852 {
1853   rtx first, last;
1854
1855   operands[3] = gen_reg_rtx (Pmode);
1856   /* Emit the move of the address to a pseudo outside of the libcall.  */
1857   if (TARGET_DIVIDE_CALL_TABLE)
1858     {
1859       /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1860          that causes problems when the divide code is supposed to come from a
1861          separate library.  Division by zero is undefined, so dividing 1 can be
1862          implemented by comparing with the divisor.  */
1863       if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1864         {
1865           emit_insn (gen_cmpsi (operands[1], operands[2]));
1866           emit_insn (gen_sgeu (operands[0]));
1867           DONE;
1868         }
1869       else if (operands[2] == const0_rtx)
1870         {
1871           emit_move_insn (operands[0], operands[2]);
1872           DONE;
1873         }
1874       function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1875       last = gen_udivsi3_i4_int (operands[0], operands[3]);
1876     }
1877   else if (TARGET_DIVIDE_CALL_FP)
1878     {
1879       function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1880       if (TARGET_FPU_SINGLE)
1881         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1882       else
1883         last = gen_udivsi3_i4 (operands[0], operands[3]);
1884     }
1885   else if (TARGET_SHMEDIA_FPU)
1886     {
1887       operands[1] = force_reg (SImode, operands[1]);
1888       operands[2] = force_reg (SImode, operands[2]);
1889       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1890       DONE;
1891     }
1892   else if (TARGET_SH2A)
1893     {
1894       operands[1] = force_reg (SImode, operands[1]);
1895       operands[2] = force_reg (SImode, operands[2]);
1896       emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1897       DONE;
1898     }
1899   else if (TARGET_SH5)
1900     {
1901       function_symbol (operands[3],
1902                        TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1903                        SFUNC_STATIC);
1904
1905       if (TARGET_SHMEDIA)
1906         last = gen_udivsi3_i1_media (operands[0], operands[3]);
1907       else if (TARGET_FPU_ANY)
1908         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1909       else
1910         last = gen_udivsi3_i1 (operands[0], operands[3]);
1911     }
1912   else
1913     {
1914       function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1915       last = gen_udivsi3_i1 (operands[0], operands[3]);
1916     }
1917   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1918   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1919   last = emit_insn (last);
1920   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1921      invariant code motion can move it.  */
1922   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1923   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1924   DONE;
1925 }")
1926
1927 (define_insn "divsi3_sh2a"
1928   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1929         (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1930                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1931   "TARGET_SH2A"
1932   "divs %2,%1"
1933   [(set_attr "type" "arith")
1934    (set_attr "in_delay_slot" "no")])
1935
1936 (define_insn "divsi3_i1"
1937   [(set (match_operand:SI 0 "register_operand" "=z")
1938         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1939    (clobber (reg:SI T_REG))
1940    (clobber (reg:SI PR_REG))
1941    (clobber (reg:SI R1_REG))
1942    (clobber (reg:SI R2_REG))
1943    (clobber (reg:SI R3_REG))
1944    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1945   "TARGET_SH1 && ! TARGET_SH4"
1946   "jsr  @%1%#"
1947   [(set_attr "type" "sfunc")
1948    (set_attr "needs_delay_slot" "yes")])
1949
1950 (define_insn "divsi3_i1_media"
1951   [(set (match_operand:SI 0 "register_operand" "=z")
1952         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1953    (clobber (reg:SI T_MEDIA_REG))
1954    (clobber (reg:SI PR_MEDIA_REG))
1955    (clobber (reg:SI R1_REG))
1956    (clobber (reg:SI R20_REG))
1957    (clobber (reg:SI R21_REG))
1958    (clobber (reg:SI TR0_REG))
1959    (use (match_operand 1 "target_operand" "b"))]
1960   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1961   "blink        %1, r18"
1962   [(set_attr "type" "sfunc")])
1963
1964 (define_insn "divsi3_media_2"
1965   [(set (match_operand:SI 0 "register_operand" "=z")
1966         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1967    (clobber (reg:SI T_MEDIA_REG))
1968    (clobber (reg:SI PR_MEDIA_REG))
1969    (clobber (reg:SI R1_REG))
1970    (clobber (reg:SI R21_REG))
1971    (clobber (reg:SI TR0_REG))
1972    (use (reg:SI R20_REG))
1973    (use (match_operand 1 "target_operand" "b"))]
1974   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1975   "blink        %1, r18"
1976   [(set_attr "type" "sfunc")])
1977
1978 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1979 ;; hard reg clobbers and data dependencies that we need when we want
1980 ;; to rematerialize the division into a call.
1981 (define_insn_and_split "divsi_inv_call"
1982   [(set (match_operand:SI 0 "register_operand" "=r")
1983         (div:SI (match_operand:SI 1 "register_operand" "r")
1984                 (match_operand:SI 2 "register_operand" "r")))
1985    (clobber (reg:SI R4_REG))
1986    (clobber (reg:SI R5_REG))
1987    (clobber (reg:SI T_MEDIA_REG))
1988    (clobber (reg:SI PR_MEDIA_REG))
1989    (clobber (reg:SI R1_REG))
1990    (clobber (reg:SI R21_REG))
1991    (clobber (reg:SI TR0_REG))
1992    (clobber (reg:SI R20_REG))
1993    (use (match_operand:SI 3 "register_operand" "r"))]
1994   "TARGET_SHMEDIA"
1995   "#"
1996   "&& (high_life_started || reload_completed)"
1997   [(set (match_dup 0) (match_dup 3))]
1998   ""
1999   [(set_attr "highpart" "must_split")])
2000
2001 ;; This is the combiner pattern for -mdiv=inv:call .
2002 (define_insn_and_split "*divsi_inv_call_combine"
2003   [(set (match_operand:SI 0 "register_operand" "=z")
2004         (div:SI (match_operand:SI 1 "register_operand" "r")
2005                 (match_operand:SI 2 "register_operand" "r")))
2006    (clobber (reg:SI R4_REG))
2007    (clobber (reg:SI R5_REG))
2008    (clobber (reg:SI T_MEDIA_REG))
2009    (clobber (reg:SI PR_MEDIA_REG))
2010    (clobber (reg:SI R1_REG))
2011    (clobber (reg:SI R21_REG))
2012    (clobber (reg:SI TR0_REG))
2013    (clobber (reg:SI R20_REG))
2014    (use (unspec:SI [(match_dup 1)
2015                     (match_operand:SI 3 "" "")
2016                     (unspec:SI [(match_operand:SI 4 "" "")
2017                                 (match_dup 3)
2018                                 (match_operand:DI 5 "" "")]
2019                      UNSPEC_DIV_INV_M2)
2020                     (match_operand:DI 6 "" "")
2021                     (const_int 0)
2022                     (const_int 0)]
2023          UNSPEC_DIV_INV_M3))]
2024   "TARGET_SHMEDIA"
2025   "#"
2026   "&& (high_life_started || reload_completed)"
2027   [(pc)]
2028   "
2029 {
2030   const char *name = sh_divsi3_libfunc;
2031   enum sh_function_kind kind = SFUNC_GOT;
2032   rtx sym;
2033
2034   emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2035   emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2036   while (TARGET_DIVIDE_INV_CALL2)
2037     {
2038       rtx x = operands[3];
2039
2040       if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2041         break;
2042       x = XVECEXP (x, 0, 0);
2043       name = \"__sdivsi3_2\";
2044       kind = SFUNC_STATIC;
2045       emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2046       break;
2047     }
2048   sym = function_symbol (NULL, name, kind);
2049   emit_insn (gen_divsi3_media_2 (operands[0], sym));
2050   DONE;
2051 }"
2052   [(set_attr "highpart" "must_split")])
2053
2054 (define_expand "divsi3_i4_media"
2055   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2056    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2057    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2058    (set (match_operand:SI 0 "register_operand" "=r")
2059         (fix:SI (match_dup 5)))]
2060   "TARGET_SHMEDIA_FPU"
2061   "
2062 {
2063   operands[3] = gen_reg_rtx (DFmode);
2064   operands[4] = gen_reg_rtx (DFmode);
2065   operands[5] = gen_reg_rtx (DFmode);
2066 }")
2067
2068 (define_insn "divsi3_i4"
2069   [(set (match_operand:SI 0 "register_operand" "=y")
2070         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2071    (clobber (reg:SI PR_REG))
2072    (clobber (reg:DF DR0_REG))
2073    (clobber (reg:DF DR2_REG))
2074    (use (reg:PSI FPSCR_REG))
2075    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2076   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
2077   "jsr  @%1%#"
2078   [(set_attr "type" "sfunc")
2079    (set_attr "fp_mode" "double")
2080    (set_attr "needs_delay_slot" "yes")])
2081
2082 (define_insn "divsi3_i4_single"
2083   [(set (match_operand:SI 0 "register_operand" "=y")
2084         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2085    (clobber (reg:SI PR_REG))
2086    (clobber (reg:DF DR0_REG))
2087    (clobber (reg:DF DR2_REG))
2088    (clobber (reg:SI R2_REG))
2089    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2090   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
2091   "jsr  @%1%#"
2092   [(set_attr "type" "sfunc")
2093    (set_attr "needs_delay_slot" "yes")])
2094
2095 (define_insn "divsi3_i4_int"
2096   [(set (match_operand:SI 0 "register_operand" "=z")
2097         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2098    (clobber (reg:SI T_REG))
2099    (clobber (reg:SI PR_REG))
2100    (clobber (reg:SI R1_REG))
2101    (clobber (reg:SI MACH_REG))
2102    (clobber (reg:SI MACL_REG))
2103    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2104   "TARGET_SH1"
2105   "jsr  @%1%#"
2106   [(set_attr "type" "sfunc")
2107    (set_attr "needs_delay_slot" "yes")])
2108
2109 (define_expand "divsi3"
2110   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2111    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2112    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2113    (parallel [(set (match_operand:SI 0 "register_operand" "")
2114                    (div:SI (reg:SI R4_REG)
2115                            (reg:SI R5_REG)))
2116               (clobber (reg:SI T_REG))
2117               (clobber (reg:SI PR_REG))
2118               (clobber (reg:SI R1_REG))
2119               (clobber (reg:SI R2_REG))
2120               (clobber (reg:SI R3_REG))
2121               (use (match_dup 3))])]
2122   ""
2123   "
2124 {
2125   rtx first, last;
2126
2127   operands[3] = gen_reg_rtx (Pmode);
2128   /* Emit the move of the address to a pseudo outside of the libcall.  */
2129   if (TARGET_DIVIDE_CALL_TABLE)
2130     {
2131       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2132       last = gen_divsi3_i4_int (operands[0], operands[3]);
2133     }
2134   else if (TARGET_DIVIDE_CALL_FP)
2135     {
2136       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2137       if (TARGET_FPU_SINGLE)
2138         last = gen_divsi3_i4_single (operands[0], operands[3]);
2139       else
2140         last = gen_divsi3_i4 (operands[0], operands[3]);
2141     }
2142   else if (TARGET_SH2A)
2143     {
2144       operands[1] = force_reg (SImode, operands[1]);
2145       operands[2] = force_reg (SImode, operands[2]);
2146       emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2147       DONE;
2148     }
2149   else if (TARGET_DIVIDE_INV)
2150     {
2151       rtx dividend = operands[1];
2152       rtx divisor = operands[2];
2153       rtx tab_base;
2154       rtx nsb_res = gen_reg_rtx (DImode);
2155       rtx norm64 = gen_reg_rtx (DImode);
2156       rtx tab_ix = gen_reg_rtx (DImode);
2157       rtx norm32 = gen_reg_rtx (SImode);
2158       rtx i92 = force_reg (DImode, GEN_INT (92));
2159       rtx scratch0a = gen_reg_rtx (DImode);
2160       rtx scratch0b = gen_reg_rtx (DImode);
2161       rtx inv0 = gen_reg_rtx (SImode);
2162       rtx scratch1a = gen_reg_rtx (DImode);
2163       rtx scratch1b = gen_reg_rtx (DImode);
2164       rtx shift = gen_reg_rtx (DImode);
2165       rtx i2p27, i43;
2166       rtx inv1 = gen_reg_rtx (SImode);
2167       rtx scratch2a = gen_reg_rtx (DImode);
2168       rtx scratch2b = gen_reg_rtx (SImode);
2169       rtx inv2 = gen_reg_rtx (SImode);
2170       rtx scratch3a = gen_reg_rtx (DImode);
2171       rtx scratch3b = gen_reg_rtx (DImode);
2172       rtx scratch3c = gen_reg_rtx (DImode);
2173       rtx scratch3d = gen_reg_rtx (SImode);
2174       rtx scratch3e = gen_reg_rtx (DImode);
2175       rtx result = gen_reg_rtx (SImode);
2176
2177       if (! arith_reg_or_0_operand (dividend, SImode))
2178         dividend = force_reg (SImode, dividend);
2179       if (! arith_reg_operand (divisor, SImode))
2180         divisor = force_reg (SImode, divisor);
2181       if (flag_pic && Pmode != DImode)
2182         {
2183           tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2184           tab_base = gen_datalabel_ref (tab_base);
2185           tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2186         }
2187       else
2188         {
2189           tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2190           tab_base = gen_datalabel_ref (tab_base);
2191           tab_base = force_reg (DImode, tab_base);
2192         }
2193       if (TARGET_DIVIDE_INV20U)
2194         i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2195       else
2196         i2p27 = GEN_INT (0);
2197       if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2198         i43 = force_reg (DImode, GEN_INT (43));
2199       else
2200         i43 = GEN_INT (0);
2201       emit_insn (gen_nsbdi (nsb_res,
2202                             simplify_gen_subreg (DImode, divisor, SImode, 0)));
2203       emit_insn (gen_ashldi3_media (norm64,
2204                                     gen_rtx_SUBREG (DImode, divisor, 0),
2205                                     nsb_res));
2206       emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2207       emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2208       emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2209                                    inv0, scratch0a, scratch0b,
2210                                    scratch1a, scratch1b));
2211       emit_insn (gen_subdi3 (shift, i92, nsb_res));
2212       emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2213                                    scratch2a));
2214       emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2215                                    i2p27, i43,
2216                                    scratch3a, scratch3b, scratch3c,
2217                                    scratch2a, scratch2b, scratch3d, scratch3e));
2218       if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2219         emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2220       else if (TARGET_DIVIDE_INV_FP)
2221         emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2222                                      gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2223                                      gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2224                                      gen_reg_rtx (DFmode)));
2225       else
2226         emit_move_insn (operands[0], result);
2227       DONE;
2228     }
2229   else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2230     {
2231       operands[1] = force_reg (SImode, operands[1]);
2232       operands[2] = force_reg (SImode, operands[2]);
2233       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2234       DONE;
2235     }
2236   else if (TARGET_SH5)
2237     {
2238       if (TARGET_DIVIDE_CALL2)
2239         {
2240           rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2241           tab_base = gen_datalabel_ref (tab_base);
2242           emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2243         }
2244       if (TARGET_FPU_ANY && TARGET_SH1)
2245         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2246       else if (TARGET_DIVIDE_CALL2)
2247         function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2248       else
2249         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2250
2251       if (TARGET_SHMEDIA)
2252         last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2253                 (operands[0], operands[3]));
2254       else if (TARGET_FPU_ANY)
2255         last = gen_divsi3_i4_single (operands[0], operands[3]);
2256       else
2257         last = gen_divsi3_i1 (operands[0], operands[3]);
2258     }
2259   else
2260     {
2261       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2262       last = gen_divsi3_i1 (operands[0], operands[3]);
2263     }
2264   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2265   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2266   last = emit_insn (last);
2267   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2268      invariant code motion can move it.  */
2269   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2270   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2271   DONE;
2272 }")
2273
2274 ;; operands: scratch, tab_base, tab_ix
2275 ;; These are unspecs because we could generate an indexed addressing mode
2276 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2277 ;; confuse reload.  See PR27117.
2278
2279 (define_insn "divsi_inv_qitable"
2280   [(set (match_operand:DI 0 "register_operand" "=r")
2281         (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2282                                     (match_operand:DI 2 "register_operand" "r")]
2283                          UNSPEC_DIV_INV_TABLE)))]
2284   "TARGET_SHMEDIA"
2285   "@
2286         ldx.ub  %1, %2, %0"
2287   [(set_attr "type" "load_media")
2288    (set_attr "highpart" "user")])
2289
2290 ;; operands: scratch, tab_base, tab_ix
2291 (define_insn "divsi_inv_hitable"
2292   [(set (match_operand:DI 0 "register_operand" "=r")
2293         (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2294                                     (match_operand:DI 2 "register_operand" "r")]
2295                          UNSPEC_DIV_INV_TABLE)))]
2296   "TARGET_SHMEDIA"
2297   "@
2298         ldx.w   %1, %2, %0"
2299   [(set_attr "type" "load_media")
2300    (set_attr "highpart" "user")])
2301
2302 ;; operands: inv0, tab_base, tab_ix, norm32
2303 ;; scratch equiv in sdivsi3_2: r19, r21
2304 (define_expand "divsi_inv_m0"
2305   [(set (match_operand:SI 0 "register_operand" "=r")
2306         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2307                     (match_operand:DI 2 "register_operand" "r")
2308                     (match_operand:SI 3 "register_operand" "r")]
2309          UNSPEC_DIV_INV_M0))
2310    (clobber (match_operand:DI 4 "register_operand" "=r"))
2311    (clobber (match_operand:DI 5 "register_operand" "=r"))]
2312   "TARGET_SHMEDIA"
2313   "
2314 {
2315 /*
2316 tab_base: r20
2317 tab_ix: r21
2318 norm32: r25
2319  ldx.ub r20, r21, r19 // u0.8
2320  shlli r21, 1, r21
2321  muls.l r25, r19, r19 // s2.38
2322  ldx.w r20, r21, r21  // s2.14
2323  shari r19, 24, r19   // truncate to s2.14
2324  sub r21, r19, r19    // some 11 bit inverse in s1.14
2325 */
2326
2327   rtx inv0 = operands[0];
2328   rtx tab_base = operands[1];
2329   rtx tab_ix = operands[2];
2330   rtx norm32 = operands[3];
2331   rtx scratch0 = operands[4];
2332   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2333   rtx scratch1 = operands[5];
2334
2335   emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2336   emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2337   emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2338   emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2339   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2340   emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2341   DONE;
2342 }")
2343
2344 ;; operands: inv1, tab_base, tab_ix, norm32
2345 (define_insn_and_split "divsi_inv_m1"
2346   [(set (match_operand:SI 0 "register_operand" "=r")
2347         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2348                     (match_operand:DI 2 "register_operand" "r")
2349                     (match_operand:SI 3 "register_operand" "r")]
2350          UNSPEC_DIV_INV_M1))
2351    (clobber (match_operand:SI 4 "register_operand" "=r"))
2352    (clobber (match_operand:DI 5 "register_operand" "=r"))
2353    (clobber (match_operand:DI 6 "register_operand" "=r"))
2354    (clobber (match_operand:DI 7 "register_operand" "=r"))
2355    (clobber (match_operand:DI 8 "register_operand" "=r"))]
2356   "TARGET_SHMEDIA"
2357   "#"
2358   "&& no_new_pseudos"
2359   [(pc)]
2360   "
2361 {
2362 /* inv0: r19
2363  muls.l r19, r19, r18 // u0.28
2364  muls.l r25, r18, r18 // s2.58
2365  shlli r19, 45, r0    // multiply by two and convert to s2.58
2366  sub r0, r18, r18
2367  shari r18, 28, r18   // some 18 bit inverse in s1.30
2368 */
2369
2370   rtx inv1 = operands[0];
2371   rtx tab_base = operands[1];
2372   rtx tab_ix = operands[2];
2373   rtx norm32 = operands[3];
2374   rtx inv0 = operands[4];
2375   rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2376   rtx scratch0a = operands[5];
2377   rtx scratch0b = operands[6];
2378   rtx scratch0 = operands[7];
2379   rtx scratch1 = operands[8];
2380   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2381
2382   emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2383                                scratch0a, scratch0b));
2384   emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2385   emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2386   emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2387   emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2388   emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2389   DONE;
2390 }")
2391
2392 ;; operands: inv2, norm32, inv1, i92
2393 (define_insn_and_split "divsi_inv_m2"
2394   [(set (match_operand:SI 0 "register_operand" "=r")
2395         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2396                     (match_operand:SI 2 "register_operand" "r")
2397                     (match_operand:DI 3 "register_operand" "r")]
2398          UNSPEC_DIV_INV_M2))
2399    (clobber (match_operand:DI 4 "register_operand" "=r"))]
2400   "TARGET_SHMEDIA"
2401   "#"
2402   "&& no_new_pseudos"
2403   [(pc)]
2404   "
2405 {
2406 /*
2407  muls.l r18, r25, r0  // s2.60
2408  shari r0, 16, r0     // s-16.44
2409   sub
2410  muls.l r0, r18, r19  // s-16.74
2411  shari r19, 30, r19   // s-16.44
2412 */
2413   rtx inv2 = operands[0];
2414   rtx norm32 = operands[1];
2415   rtx inv1 = operands[2];
2416   rtx i92 = operands[3];
2417   rtx scratch0 = operands[4];
2418   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2419
2420   emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2421   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2422   emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2423   emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2424   emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2425   DONE;
2426 }")
2427
2428 (define_insn_and_split "divsi_inv_m3"
2429   [(set (match_operand:SI 0 "register_operand" "=r")
2430         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2431                     (match_operand:SI 2 "register_operand" "r")
2432                     (match_operand:SI 3 "register_operand" "r")
2433                     (match_operand:DI 4 "register_operand" "r")
2434                     (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2435                     (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2436          UNSPEC_DIV_INV_M3))
2437    (clobber (match_operand:DI 7 "register_operand" "=r"))
2438    (clobber (match_operand:DI 8 "register_operand" "=r"))
2439    (clobber (match_operand:DI 9 "register_operand" "=r"))
2440    (clobber (match_operand:DI 10 "register_operand" "=r"))
2441    (clobber (match_operand:SI 11 "register_operand" "=r"))
2442    (clobber (match_operand:SI 12 "register_operand" "=r"))
2443    (clobber (match_operand:DI 13 "register_operand" "=r"))]
2444   "TARGET_SHMEDIA"
2445   "#"
2446   "&& no_new_pseudos"
2447   [(pc)]
2448   "
2449 {
2450 /*
2451   r0: result  r1: shift  r4: dividend  r18: inv1  r19: inv2
2452   r0: scratch0  r19: scratch1 r21: scratch2
2453
2454   muls.l r18, r4, r25 // s32.30
2455  muls.l r19, r4, r19  // s15.30
2456  shari r25, 63, r21
2457   shari r19, 14, r19  // s18.-14
2458  sub r25, r19, r0
2459  shard r0, r1, r0
2460  sub r0, r21, r0
2461 */
2462
2463   rtx result = operands[0];
2464   rtx dividend = operands[1];
2465   rtx inv1 = operands[2];
2466   rtx inv2 = operands[3];
2467   rtx shift = operands[4];
2468   rtx scratch0 = operands[7];
2469   rtx scratch1 = operands[8];
2470   rtx scratch2 = operands[9];
2471
2472   emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2473   emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2474   emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2475   emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2476   emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2477   emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2478   emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2479   DONE;
2480 }")
2481
2482 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2483 ;; inv1: tab_base, tab_ix, norm32
2484 ;; inv2: norm32, inv1, i92
2485 (define_insn_and_split "divsi_inv_m1_3"
2486   [(set (match_operand:SI 0 "register_operand" "=r")
2487         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2488                     (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2489                                 (match_operand:DI 3 "register_operand" "r")
2490                                 (match_operand:SI 4 "register_operand" "r")]
2491                      UNSPEC_DIV_INV_M1)
2492                     (unspec:SI [(match_dup 4)
2493                                 (unspec:SI [(match_dup 2)
2494                                             (match_dup 3)
2495                                             (match_dup 4)] UNSPEC_DIV_INV_M1)
2496                                 (match_operand:SI 5 "" "")]
2497                      UNSPEC_DIV_INV_M2)
2498                     (match_operand:DI 6 "register_operand" "r")
2499                     (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2500                     (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2501          UNSPEC_DIV_INV_M3))
2502    (clobber (match_operand:DI 9 "register_operand" "=r"))
2503    (clobber (match_operand:DI 10 "register_operand" "=r"))
2504    (clobber (match_operand:DI 11 "register_operand" "=r"))
2505    (clobber (match_operand:DI 12 "register_operand" "=r"))
2506    (clobber (match_operand:SI 13 "register_operand" "=r"))
2507    (clobber (match_operand:SI 14 "register_operand" "=r"))
2508    (clobber (match_operand:DI 15 "register_operand" "=r"))]
2509   "TARGET_SHMEDIA
2510    && (TARGET_DIVIDE_INV_MINLAT
2511        || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2512   "#"
2513   "&& no_new_pseudos"
2514   [(pc)]
2515   "
2516 {
2517   rtx result = operands[0];
2518   rtx dividend = operands[1];
2519   rtx tab_base = operands[2];
2520   rtx tab_ix = operands[3];
2521   rtx norm32 = operands[4];
2522   /* rtx i92 = operands[5]; */
2523   rtx shift = operands[6];
2524   rtx i2p27 = operands[7];
2525   rtx i43 = operands[8];
2526   rtx scratch0 = operands[9];
2527   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2528   rtx scratch1 = operands[10];
2529   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2530   rtx scratch2 = operands[11];
2531   rtx scratch3 = operands[12];
2532   rtx scratch4 = operands[13];
2533   rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2534   rtx scratch5 = operands[14];
2535   rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2536   rtx scratch6 = operands[15];
2537
2538   emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2539                                scratch0, scratch1));
2540   /* inv0 == scratch4 */
2541   if (! TARGET_DIVIDE_INV20U)
2542     {
2543       emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2544       i2p27 = scratch0;
2545       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2546     }
2547   else
2548     {
2549       emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2550       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2551     }
2552   emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2553   emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2554   emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2555   /* inv1 == scratch4 */
2556
2557   if (TARGET_DIVIDE_INV_MINLAT)
2558     {
2559       emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2560       emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2561       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2562       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2563       emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2564       emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2565       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2566       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2567       emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2568       emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2569       emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2570     }
2571   else
2572     {
2573       rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2574       /* Use separate scratch regs for nsb and sign to allow scheduling.  */
2575       emit_insn (gen_nsbdi (scratch6,
2576                             simplify_gen_subreg (DImode, dividend, SImode, 0)));
2577       emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2578       emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2579       emit_insn (gen_divsi_inv20 (scratch2,
2580                                   norm32, scratch4, dividend,
2581                                   scratch6, scratch3, i43,
2582                                   /* scratch0 may be shared with i2p27.  */
2583                                   scratch0, scratch1, scratch5,
2584                                   label, label, i2p27));
2585     }
2586   emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2587   emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2588   DONE;
2589 }")
2590
2591 (define_insn "divsi_inv20"
2592   [(set (match_operand:DI 0 "register_operand" "=&r")
2593         (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2594                     (match_operand:SI 2 "register_operand" "r")
2595                     (match_operand:SI 3 "register_operand" "r")
2596                     (match_operand:DI 4 "register_operand" "r")
2597                     (match_operand:DI 5 "register_operand" "r")
2598                     (match_operand:DI 6 "register_operand" "r")
2599                     (match_operand:DI 12 "register_operand" "r")
2600                     (match_operand 10 "target_operand" "b")
2601                     (match_operand 11 "immediate_operand" "i")]
2602          UNSPEC_DIV_INV20))
2603    (clobber (match_operand:DI 7 "register_operand" "=&r"))
2604    (clobber (match_operand:DI 8 "register_operand" "=&r"))
2605    (clobber (match_operand:SI 9 "register_operand" "=r"))]
2606   "TARGET_SHMEDIA
2607    && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2608   "*
2609 {
2610 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2611              %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2612              %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2613              %10 label (tr), %11 label (imm)
2614
2615  muls.l inv1, norm32, scratch0  // s2.60
2616   muls.l inv1, dividend, result // s32.30
2617   xor i2p27, result_sign, round_scratch
2618  bge/u dividend_nsb, i43, tr.. (label)
2619  shari scratch0, 16, scratch0   // s-16.44
2620  muls.l sratch0_si, inv1, scratch0 // s-16.74
2621   sub result, round_scratch, result
2622   shari dividend, 14, scratch1   // s19.-14
2623  shari scratch0, 30, scratch0   // s-16.44
2624  muls.l scratch0, scratch1, round_scratch // s15.30
2625 label:
2626  sub result, round_scratch, result */
2627
2628   int likely = TARGET_DIVIDE_INV20L;
2629
2630   if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2631   output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2632   output_asm_insn (likely
2633                    ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2634                    : \"bge/u\t%4, %6, %10\", operands);
2635   output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2636   if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2637   output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2638   return (likely
2639           ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2640           : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2641 }")
2642
2643 (define_insn_and_split "divsi_inv_fp"
2644   [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2645         (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2646                 (match_operand:SI 2 "register_operand" "rf")))
2647    (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2648    (clobber (match_operand:SI 4 "register_operand" "=r"))
2649    (clobber (match_operand:SI 5 "register_operand" "=r"))
2650    (clobber (match_operand:DF 6 "register_operand" "=r"))
2651    (clobber (match_operand:DF 7 "register_operand" "=r"))
2652    (clobber (match_operand:DF 8 "register_operand" "=r"))]
2653   "TARGET_SHMEDIA_FPU"
2654   "#"
2655   "&& (high_life_started || reload_completed)"
2656   [(set (match_dup 0) (match_dup 3))]
2657   ""
2658   [(set_attr "highpart" "must_split")])
2659
2660 ;; If a matching group of divide-by-inverse instructions is in the same
2661 ;; basic block after gcse & loop optimizations, we want to transform them
2662 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2663 (define_insn_and_split "*divsi_inv_fp_combine"
2664   [(set (match_operand:SI 0 "register_operand" "=f")
2665         (div:SI (match_operand:SI 1 "register_operand" "f")
2666                 (match_operand:SI 2 "register_operand" "f")))
2667    (use (unspec:SI [(match_dup 1)
2668                     (match_operand:SI 3 "" "")
2669                     (unspec:SI [(match_operand:SI 4 "" "")
2670                                 (match_dup 3)
2671                                 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2672                     (match_operand:DI 6 "" "")
2673                     (const_int 0)
2674                     (const_int 0)] UNSPEC_DIV_INV_M3))
2675    (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2676    (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2677    (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2678    (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2679    (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2680   "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && no_new_pseudos"
2681   "#"
2682   "&& 1"
2683   [(set (match_dup 9) (float:DF (match_dup 1)))
2684    (set (match_dup 10) (float:DF (match_dup 2)))
2685    (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2686    (set (match_dup 8)
2687         (fix:SI (match_dup 11)))
2688    (set (match_dup 0) (match_dup 8))]
2689   "
2690 {
2691   if (! fp_arith_reg_operand (operands[1], SImode))
2692     {
2693       emit_move_insn (operands[7], operands[1]);
2694       operands[1] = operands[7];
2695     }
2696   if (! fp_arith_reg_operand (operands[2], SImode))
2697     {
2698       emit_move_insn (operands[8], operands[2]);
2699       operands[2] = operands[8];
2700     }
2701 }"
2702   [(set_attr "highpart" "must_split")])
2703 \f
2704 ;; -------------------------------------------------------------------------
2705 ;; Multiplication instructions
2706 ;; -------------------------------------------------------------------------
2707
2708 (define_insn "umulhisi3_i"
2709   [(set (reg:SI MACL_REG)
2710         (mult:SI (zero_extend:SI
2711                   (match_operand:HI 0 "arith_reg_operand" "r"))
2712                  (zero_extend:SI
2713                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2714   "TARGET_SH1"
2715   "mulu.w       %1,%0"
2716   [(set_attr "type" "smpy")])
2717
2718 (define_insn "mulhisi3_i"
2719   [(set (reg:SI MACL_REG)
2720         (mult:SI (sign_extend:SI
2721                   (match_operand:HI 0 "arith_reg_operand" "r"))
2722                  (sign_extend:SI
2723                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2724   "TARGET_SH1"
2725   "muls.w       %1,%0"
2726   [(set_attr "type" "smpy")])
2727
2728 (define_expand "mulhisi3"
2729   [(set (reg:SI MACL_REG)
2730         (mult:SI (sign_extend:SI
2731                   (match_operand:HI 1 "arith_reg_operand" ""))
2732                  (sign_extend:SI
2733                   (match_operand:HI 2 "arith_reg_operand" ""))))
2734    (set (match_operand:SI 0 "arith_reg_operand" "")
2735         (reg:SI MACL_REG))]
2736   "TARGET_SH1"
2737   "
2738 {
2739   rtx first, last;
2740
2741   first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2742   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2743   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2744      invariant code motion can move it.  */
2745   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2746   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2747   /* expand_binop can't find a suitable code in umul_widen_optab to
2748      make a REG_EQUAL note from, so make one here.
2749      See also smulsi3_highpart.
2750      ??? Alternatively, we could put this at the calling site of expand_binop,
2751      i.e. expand_expr.  */
2752   set_unique_reg_note (last, REG_EQUAL,
2753                        copy_rtx (SET_SRC (single_set (first))));
2754
2755   DONE;
2756 }")
2757
2758 (define_expand "umulhisi3"
2759   [(set (reg:SI MACL_REG)
2760         (mult:SI (zero_extend:SI
2761                   (match_operand:HI 1 "arith_reg_operand" ""))
2762                  (zero_extend:SI
2763                   (match_operand:HI 2 "arith_reg_operand" ""))))
2764    (set (match_operand:SI 0 "arith_reg_operand" "")
2765         (reg:SI MACL_REG))]
2766   "TARGET_SH1"
2767   "
2768 {
2769   rtx first, last;
2770
2771   first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2772   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2773   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2774      invariant code motion can move it.  */
2775   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2776   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2777   /* expand_binop can't find a suitable code in umul_widen_optab to
2778      make a REG_EQUAL note from, so make one here.
2779      See also smulsi3_highpart.
2780      ??? Alternatively, we could put this at the calling site of expand_binop,
2781      i.e. expand_expr.  */
2782   set_unique_reg_note (last, REG_EQUAL,
2783                        copy_rtx (SET_SRC (single_set (first))));
2784
2785   DONE;
2786 }")
2787
2788 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2789 ;; a call to a routine which clobbers known registers.
2790
2791 (define_insn ""
2792   [(set (match_operand:SI 1 "register_operand" "=z")
2793         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2794    (clobber (reg:SI MACL_REG))
2795    (clobber (reg:SI T_REG))
2796    (clobber (reg:SI PR_REG))
2797    (clobber (reg:SI R3_REG))
2798    (clobber (reg:SI R2_REG))
2799    (clobber (reg:SI R1_REG))
2800    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2801   "TARGET_SH1"
2802   "jsr  @%0%#"
2803   [(set_attr "type" "sfunc")
2804    (set_attr "needs_delay_slot" "yes")])
2805
2806 (define_expand "mulsi3_call"
2807   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2808    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2809    (parallel[(set (match_operand:SI 0 "register_operand" "")
2810                   (mult:SI (reg:SI R4_REG)
2811                            (reg:SI R5_REG)))
2812              (clobber (reg:SI MACL_REG))
2813              (clobber (reg:SI T_REG))
2814              (clobber (reg:SI PR_REG))
2815              (clobber (reg:SI R3_REG))
2816              (clobber (reg:SI R2_REG))
2817              (clobber (reg:SI R1_REG))
2818              (use (match_operand:SI 3 "register_operand" ""))])]
2819   "TARGET_SH1"
2820   "")
2821
2822 (define_insn "mul_r"
2823   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2824         (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2825                  (match_operand:SI 2 "arith_reg_operand" "z")))]
2826   "TARGET_SH2A"
2827   "mulr %2,%0"
2828   [(set_attr "type" "dmpy")])
2829
2830 (define_insn "mul_l"
2831   [(set (reg:SI MACL_REG)
2832         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2833                  (match_operand:SI 1 "arith_reg_operand" "r")))]
2834   "TARGET_SH2"
2835   "mul.l        %1,%0"
2836   [(set_attr "type" "dmpy")])
2837
2838 (define_expand "mulsi3"
2839   [(set (reg:SI MACL_REG)
2840         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
2841                   (match_operand:SI 2 "arith_reg_operand" "")))
2842    (set (match_operand:SI 0 "arith_reg_operand" "")
2843         (reg:SI MACL_REG))]
2844   "TARGET_SH1"
2845   "
2846 {
2847   rtx first, last;
2848
2849   if (!TARGET_SH2)
2850     {
2851       /* The address must be set outside the libcall,
2852          since it goes into a pseudo.  */
2853       rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2854       rtx addr = force_reg (SImode, sym);
2855       rtx insns = gen_mulsi3_call (operands[0], operands[1],
2856                                    operands[2], addr);
2857       first = insns;
2858       last = emit_insn (insns);
2859     }
2860   else
2861     {
2862       rtx macl = gen_rtx_REG (SImode, MACL_REG);
2863
2864       first = emit_insn (gen_mul_l (operands[1], operands[2]));
2865       /* consec_sets_giv can only recognize the first insn that sets a
2866          giv as the giv insn.  So we must tag this also with a REG_EQUAL
2867          note.  */
2868       last = emit_insn (gen_movsi_i ((operands[0]), macl));
2869     }
2870   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2871      invariant code motion can move it.  */
2872   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2873   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2874   DONE;
2875 }")
2876
2877 (define_insn "mulsidi3_i"
2878   [(set (reg:SI MACH_REG)
2879         (truncate:SI
2880          (lshiftrt:DI
2881           (mult:DI
2882            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2883            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2884           (const_int 32))))
2885    (set (reg:SI MACL_REG)
2886         (mult:SI (match_dup 0)
2887                  (match_dup 1)))]
2888   "TARGET_SH2"
2889   "dmuls.l      %1,%0"
2890   [(set_attr "type" "dmpy")])
2891
2892 (define_expand "mulsidi3"
2893   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2894         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2895                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2896   "TARGET_SH2 || TARGET_SHMEDIA"
2897   "
2898 {
2899   if (TARGET_SH2)
2900     {
2901        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2902                                         operands[2]));
2903        DONE;
2904     }
2905 }")
2906
2907 (define_insn "mulsidi3_media"
2908   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2909         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2910                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2911   "TARGET_SHMEDIA"
2912   "muls.l       %1, %2, %0"
2913   [(set_attr "type" "dmpy_media")
2914    (set_attr "highpart" "ignore")])
2915
2916 (define_insn "mulsidi3_compact"
2917   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2918         (mult:DI
2919          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2920          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2921    (clobber (reg:SI MACH_REG))
2922    (clobber (reg:SI MACL_REG))]
2923   "TARGET_SH2"
2924   "#")
2925
2926 (define_split
2927   [(set (match_operand:DI 0 "arith_reg_dest" "")
2928         (mult:DI
2929          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2930          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2931    (clobber (reg:SI MACH_REG))
2932    (clobber (reg:SI MACL_REG))]
2933   "TARGET_SH2"
2934   [(const_int 0)]
2935   "
2936 {
2937   rtx low_dst = gen_lowpart (SImode, operands[0]);
2938   rtx high_dst = gen_highpart (SImode, operands[0]);
2939
2940   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2941
2942   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2943   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2944   /* We need something to tag the possible REG_EQUAL notes on to.  */
2945   emit_move_insn (operands[0], operands[0]);
2946   DONE;
2947 }")
2948
2949 (define_insn "umulsidi3_i"
2950   [(set (reg:SI MACH_REG)
2951         (truncate:SI
2952          (lshiftrt:DI
2953           (mult:DI
2954            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2955            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2956           (const_int 32))))
2957    (set (reg:SI MACL_REG)
2958         (mult:SI (match_dup 0)
2959                  (match_dup 1)))]
2960   "TARGET_SH2"
2961   "dmulu.l      %1,%0"
2962   [(set_attr "type" "dmpy")])
2963
2964 (define_expand "umulsidi3"
2965   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2966         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2967                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2968   "TARGET_SH2 || TARGET_SHMEDIA"
2969   "
2970 {
2971   if (TARGET_SH2)
2972     {
2973        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2974                                          operands[2]));
2975        DONE;
2976     }
2977 }")
2978
2979 (define_insn "umulsidi3_media"
2980   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2981         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2982                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2983   "TARGET_SHMEDIA"
2984   "mulu.l       %1, %2, %0"
2985   [(set_attr "type" "dmpy_media")
2986    (set_attr "highpart" "ignore")])
2987
2988 (define_insn "umulsidi3_compact"
2989   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2990         (mult:DI
2991          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2992          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2993    (clobber (reg:SI MACH_REG))
2994    (clobber (reg:SI MACL_REG))]
2995   "TARGET_SH2"
2996   "#")
2997
2998 (define_split
2999   [(set (match_operand:DI 0 "arith_reg_dest" "")
3000         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3001                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
3002    (clobber (reg:SI MACH_REG))
3003    (clobber (reg:SI MACL_REG))]
3004   "TARGET_SH2"
3005   [(const_int 0)]
3006   "
3007 {
3008   rtx low_dst = gen_lowpart (SImode, operands[0]);
3009   rtx high_dst = gen_highpart (SImode, operands[0]);
3010
3011   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
3012
3013   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3014   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3015   /* We need something to tag the possible REG_EQUAL notes on to.  */
3016   emit_move_insn (operands[0], operands[0]);
3017   DONE;
3018 }")
3019
3020 (define_insn "smulsi3_highpart_i"
3021   [(set (reg:SI MACH_REG)
3022         (truncate:SI
3023          (lshiftrt:DI
3024           (mult:DI
3025            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3026            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3027           (const_int 32))))
3028    (clobber (reg:SI MACL_REG))]
3029   "TARGET_SH2"
3030   "dmuls.l      %1,%0"
3031   [(set_attr "type" "dmpy")])
3032
3033 (define_expand "smulsi3_highpart"
3034   [(parallel
3035     [(set (reg:SI MACH_REG)
3036           (truncate:SI
3037            (lshiftrt:DI
3038             (mult:DI
3039              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3040              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3041             (const_int 32))))
3042     (clobber (reg:SI MACL_REG))])
3043    (set (match_operand:SI 0 "arith_reg_operand" "")
3044         (reg:SI MACH_REG))]
3045   "TARGET_SH2"
3046   "
3047 {
3048   rtx first, last;
3049
3050   first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3051   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
3052   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
3053      invariant code motion can move it.  */
3054   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
3055   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
3056   /* expand_binop can't find a suitable code in mul_highpart_optab to
3057      make a REG_EQUAL note from, so make one here.
3058      See also {,u}mulhisi.
3059      ??? Alternatively, we could put this at the calling site of expand_binop,
3060      i.e. expand_mult_highpart.  */
3061   set_unique_reg_note (last, REG_EQUAL,
3062                        copy_rtx (SET_SRC (single_set (first))));
3063
3064   DONE;
3065 }")
3066
3067 (define_insn "umulsi3_highpart_i"
3068   [(set (reg:SI MACH_REG)
3069         (truncate:SI
3070          (lshiftrt:DI
3071           (mult:DI
3072            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3073            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3074           (const_int 32))))
3075    (clobber (reg:SI MACL_REG))]
3076   "TARGET_SH2"
3077   "dmulu.l      %1,%0"
3078   [(set_attr "type" "dmpy")])
3079
3080 (define_expand "umulsi3_highpart"
3081   [(parallel
3082     [(set (reg:SI MACH_REG)
3083           (truncate:SI
3084            (lshiftrt:DI
3085             (mult:DI
3086              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3087              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3088             (const_int 32))))
3089     (clobber (reg:SI MACL_REG))])
3090    (set (match_operand:SI 0 "arith_reg_operand" "")
3091         (reg:SI MACH_REG))]
3092   "TARGET_SH2"
3093   "
3094 {
3095   rtx first, last;
3096
3097   first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3098   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
3099   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
3100      invariant code motion can move it.  */
3101   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
3102   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
3103   DONE;
3104 }")
3105
3106 (define_insn_and_split "muldi3"
3107   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3108         (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3109                  (match_operand:DI 2 "arith_reg_operand" "r")))
3110    (clobber (match_scratch:DI 3 "=&r"))
3111    (clobber (match_scratch:DI 4 "=r"))]
3112   "TARGET_SHMEDIA"
3113   "#"
3114   "reload_completed"
3115   [(const_int 0)]
3116   "
3117 {
3118   rtx op3_v2si, op2_v2si;
3119
3120   op3_v2si = operands[3];
3121   if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3122     {
3123       op3_v2si = XEXP (op3_v2si, 0);
3124       op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3125     }
3126   op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3127   op2_v2si = operands[2];
3128   if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3129     {
3130       op2_v2si = XEXP (op2_v2si, 0);
3131       op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3132     }
3133   op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3134   emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3135   emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3136   emit_insn (gen_umulsidi3_media (operands[4],
3137                                  sh_gen_truncate (SImode, operands[1], 0),
3138                                  sh_gen_truncate (SImode, operands[2], 0)));
3139   emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3140   emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3141   emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3142   emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3143   DONE;
3144 }")
3145
3146 \f
3147 ;; -------------------------------------------------------------------------
3148 ;; Logical operations
3149 ;; -------------------------------------------------------------------------
3150
3151 (define_insn "*andsi3_compact"
3152   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3153         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3154                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3155   "TARGET_SH1"
3156   "and  %2,%0"
3157   [(set_attr "type" "arith")])
3158
3159 (define_insn "*andsi3_media"
3160   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3161         (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3162                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3163   "TARGET_SHMEDIA"
3164   "@
3165         and     %1, %2, %0
3166         andi    %1, %2, %0"
3167   [(set_attr "type" "arith_media")])
3168
3169 ;; If the constant is 255, then emit an extu.b instruction instead of an
3170 ;; and, since that will give better code.
3171
3172 (define_expand "andsi3"
3173   [(set (match_operand:SI 0 "arith_reg_operand" "")
3174         (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3175                 (match_operand:SI 2 "logical_operand" "")))]
3176   ""
3177   "
3178 {
3179   if (TARGET_SH1
3180       && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
3181     {
3182       emit_insn (gen_zero_extendqisi2 (operands[0],
3183                                        gen_lowpart (QImode, operands[1])));
3184       DONE;
3185     }
3186 }")
3187
3188 (define_insn_and_split "anddi3"
3189   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3190         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3191                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3192   "TARGET_SHMEDIA"
3193   "@
3194         and     %1, %2, %0
3195         andi    %1, %2, %0
3196         #"
3197   "reload_completed
3198    && ! logical_operand (operands[2], DImode)"
3199   [(const_int 0)]
3200   "
3201 {
3202   if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3203     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3204   else
3205     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3206   DONE;
3207 }"
3208   [(set_attr "type" "arith_media")])
3209
3210 (define_insn "andcsi3"
3211   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3212         (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3213                 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3214   "TARGET_SHMEDIA"
3215   "andc %1,%2,%0"
3216   [(set_attr "type" "arith_media")])
3217
3218 (define_insn "andcdi3"
3219   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3220         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3221                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3222   "TARGET_SHMEDIA"
3223   "andc %1,%2,%0"
3224   [(set_attr "type" "arith_media")])
3225
3226 (define_expand "iorsi3"
3227   [(set (match_operand:SI 0 "arith_reg_operand" "")
3228         (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3229                 (match_operand:SI 2 "logical_operand" "")))]
3230   ""
3231   "")
3232
3233 (define_insn "*iorsi3_compact"
3234   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3235         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3236                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3237   "TARGET_SH1"
3238   "or   %2,%0"
3239   [(set_attr "type" "arith")])
3240
3241 (define_insn "*iorsi3_media"
3242   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3243         (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3244                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3245   "TARGET_SHMEDIA"
3246   "@
3247         or      %1, %2, %0
3248         ori     %1, %2, %0"
3249   [(set_attr "type" "arith_media")])
3250
3251 (define_insn "iordi3"
3252   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3253         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3254                 (match_operand:DI 2 "logical_operand" "r,I10")))]
3255   "TARGET_SHMEDIA"
3256   "@
3257         or      %1, %2, %0
3258         ori     %1, %2, %0"
3259   [(set_attr "type" "arith_media")])
3260
3261 (define_insn_and_split "*logical_sidi3"
3262   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3263         (sign_extend:DI (match_operator:SI 3 "logical_operator"
3264                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3265                            (match_operand:SI 2 "logical_operand" "r,I10")])))]
3266   "TARGET_SHMEDIA"
3267   "#"
3268   "&& reload_completed"
3269   [(set (match_dup 0) (match_dup 3))]
3270   "
3271 {
3272   operands[3]
3273     = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3274                       simplify_gen_subreg (DImode, operands[1], SImode, 0),
3275                       simplify_gen_subreg (DImode, operands[2], SImode, 0));
3276 }")
3277
3278 (define_insn_and_split "*logical_sidisi3"
3279   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3280         (truncate:SI (sign_extend:DI
3281                         (match_operator:SI 3 "logical_operator"
3282                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3283                            (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3284   "TARGET_SHMEDIA"
3285   "#"
3286   "&& 1"
3287   [(set (match_dup 0) (match_dup 3))])
3288
3289 (define_insn_and_split "*logical_sidi3_2"
3290   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3291         (sign_extend:DI (truncate:SI (sign_extend:DI
3292                         (match_operator:SI 3 "logical_operator"
3293                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3294                            (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3295   "TARGET_SHMEDIA"
3296   "#"
3297   "&& 1"
3298   [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3299
3300 (define_expand "xorsi3"
3301   [(set (match_operand:SI 0 "arith_reg_operand" "")
3302         (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3303                 (match_operand:SI 2 "xor_operand" "")))]
3304   ""
3305   "")
3306
3307 (define_insn "*xorsi3_compact"
3308   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3309         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3310                 (match_operand:SI 2 "logical_operand" "K08,r")))]
3311   "TARGET_SH1"
3312   "xor  %2,%0"
3313   [(set_attr "type" "arith")])
3314
3315 (define_insn "*xorsi3_media"
3316   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3317         (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3318                 (match_operand:SI 2 "xor_operand" "r,I06")))]
3319   "TARGET_SHMEDIA"
3320   "@
3321         xor     %1, %2, %0
3322         xori    %1, %2, %0"
3323   [(set_attr "type" "arith_media")])
3324
3325 (define_insn "xordi3"
3326   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3327         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3328                 (match_operand:DI 2 "xor_operand" "r,I06")))]
3329   "TARGET_SHMEDIA"
3330   "@
3331         xor     %1, %2, %0
3332         xori    %1, %2, %0"
3333   [(set_attr "type" "arith_media")])
3334
3335 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3336 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3337 (define_split
3338   [(set (match_operand:DI 0 "arith_reg_dest" "")
3339         (sign_extend:DI (match_operator 4 "binary_logical_operator"
3340                           [(match_operand 1 "any_register_operand" "")
3341                            (match_operand 2 "any_register_operand" "")])))]
3342   "TARGET_SHMEDIA"
3343   [(set (match_dup 5) (match_dup 4))
3344    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3345 "
3346 {
3347   enum machine_mode inmode = GET_MODE (operands[1]);
3348   int offset = 0;
3349
3350   if (GET_CODE (operands[0]) == SUBREG)
3351     {
3352       offset = SUBREG_BYTE (operands[0]);
3353       operands[0] = SUBREG_REG (operands[0]);
3354     }
3355   gcc_assert (GET_CODE (operands[0]) == REG);
3356   if (! TARGET_LITTLE_ENDIAN)
3357     offset += 8 - GET_MODE_SIZE (inmode);
3358   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3359 }")
3360 \f
3361 ;; -------------------------------------------------------------------------
3362 ;; Shifts and rotates
3363 ;; -------------------------------------------------------------------------
3364
3365 (define_expand "rotldi3"
3366   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3367         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3368                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3369   "TARGET_SHMEDIA"
3370   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3371
3372 (define_insn "rotldi3_mextr"
3373   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3374         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3375                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3376   "TARGET_SHMEDIA"
3377   "*
3378 {
3379   static char templ[16];
3380
3381   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3382            8 - (int) (INTVAL (operands[2]) >> 3));
3383   return templ;
3384 }"
3385   [(set_attr "type" "arith_media")])
3386
3387 (define_expand "rotrdi3"
3388   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3389         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3390                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3391   "TARGET_SHMEDIA"
3392   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3393
3394 (define_insn "rotrdi3_mextr"
3395   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3396         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3397                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3398   "TARGET_SHMEDIA"
3399   "*
3400 {
3401   static char templ[16];
3402
3403   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3404   return templ;
3405 }"
3406   [(set_attr "type" "arith_media")])
3407
3408 (define_split
3409   [(set (match_operand:DI 0 "arith_reg_dest" "")
3410         (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3411                                          "ua_address_operand" "")))
3412                 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3413                            (const_int 8))))
3414    (clobber (match_operand:DI 3 "register_operand" ""))]
3415   "TARGET_SHMEDIA"
3416   [(match_dup 4) (match_dup 5)]
3417   "
3418 {
3419   operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3420                  (operands[3], operands[1]));
3421   operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3422                               GEN_INT (56), GEN_INT (8));
3423 }")
3424
3425 (define_insn "rotlsi3_1"
3426   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3427         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3428                    (const_int 1)))
3429    (set (reg:SI T_REG)
3430         (lshiftrt:SI (match_dup 1) (const_int 31)))]
3431   "TARGET_SH1"
3432   "rotl %0"
3433   [(set_attr "type" "arith")])
3434
3435 (define_insn "rotlsi3_31"
3436   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3437         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3438                    (const_int 31)))
3439    (clobber (reg:SI T_REG))]
3440   "TARGET_SH1"
3441   "rotr %0"
3442   [(set_attr "type" "arith")])
3443
3444 (define_insn "rotlsi3_16"
3445   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3446         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3447                    (const_int 16)))]
3448   "TARGET_SH1"
3449   "swap.w       %1,%0"
3450   [(set_attr "type" "arith")])
3451
3452 (define_expand "rotlsi3"
3453   [(set (match_operand:SI 0 "arith_reg_dest" "")
3454         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3455                    (match_operand:SI 2 "immediate_operand" "")))]
3456   "TARGET_SH1"
3457   "
3458 {
3459   static const char rot_tab[] = {
3460     000, 000, 000, 000, 000, 000, 010, 001,
3461     001, 001, 011, 013, 003, 003, 003, 003,
3462     003, 003, 003, 003, 003, 013, 012, 002,
3463     002, 002, 010, 000, 000, 000, 000, 000,
3464   };
3465
3466   int count, choice;
3467
3468   if (GET_CODE (operands[2]) != CONST_INT)
3469     FAIL;
3470   count = INTVAL (operands[2]);
3471   choice = rot_tab[count];
3472   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3473     FAIL;
3474   choice &= 7;
3475   switch (choice)
3476     {
3477     case 0:
3478       emit_move_insn (operands[0], operands[1]);
3479       count -= (count & 16) * 2;
3480       break;
3481     case 3:
3482      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3483      count -= 16;
3484      break;
3485     case 1:
3486     case 2:
3487       {
3488         rtx parts[2];
3489         parts[0] = gen_reg_rtx (SImode);
3490         parts[1] = gen_reg_rtx (SImode);
3491         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3492         emit_move_insn (parts[choice-1], operands[1]);
3493         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3494         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3495         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3496         count = (count & ~16) - 8;
3497       }
3498     }
3499
3500   for (; count > 0; count--)
3501     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3502   for (; count < 0; count++)
3503     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3504
3505   DONE;
3506 }")
3507
3508 (define_insn "*rotlhi3_8"
3509   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3510         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3511                    (const_int 8)))]
3512   "TARGET_SH1"
3513   "swap.b       %1,%0"
3514   [(set_attr "type" "arith")])
3515
3516 (define_expand "rotlhi3"
3517   [(set (match_operand:HI 0 "arith_reg_operand" "")
3518         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3519                    (match_operand:HI 2 "immediate_operand" "")))]
3520   "TARGET_SH1"
3521   "
3522 {
3523   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
3524     FAIL;
3525 }")
3526
3527 ;;
3528 ;; shift left
3529
3530 (define_insn "ashlsi3_sh2a"
3531   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3532         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3533                    (match_operand:SI 2 "arith_reg_operand" "r")))]
3534   "TARGET_SH2A"
3535   "shad %2,%0"
3536   [(set_attr "type" "arith")
3537    (set_attr "length" "4")])
3538
3539 ;; This pattern is used by init_expmed for computing the costs of shift
3540 ;; insns.
3541
3542 (define_insn_and_split "ashlsi3_std"
3543   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3544         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3545                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3546    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3547   "TARGET_SH3
3548    || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
3549        && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
3550   "@
3551    shld %2,%0
3552    add  %0,%0
3553    shll%O2      %0
3554    #"
3555   "TARGET_SH3
3556    && reload_completed
3557    && GET_CODE (operands[2]) == CONST_INT
3558    && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3559   [(set (match_dup 3) (match_dup 2))
3560    (parallel
3561     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3562      (clobber (match_dup 4))])]
3563   "operands[4] = gen_rtx_SCRATCH (SImode);"
3564   [(set_attr "length" "*,*,*,4")
3565    (set_attr "type" "dyn_shift,arith,arith,arith")])
3566
3567 (define_insn "ashlhi3_k"
3568   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3569         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3570                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
3571   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3572   "@
3573         add     %0,%0
3574         shll%O2 %0"
3575   [(set_attr "type" "arith")])
3576
3577 (define_insn "ashlsi3_n"
3578   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3579         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3580                    (match_operand:SI 2 "const_int_operand" "n")))
3581    (clobber (reg:SI T_REG))]
3582   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3583   "#"
3584   [(set (attr "length")
3585         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3586                (const_string "2")
3587                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3588                (const_string "4")
3589                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3590                (const_string "6")]
3591               (const_string "8")))
3592    (set_attr "type" "arith")])
3593
3594 (define_split
3595   [(set (match_operand:SI 0 "arith_reg_dest" "")
3596         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3597                    (match_operand:SI 2 "const_int_operand" "")))
3598    (clobber (reg:SI T_REG))]
3599   "TARGET_SH1 && reload_completed"
3600   [(use (reg:SI R0_REG))]
3601   "
3602 {
3603   gen_shifty_op (ASHIFT, operands);
3604   DONE;
3605 }")
3606
3607 (define_insn "ashlsi3_media"
3608   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3609         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3610                    (match_operand:SI 2 "shift_count_operand" "r,n")))]
3611   "TARGET_SHMEDIA"
3612   "@
3613         shlld.l %1, %2, %0
3614         shlli.l %1, %2, %0"
3615   [(set_attr "type" "arith_media")
3616    (set_attr "highpart" "ignore")])
3617
3618 (define_expand "ashlsi3"
3619   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3620                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3621                               (match_operand:SI 2 "nonmemory_operand" "")))
3622               (clobber (reg:SI T_REG))])]
3623   ""
3624   "
3625 {
3626   if (TARGET_SHMEDIA)
3627     {
3628       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3629       DONE;
3630     }
3631   if (GET_CODE (operands[2]) == CONST_INT
3632       && sh_dynamicalize_shift_p (operands[2]))
3633     operands[2] = force_reg (SImode, operands[2]);
3634   if (TARGET_SH3)
3635     {
3636       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3637       DONE;
3638     }
3639   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3640     FAIL;
3641 }")
3642
3643 (define_insn "*ashlhi3_n"
3644   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3645         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3646                    (match_operand:HI 2 "const_int_operand" "n")))
3647    (clobber (reg:SI T_REG))]
3648   "TARGET_SH1"
3649   "#"
3650   [(set (attr "length")
3651         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3652                (const_string "2")
3653                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3654                (const_string "4")]
3655               (const_string "6")))
3656    (set_attr "type" "arith")])
3657
3658 (define_expand "ashlhi3"
3659   [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3660                    (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3661                               (match_operand:SI 2 "nonmemory_operand" "")))
3662               (clobber (reg:SI T_REG))])]
3663   "TARGET_SH1"
3664   "
3665 {
3666   if (GET_CODE (operands[2]) != CONST_INT)
3667     FAIL;
3668   /* It may be possible to call gen_ashlhi3 directly with more generic
3669      operands.  Make sure operands[1] is a HImode register here.  */
3670   if (!arith_reg_operand (operands[1], HImode))
3671     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3672 }")
3673
3674 (define_split
3675   [(set (match_operand:HI 0 "arith_reg_dest" "")
3676         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3677                    (match_operand:HI 2 "const_int_operand" "")))
3678    (clobber (reg:SI T_REG))]
3679   "TARGET_SH1 && reload_completed"
3680   [(use (reg:SI R0_REG))]
3681   "
3682 {
3683   gen_shifty_hi_op (ASHIFT, operands);
3684   DONE;
3685 }")
3686
3687 ;
3688 ; arithmetic shift right
3689 ;
3690
3691 (define_insn "ashrsi3_sh2a"
3692   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3693         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3694                    (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3695   "TARGET_SH2A"
3696   "shad %2,%0"
3697   [(set_attr "type" "dyn_shift")
3698    (set_attr "length" "4")])
3699
3700 (define_insn "ashrsi3_k"
3701   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3702         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3703                      (match_operand:SI 2 "const_int_operand" "M")))
3704    (clobber (reg:SI T_REG))]
3705   "TARGET_SH1 && INTVAL (operands[2]) == 1"
3706   "shar %0"
3707   [(set_attr "type" "arith")])
3708
3709 ;; We can't do HImode right shifts correctly unless we start out with an
3710 ;; explicit zero / sign extension; doing that would result in worse overall
3711 ;; code, so just let the machine independent code widen the mode.
3712 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3713
3714
3715 ;; ??? This should be a define expand.
3716
3717 (define_insn "ashrsi2_16"
3718   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3719         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3720                      (const_int 16)))]
3721   "TARGET_SH1"
3722   "#"
3723   [(set_attr "length" "4")])
3724
3725 (define_split
3726   [(set (match_operand:SI 0 "arith_reg_dest" "")
3727         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3728                      (const_int 16)))]
3729   "TARGET_SH1"
3730   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3731    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3732   "operands[2] = gen_lowpart (HImode, operands[0]);")
3733
3734 ;; ??? This should be a define expand.
3735
3736 (define_insn "ashrsi2_31"
3737   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3738         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3739                      (const_int 31)))
3740    (clobber (reg:SI T_REG))]
3741   "TARGET_SH1"
3742   "#"
3743   [(set_attr "length" "4")])
3744
3745 (define_split
3746   [(set (match_operand:SI 0 "arith_reg_dest" "")
3747         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3748                      (const_int 31)))
3749    (clobber (reg:SI T_REG))]
3750   "TARGET_SH1"
3751   [(const_int 0)]
3752   "
3753 {
3754   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3755   emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3756   DONE;
3757 }")
3758
3759 (define_peephole2
3760   [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3761    (set (reg:SI T_REG)
3762         (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3763   "TARGET_SH1
3764    && peep2_reg_dead_p (2, operands[0])
3765    && peep2_reg_dead_p (2, operands[1])"
3766   [(const_int 0)]
3767   "
3768 {
3769   emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3770   DONE;
3771 }")
3772
3773 (define_insn "ashlsi_c"
3774   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3775         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3776    (set (reg:SI T_REG)
3777         (lt:SI (match_dup 1) (const_int 0)))]
3778   "TARGET_SH1"
3779   "shll %0"
3780   [(set_attr "type" "arith")])
3781
3782 (define_insn "*ashlsi_c_void"
3783   [(set (reg:SI T_REG)
3784         (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3785    (clobber (match_scratch:SI 1 "=0"))]
3786   "TARGET_SH1 && cse_not_expected"
3787   "shll %0"
3788   [(set_attr "type" "arith")])
3789
3790 (define_insn "ashrsi3_d"
3791   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3792         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3793                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3794   "TARGET_SH3"
3795   "shad %2,%0"
3796   [(set_attr "type" "dyn_shift")])
3797
3798 (define_insn "ashrsi3_n"
3799   [(set (reg:SI R4_REG)
3800         (ashiftrt:SI (reg:SI R4_REG)
3801                      (match_operand:SI 0 "const_int_operand" "i")))
3802    (clobber (reg:SI T_REG))
3803    (clobber (reg:SI PR_REG))
3804    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3805   "TARGET_SH1"
3806   "jsr  @%1%#"
3807   [(set_attr "type" "sfunc")
3808    (set_attr "needs_delay_slot" "yes")])
3809
3810 (define_insn "ashrsi3_media"
3811   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3812         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3813                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3814   "TARGET_SHMEDIA"
3815   "@
3816         shard.l %1, %2, %0
3817         shari.l %1, %2, %0"
3818   [(set_attr "type" "arith_media")
3819    (set_attr "highpart" "ignore")])
3820
3821 (define_expand "ashrsi3"
3822   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3823                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3824                                 (match_operand:SI 2 "nonmemory_operand" "")))
3825               (clobber (reg:SI T_REG))])]
3826   ""
3827   "
3828 {
3829   if (TARGET_SHMEDIA)
3830     {
3831       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3832       DONE;
3833     }
3834   if (expand_ashiftrt (operands))
3835     DONE;
3836   else
3837     FAIL;
3838 }")
3839
3840 ;; logical shift right
3841
3842 (define_insn "lshrsi3_sh2a"
3843   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3844         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3845                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3846   "TARGET_SH2A"
3847   "shld %2,%0"
3848   [(set_attr "type" "dyn_shift")
3849    (set_attr "length" "4")])
3850
3851 (define_insn "lshrsi3_d"
3852   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3853         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3854                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3855   "TARGET_SH3"
3856   "shld %2,%0"
3857   [(set_attr "type" "dyn_shift")])
3858
3859 ;;  Only the single bit shift clobbers the T bit.
3860
3861 (define_insn "lshrsi3_m"
3862   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3863         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3864                      (match_operand:SI 2 "const_int_operand" "M")))
3865    (clobber (reg:SI T_REG))]
3866   "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
3867   "shlr %0"
3868   [(set_attr "type" "arith")])
3869
3870 (define_insn "lshrsi3_k"
3871   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3872         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3873                      (match_operand:SI 2 "const_int_operand" "P27")))]
3874   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
3875    && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
3876   "shlr%O2      %0"
3877   [(set_attr "type" "arith")])
3878
3879 (define_insn "lshrsi3_n"
3880   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3881         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3882                      (match_operand:SI 2 "const_int_operand" "n")))
3883    (clobber (reg:SI T_REG))]
3884   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3885   "#"
3886   [(set (attr "length")
3887         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3888                (const_string "2")
3889                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3890                (const_string "4")
3891                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3892                (const_string "6")]
3893               (const_string "8")))
3894    (set_attr "type" "arith")])
3895
3896 (define_split
3897   [(set (match_operand:SI 0 "arith_reg_dest" "")
3898         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3899                      (match_operand:SI 2 "const_int_operand" "")))
3900    (clobber (reg:SI T_REG))]
3901   "TARGET_SH1 && reload_completed"
3902   [(use (reg:SI R0_REG))]
3903   "
3904 {
3905   gen_shifty_op (LSHIFTRT, operands);
3906   DONE;
3907 }")
3908
3909 (define_insn "lshrsi3_media"
3910   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3911         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3912                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3913   "TARGET_SHMEDIA"
3914   "@
3915         shlrd.l %1, %2, %0
3916         shlri.l %1, %2, %0"
3917   [(set_attr "type" "arith_media")
3918    (set_attr "highpart" "ignore")])
3919
3920 (define_expand "lshrsi3"
3921   [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3922                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3923                                 (match_operand:SI 2 "nonmemory_operand" "")))
3924               (clobber (reg:SI T_REG))])]
3925   ""
3926   "
3927 {
3928   if (TARGET_SHMEDIA)
3929     {
3930       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3931       DONE;
3932     }
3933   if (GET_CODE (operands[2]) == CONST_INT
3934       && sh_dynamicalize_shift_p (operands[2]))
3935     operands[2] = force_reg (SImode, operands[2]);
3936   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3937     {
3938       rtx count = copy_to_mode_reg (SImode, operands[2]);
3939       emit_insn (gen_negsi2 (count, count));
3940       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3941       DONE;
3942     }
3943   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3944     FAIL;
3945 }")
3946
3947 ;; ??? This should be a define expand.
3948
3949 (define_insn "ashldi3_k"
3950   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3951         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3952                    (const_int 1)))
3953    (clobber (reg:SI T_REG))]
3954   "TARGET_SH1"
3955   "shll %R0\;rotcl      %S0"
3956   [(set_attr "length" "4")
3957    (set_attr "type" "arith")])
3958
3959 (define_insn "ashldi3_media"
3960   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3961         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3962                    (match_operand:DI 2 "shift_count_operand" "r,n")))]
3963   "TARGET_SHMEDIA"
3964   "@
3965         shlld   %1, %2, %0
3966         shlli   %1, %2, %0"
3967   [(set_attr "type" "arith_media")])
3968
3969 (define_insn "*ashldisi3_media"
3970   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3971         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3972                    (match_operand:DI 2 "const_int_operand" "n")))]
3973   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3974   "shlli.l      %1, %2, %0"
3975   [(set_attr "type" "arith_media")
3976    (set_attr "highpart" "ignore")])
3977
3978 (define_expand "ashldi3"
3979   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3980                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3981                               (match_operand:DI 2 "immediate_operand" "")))
3982               (clobber (reg:SI T_REG))])]
3983   ""
3984   "
3985 {
3986   if (TARGET_SHMEDIA)
3987     {
3988       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3989       DONE;
3990     }
3991   if (GET_CODE (operands[2]) != CONST_INT
3992       || INTVAL (operands[2]) != 1)
3993     FAIL;
3994 }")
3995
3996 ;; ??? This should be a define expand.
3997
3998 (define_insn "lshrdi3_k"
3999   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4000         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4001                      (const_int 1)))
4002    (clobber (reg:SI T_REG))]
4003   "TARGET_SH1"
4004   "shlr %S0\;rotcr      %R0"
4005   [(set_attr "length" "4")
4006    (set_attr "type" "arith")])
4007
4008 (define_insn "lshrdi3_media"
4009   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4010         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4011                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
4012   "TARGET_SHMEDIA
4013    && (arith_reg_dest (operands[0], DImode)
4014        || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 32))"
4015   "@
4016         shlrd   %1, %2, %0
4017         shlri   %1, %2, %0"
4018   [(set_attr "type" "arith_media")])
4019
4020 (define_insn "*lshrdisi3_media"
4021   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4022         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4023                      (match_operand:DI 2 "const_int_operand" "n")))]
4024   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4025   "shlri.l      %1, %2, %0"
4026   [(set_attr "type" "arith_media")
4027    (set_attr "highpart" "ignore")])
4028
4029 (define_expand "lshrdi3"
4030   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4031                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4032                                (match_operand:DI 2 "immediate_operand" "")))
4033              (clobber (reg:SI T_REG))])]
4034   ""
4035   "
4036 {
4037   if (TARGET_SHMEDIA)
4038     {
4039       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
4040       DONE;
4041     }
4042   if (GET_CODE (operands[2]) != CONST_INT
4043       || INTVAL (operands[2]) != 1)
4044     FAIL;
4045 }")
4046
4047 ;; ??? This should be a define expand.
4048
4049 (define_insn "ashrdi3_k"
4050   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4051         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4052                      (const_int 1)))
4053    (clobber (reg:SI T_REG))]
4054   "TARGET_SH1"
4055   "shar %S0\;rotcr      %R0"
4056   [(set_attr "length" "4")
4057    (set_attr "type" "arith")])
4058
4059 (define_insn "ashrdi3_media"
4060   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4061         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4062                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
4063   "TARGET_SHMEDIA
4064    && (arith_reg_dest (operands[0], DImode)
4065        || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32))"
4066   "@
4067         shard   %1, %2, %0
4068         shari   %1, %2, %0"
4069   [(set_attr "type" "arith_media")])
4070
4071 (define_insn "*ashrdisi3_media"
4072   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4073         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4074                      (match_operand:DI 2 "const_int_operand" "n")))]
4075   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4076   "shari.l      %1, %2, %0"
4077   [(set_attr "type" "arith_media")
4078    (set_attr "highpart" "ignore")])
4079
4080 (define_insn "ashrdisi3_media_high"
4081   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4082         (truncate:SI
4083            (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4084                         (match_operand:DI 2 "const_int_operand" "n"))))]
4085   "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4086   "shari        %1, %2, %0"
4087   [(set_attr "type" "arith_media")])
4088
4089 (define_insn "ashrdisi3_media_opaque"
4090   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4091         (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4092                     (match_operand:DI 2 "const_int_operand" "n")]
4093          UNSPEC_ASHIFTRT))]
4094   "TARGET_SHMEDIA"
4095   "shari        %1, %2, %0"
4096   [(set_attr "type" "arith_media")])
4097
4098 (define_expand "ashrdi3"
4099   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4100                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4101                                 (match_operand:DI 2 "immediate_operand" "")))
4102               (clobber (reg:SI T_REG))])]
4103   ""
4104   "
4105 {
4106   if (TARGET_SHMEDIA)
4107     {
4108       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4109       DONE;
4110     }
4111   if (GET_CODE (operands[2]) != CONST_INT
4112       || INTVAL (operands[2]) != 1)
4113     FAIL;
4114 }")
4115
4116 ;; combined left/right shift
4117
4118 (define_split
4119   [(set (match_operand:SI 0 "register_operand" "")
4120         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4121                            (match_operand:SI 2 "const_int_operand" ""))
4122                 (match_operand:SI 3 "const_int_operand" "")))]
4123   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4124   [(use (reg:SI R0_REG))]
4125   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4126    DONE;")
4127
4128 (define_split
4129   [(set (match_operand:SI 0 "register_operand" "")
4130         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4131                            (match_operand:SI 2 "const_int_operand" ""))
4132                 (match_operand:SI 3 "const_int_operand" "")))
4133    (clobber (reg:SI T_REG))]
4134   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4135   [(use (reg:SI R0_REG))]
4136   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4137    DONE;")
4138
4139 (define_insn ""
4140   [(set (match_operand:SI 0 "register_operand" "=r")
4141         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4142                            (match_operand:SI 2 "const_int_operand" "n"))
4143                 (match_operand:SI 3 "const_int_operand" "n")))
4144    (clobber (reg:SI T_REG))]
4145   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4146  "#"
4147   [(set (attr "length")
4148         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4149                (const_string "4")
4150                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4151                (const_string "6")
4152                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4153                (const_string "8")
4154                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4155                (const_string "10")
4156                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4157                (const_string "12")
4158                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4159                (const_string "14")
4160                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4161                (const_string "16")]
4162               (const_string "18")))
4163    (set_attr "type" "arith")])
4164
4165 (define_insn ""
4166   [(set (match_operand:SI 0 "register_operand" "=z")
4167         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4168                            (match_operand:SI 2 "const_int_operand" "n"))
4169                 (match_operand:SI 3 "const_int_operand" "n")))
4170    (clobber (reg:SI T_REG))]
4171   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4172  "#"
4173   [(set (attr "length")
4174         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4175                (const_string "4")
4176                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4177                (const_string "6")
4178                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4179                (const_string "8")]
4180               (const_string "10")))
4181    (set_attr "type" "arith")])
4182
4183 ;; shift left / and combination with a scratch register: The combine pass
4184 ;; does not accept the individual instructions, even though they are
4185 ;; cheap.  But it needs a precise description so that it is usable after
4186 ;; reload.
4187 (define_insn "and_shl_scratch"
4188   [(set (match_operand:SI 0 "register_operand" "=r,&r")
4189         (lshiftrt:SI
4190          (ashift:SI
4191           (and:SI
4192            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4193                         (match_operand:SI 2 "const_int_operand" "N,n"))
4194            (match_operand:SI 3 "" "0,r"))
4195           (match_operand:SI 4 "const_int_operand" "n,n"))
4196          (match_operand:SI 5 "const_int_operand" "n,n")))
4197    (clobber (reg:SI T_REG))]
4198   "TARGET_SH1"
4199   "#"
4200   [(set (attr "length")
4201         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4202                (const_string "4")
4203                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4204                (const_string "6")
4205                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4206                (const_string "8")
4207                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4208                (const_string "10")]
4209               (const_string "12")))
4210    (set_attr "type" "arith")])
4211
4212 (define_split
4213   [(set (match_operand:SI 0 "register_operand" "")
4214         (lshiftrt:SI
4215          (ashift:SI
4216           (and:SI
4217            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4218                         (match_operand:SI 2 "const_int_operand" ""))
4219            (match_operand:SI 3 "register_operand" ""))
4220           (match_operand:SI 4 "const_int_operand" ""))
4221          (match_operand:SI 5 "const_int_operand" "")))
4222    (clobber (reg:SI T_REG))]
4223   "TARGET_SH1"
4224   [(use (reg:SI R0_REG))]
4225   "
4226 {
4227   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4228
4229   if (INTVAL (operands[2]))
4230     {
4231       gen_shifty_op (LSHIFTRT, operands);
4232     }
4233   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4234   operands[2] = operands[4];
4235   gen_shifty_op (ASHIFT, operands);
4236   if (INTVAL (operands[5]))
4237     {
4238       operands[2] = operands[5];
4239       gen_shifty_op (LSHIFTRT, operands);
4240     }
4241   DONE;
4242 }")
4243
4244 ;; signed left/right shift combination.
4245 (define_split
4246   [(set (match_operand:SI 0 "register_operand" "")
4247         (sign_extract:SI
4248          (ashift:SI (match_operand:SI 1 "register_operand" "")
4249                     (match_operand:SI 2 "const_int_operand" ""))
4250          (match_operand:SI 3 "const_int_operand" "")
4251          (const_int 0)))
4252    (clobber (reg:SI T_REG))]
4253   "TARGET_SH1"
4254   [(use (reg:SI R0_REG))]
4255   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4256    DONE;")
4257
4258 (define_insn "shl_sext_ext"
4259   [(set (match_operand:SI 0 "register_operand" "=r")
4260         (sign_extract:SI
4261          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4262                     (match_operand:SI 2 "const_int_operand" "n"))
4263          (match_operand:SI 3 "const_int_operand" "n")
4264          (const_int 0)))
4265    (clobber (reg:SI T_REG))]
4266   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4267   "#"
4268   [(set (attr "length")
4269         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4270                (const_string "2")
4271                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4272                (const_string "4")
4273                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4274                (const_string "6")
4275                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4276                (const_string "8")
4277                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4278                (const_string "10")
4279                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4280                (const_string "12")
4281                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4282                (const_string "14")
4283                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4284                (const_string "16")]
4285               (const_string "18")))
4286     (set_attr "type" "arith")])
4287
4288 (define_insn "shl_sext_sub"
4289   [(set (match_operand:SI 0 "register_operand" "=z")
4290         (sign_extract:SI
4291          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4292                     (match_operand:SI 2 "const_int_operand" "n"))
4293          (match_operand:SI 3 "const_int_operand" "n")
4294          (const_int 0)))
4295    (clobber (reg:SI T_REG))]
4296   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4297   "#"
4298   [(set (attr "length")
4299         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4300                (const_string "6")
4301                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4302                (const_string "8")
4303                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4304                (const_string "10")
4305                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4306                (const_string "12")]
4307               (const_string "14")))
4308     (set_attr "type" "arith")])
4309
4310 ;; These patterns are found in expansions of DImode shifts by 16, and
4311 ;; allow the xtrct instruction to be generated from C source.
4312
4313 (define_insn "xtrct_left"
4314   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4315         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4316                            (const_int 16))
4317                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4318                              (const_int 16))))]
4319   "TARGET_SH1"
4320   "xtrct        %1,%0"
4321   [(set_attr "type" "arith")])
4322
4323 (define_insn "xtrct_right"
4324   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4325         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4326                              (const_int 16))
4327                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4328                            (const_int 16))))]
4329   "TARGET_SH1"
4330   "xtrct        %2,%0"
4331   [(set_attr "type" "arith")])
4332
4333 ;; -------------------------------------------------------------------------
4334 ;; Unary arithmetic
4335 ;; -------------------------------------------------------------------------
4336
4337 (define_insn "negc"
4338   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4339         (neg:SI (plus:SI (reg:SI T_REG)
4340                          (match_operand:SI 1 "arith_reg_operand" "r"))))
4341    (set (reg:SI T_REG)
4342         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4343                (const_int 0)))]
4344   "TARGET_SH1"
4345   "negc %1,%0"
4346   [(set_attr "type" "arith")])
4347
4348 (define_insn "*negdi_media"
4349   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4350         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4351   "TARGET_SHMEDIA"
4352   "sub  r63, %1, %0"
4353   [(set_attr "type" "arith_media")])
4354
4355 (define_expand "negdi2"
4356   [(set (match_operand:DI 0 "arith_reg_operand" "")
4357         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4358   ""
4359   "
4360 {
4361   if (TARGET_SH1)
4362     {
4363       int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4364       int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4365
4366       rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4367       rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4368
4369       rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4370       rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4371
4372       emit_insn (gen_clrt ());
4373       emit_insn (gen_negc (low_dst, low_src));
4374       emit_insn (gen_negc (high_dst, high_src));
4375       DONE;
4376     }
4377 }")
4378
4379 (define_insn "negsi2"
4380   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4381         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4382   "TARGET_SH1"
4383   "neg  %1,%0"
4384   [(set_attr "type" "arith")])
4385
4386 (define_insn "one_cmplsi2"
4387   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4388         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4389   "TARGET_SH1"
4390   "not  %1,%0"
4391   [(set_attr "type" "arith")])
4392
4393 (define_expand "one_cmpldi2"
4394   [(set (match_operand:DI 0 "arith_reg_dest" "")
4395         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4396                 (const_int -1)))]
4397   "TARGET_SHMEDIA" "")
4398
4399 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4400    This can be used as some kind of conditional execution, which is useful
4401    for abs.  */
4402 (define_split
4403   [(set (match_operand:SI 0 "arith_reg_dest" "")
4404         (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4405                          (match_operand:SI 1 "arith_reg_operand" ""))
4406                  (reg:SI T_REG)))]
4407   "TARGET_HARD_SH4"
4408   [(const_int 0)]
4409   "emit_insn (gen_movsi_i (operands[0], operands[1]));
4410    emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4411    DONE;")
4412
4413 (define_insn "cneg"
4414   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4415         (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4416                       (match_operand:SI 1 "arith_reg_operand" "0")
4417                       (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4418   "TARGET_HARD_SH4"
4419   "bf 0f\;neg %2,%0\\n0:"
4420   [(set_attr "type" "arith") ;; poor approximation
4421    (set_attr "length" "4")])
4422
4423 \f
4424 ;; -------------------------------------------------------------------------
4425 ;; Zero extension instructions
4426 ;; -------------------------------------------------------------------------
4427
4428 (define_insn "zero_extendsidi2"
4429   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4430         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4431   "TARGET_SHMEDIA"
4432   "addz.l       %1, r63, %0"
4433   [(set_attr "type" "arith_media")
4434    (set_attr "highpart" "extend")])
4435
4436 (define_insn "zero_extendhidi2"
4437   [(set (match_operand:DI 0 "register_operand" "=r,r")
4438         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4439   "TARGET_SHMEDIA"
4440   "@
4441         #
4442         ld%M1.uw        %m1, %0"
4443   [(set_attr "type" "*,load_media")
4444    (set (attr "highpart")
4445         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4446                (const_string "user")]
4447               (const_string "ignore")))])
4448
4449 (define_split
4450   [(set (match_operand:DI 0 "register_operand" "")
4451         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4452   "TARGET_SHMEDIA && reload_completed"
4453   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4454    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4455   "
4456 {
4457   if (GET_CODE (operands[1]) == TRUNCATE)
4458     operands[1] = XEXP (operands[1], 0);
4459 }")
4460
4461 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4462 ;; reload the entire truncate expression.
4463 (define_insn_and_split "*loaddi_trunc"
4464   [(set (match_operand 0 "any_register_operand" "=r")
4465         (truncate (match_operand:DI 1 "memory_operand" "m")))]
4466   "TARGET_SHMEDIA && reload_completed"
4467   "#"
4468   "TARGET_SHMEDIA && reload_completed"
4469   [(set (match_dup 0) (match_dup 1))]
4470   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4471
4472 (define_insn "zero_extendqidi2"
4473   [(set (match_operand:DI 0 "register_operand" "=r,r")
4474         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4475   "TARGET_SHMEDIA"
4476   "@
4477         andi    %1, 255, %0
4478         ld%M1.ub        %m1, %0"
4479   [(set_attr "type" "arith_media,load_media")
4480    (set (attr "highpart")
4481         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4482                (const_string "user")]
4483               (const_string "ignore")))])
4484
4485 (define_expand "zero_extendhisi2"
4486   [(set (match_operand:SI 0 "arith_reg_operand" "")
4487         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4488   ""
4489   "
4490 {
4491   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4492     operands[1] = copy_to_mode_reg (HImode, operands[1]);
4493 }")
4494
4495 (define_insn "*zero_extendhisi2_compact"
4496   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4497         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4498   "TARGET_SH1"
4499   "extu.w       %1,%0"
4500   [(set_attr "type" "arith")])
4501
4502 (define_insn "*zero_extendhisi2_media"
4503   [(set (match_operand:SI 0 "register_operand" "=r,r")
4504         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4505   "TARGET_SHMEDIA"
4506   "@
4507         #
4508         ld%M1.uw        %m1, %0"
4509   [(set_attr "type" "arith_media,load_media")
4510    (set (attr "highpart")
4511         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4512                (const_string "user")]
4513               (const_string "ignore")))])
4514
4515 (define_split
4516   [(set (match_operand:SI 0 "register_operand" "")
4517         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4518   "TARGET_SHMEDIA && reload_completed"
4519   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4520    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4521   "
4522 {
4523   rtx op1 = operands[1];
4524
4525   if (GET_CODE (op1) == TRUNCATE)
4526     op1 = XEXP (op1, 0);
4527   operands[2]
4528     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4529                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4530 }")
4531
4532 (define_expand "zero_extendqisi2"
4533   [(set (match_operand:SI 0 "arith_reg_operand" "")
4534         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4535   ""
4536   "
4537 {
4538   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4539     operands[1] = copy_to_mode_reg (QImode, operands[1]);
4540 }")
4541
4542 (define_insn "*zero_extendqisi2_compact"
4543   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4544         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4545   "TARGET_SH1"
4546   "extu.b       %1,%0"
4547   [(set_attr "type" "arith")])
4548
4549 (define_insn "*zero_extendqisi2_media"
4550   [(set (match_operand:SI 0 "register_operand" "=r,r")
4551         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4552   "TARGET_SHMEDIA"
4553   "@
4554         andi    %1, 255, %0
4555         ld%M1.ub        %m1, %0"
4556   [(set_attr "type" "arith_media,load_media")
4557    (set (attr "highpart")
4558         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4559                (const_string "user")]
4560               (const_string "ignore")))])
4561
4562 (define_insn "zero_extendqihi2"
4563   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4564         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4565   "TARGET_SH1"
4566   "extu.b       %1,%0"
4567   [(set_attr "type" "arith")])
4568
4569 ;; -------------------------------------------------------------------------
4570 ;; Sign extension instructions
4571 ;; -------------------------------------------------------------------------
4572
4573 ;; ??? This should be a define expand.
4574 ;; ??? Or perhaps it should be dropped?
4575
4576 ;; convert_move generates good code for SH[1-4].
4577 (define_insn "extendsidi2"
4578   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4579         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4580   "TARGET_SHMEDIA"
4581   "@
4582         add.l   %1, r63, %0
4583         ld%M1.l %m1, %0
4584         fmov.sl %1, %0"
4585   [(set_attr "type" "arith_media,load_media,fpconv_media")
4586    (set (attr "highpart")
4587         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4588                (const_string "user")]
4589               (const_string "extend")))])
4590
4591 (define_insn "extendhidi2"
4592   [(set (match_operand:DI 0 "register_operand" "=r,r")
4593         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4594   "TARGET_SHMEDIA"
4595   "@
4596         #
4597         ld%M1.w %m1, %0"
4598   [(set_attr "type" "*,load_media")
4599    (set (attr "highpart")
4600         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4601                (const_string "user")]
4602               (const_string "ignore")))])
4603
4604 (define_split
4605   [(set (match_operand:DI 0 "register_operand" "")
4606         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4607   "TARGET_SHMEDIA && reload_completed"
4608   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4609    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4610   "
4611 {
4612   if (GET_CODE (operands[1]) == TRUNCATE)
4613     operands[1] = XEXP (operands[1], 0);
4614 }")
4615
4616 (define_insn "extendqidi2"
4617   [(set (match_operand:DI 0 "register_operand" "=r,r")
4618         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4619   "TARGET_SHMEDIA"
4620   "@
4621         #
4622         ld%M1.b %m1, %0"
4623   [(set_attr "type" "*,load_media")
4624    (set (attr "highpart")
4625         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4626                (const_string "user")]
4627               (const_string "ignore")))])
4628
4629 (define_split
4630   [(set (match_operand:DI 0 "register_operand" "")
4631         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4632   "TARGET_SHMEDIA && reload_completed"
4633   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4634    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4635   "
4636 {
4637   if (GET_CODE (operands[1]) == TRUNCATE)
4638     operands[1] = XEXP (operands[1], 0);
4639 }")
4640
4641 (define_expand "extendhisi2"
4642   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4643         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4644   ""
4645   "")
4646
4647 (define_insn "*extendhisi2_compact"
4648   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4649         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4650   "TARGET_SH1"
4651   "@
4652         exts.w  %1,%0
4653         mov.w   %1,%0"
4654   [(set_attr "type" "arith,load")])
4655
4656 (define_insn "*extendhisi2_media"
4657   [(set (match_operand:SI 0 "register_operand" "=r,r")
4658         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4659   "TARGET_SHMEDIA"
4660   "@
4661         #
4662         ld%M1.w %m1, %0"
4663   [(set_attr "type" "arith_media,load_media")
4664    (set (attr "highpart")
4665         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4666                (const_string "user")]
4667               (const_string "ignore")))])
4668
4669 (define_split
4670   [(set (match_operand:SI 0 "register_operand" "")
4671         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4672   "TARGET_SHMEDIA && reload_completed"
4673   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4674    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4675   "
4676 {
4677   rtx op1 = operands[1];
4678   if (GET_CODE (op1) == TRUNCATE)
4679     op1 = XEXP (op1, 0);
4680   operands[2]
4681     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4682                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4683 }")
4684
4685 (define_expand "extendqisi2"
4686   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4687         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4688   ""
4689   "")
4690
4691 (define_insn "*extendqisi2_compact"
4692   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4693         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4694   "TARGET_SH1"
4695   "@
4696         exts.b  %1,%0
4697         mov.b   %1,%0"
4698   [(set_attr "type" "arith,load")])
4699
4700 (define_insn "*extendqisi2_media"
4701   [(set (match_operand:SI 0 "register_operand" "=r,r")
4702         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4703   "TARGET_SHMEDIA"
4704   "@
4705         #
4706         ld%M1.b %m1, %0"
4707   [(set_attr "type" "arith_media,load_media")
4708    (set (attr "highpart")
4709         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4710                (const_string "user")]
4711               (const_string "ignore")))])
4712
4713 (define_split
4714   [(set (match_operand:SI 0 "register_operand" "")
4715         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4716   "TARGET_SHMEDIA && reload_completed"
4717   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4718    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4719    "
4720 {
4721   rtx op1 = operands[1];
4722   if (GET_CODE (op1) == TRUNCATE)
4723     op1 = XEXP (op1, 0);
4724   operands[2]
4725     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4726                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4727 }")
4728
4729 (define_insn "extendqihi2"
4730   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4731         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4732   "TARGET_SH1"
4733   "@
4734         exts.b  %1,%0
4735         mov.b   %1,%0"
4736   [(set_attr "type" "arith,load")])
4737
4738 /* It would seem useful to combine the truncXi patterns into the movXi
4739    patterns, but unary operators are ignored when matching constraints,
4740    so we need separate patterns.  */
4741 (define_insn "truncdisi2"
4742   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4743         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4744   "TARGET_SHMEDIA"
4745   "@
4746         add.l   %1, r63, %0
4747         st%M0.l %m0, %1
4748         fst%M0.s        %m0, %T1
4749         fmov.ls %1, %0
4750         fmov.sl %T1, %0
4751         fmov.s  %T1, %0"
4752   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4753    (set (attr "highpart")
4754         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4755                (const_string "user")]
4756               (const_string "extend")))])
4757
4758 (define_insn "truncdihi2"
4759   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4760         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4761   "TARGET_SHMEDIA"
4762   "@
4763         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4764         st%M0.w %m0, %1"
4765   [(set_attr "type"   "arith_media,store_media")
4766    (set_attr "length" "8,4")
4767    (set (attr "highpart")
4768         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4769                (const_string "user")]
4770               (const_string "extend")))])
4771
4772 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4773 ; Because we use zero extension, we can't provide signed QImode compares
4774 ; using a simple compare or conditional banch insn.
4775 (define_insn "truncdiqi2"
4776   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4777         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4778   "TARGET_SHMEDIA"
4779   "@
4780         andi    %1, 255, %0
4781         st%M0.b %m0, %1"
4782   [(set_attr "type"   "arith_media,store")
4783    (set (attr "highpart")
4784         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4785                (const_string "user")]
4786               (const_string "extend")))])
4787 ;; -------------------------------------------------------------------------
4788 ;; Move instructions
4789 ;; -------------------------------------------------------------------------
4790
4791 ;; define push and pop so it is easy for sh.c
4792 ;; We can't use push and pop on SHcompact because the stack must always
4793 ;; be 8-byte aligned.
4794
4795 (define_expand "push"
4796   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4797         (match_operand:SI 0 "register_operand" "r,l,x"))]
4798   "TARGET_SH1 && ! TARGET_SH5"
4799   "")
4800
4801 (define_expand "pop"
4802   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4803         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4804   "TARGET_SH1 && ! TARGET_SH5"
4805   "")
4806
4807 (define_expand "push_e"
4808   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4809                    (match_operand:SF 0 "" ""))
4810               (use (reg:PSI FPSCR_REG))
4811               (clobber (scratch:SI))])]
4812   "TARGET_SH1 && ! TARGET_SH5"
4813   "")
4814
4815 (define_insn "push_fpul"
4816   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4817   "TARGET_SH2E && ! TARGET_SH5"
4818   "sts.l        fpul,@-r15"
4819   [(set_attr "type" "fstore")
4820    (set_attr "late_fp_use" "yes")
4821    (set_attr "hit_stack" "yes")])
4822
4823 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4824 ;; so use that.
4825 (define_expand "push_4"
4826   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4827                    (match_operand:DF 0 "" ""))
4828               (use (reg:PSI FPSCR_REG))
4829               (clobber (scratch:SI))])]
4830   "TARGET_SH1 && ! TARGET_SH5"
4831   "")
4832
4833 (define_expand "pop_e"
4834   [(parallel [(set (match_operand:SF 0 "" "")
4835               (mem:SF (post_inc:SI (reg:SI SP_REG))))
4836               (use (reg:PSI FPSCR_REG))
4837               (clobber (scratch:SI))])]
4838   "TARGET_SH1 && ! TARGET_SH5"
4839   "")
4840
4841 (define_insn "pop_fpul"
4842   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4843   "TARGET_SH2E && ! TARGET_SH5"
4844   "lds.l        @r15+,fpul"
4845   [(set_attr "type" "load")
4846    (set_attr "hit_stack" "yes")])
4847
4848 (define_expand "pop_4"
4849   [(parallel [(set (match_operand:DF 0 "" "")
4850                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
4851               (use (reg:PSI FPSCR_REG))
4852               (clobber (scratch:SI))])]
4853   "TARGET_SH1 && ! TARGET_SH5"
4854   "")
4855
4856 (define_expand "push_fpscr"
4857   [(const_int 0)]
4858   "TARGET_SH2E"
4859   "
4860 {
4861   rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4862                                                  gen_rtx_PRE_DEC (Pmode,
4863                                                           stack_pointer_rtx)),
4864                                         get_fpscr_rtx ()));
4865   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4866   DONE;
4867 }")
4868
4869 (define_expand "pop_fpscr"
4870   [(const_int 0)]
4871   "TARGET_SH2E"
4872   "
4873 {
4874   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4875                                         gen_frame_mem (PSImode,
4876                                                  gen_rtx_POST_INC (Pmode,
4877                                                           stack_pointer_rtx))));
4878   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4879   DONE;
4880 }")
4881
4882 ;; These two patterns can happen as the result of optimization, when
4883 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4884 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4885
4886 (define_insn "clrt"
4887   [(set (reg:SI T_REG) (const_int 0))]
4888   "TARGET_SH1"
4889   "clrt")
4890
4891 (define_insn "sett"
4892   [(set (reg:SI T_REG) (const_int 1))]
4893   "TARGET_SH1"
4894   "sett")
4895
4896 ;; t/r must come after r/r, lest reload will try to reload stuff like
4897 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4898 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4899 (define_insn "movsi_i"
4900   [(set (match_operand:SI 0 "general_movdst_operand"
4901             "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4902         (match_operand:SI 1 "general_movsrc_operand"
4903          "Q,r,I08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4904   "TARGET_SH1
4905    && ! TARGET_SH2E
4906    && ! TARGET_SH2A
4907    && (register_operand (operands[0], SImode)
4908        || register_operand (operands[1], SImode))"
4909   "@
4910         mov.l   %1,%0
4911         mov     %1,%0
4912         mov     %1,%0
4913         cmp/pl  %1
4914         mov.l   %1,%0
4915         sts     %1,%0
4916         sts     %1,%0
4917         movt    %0
4918         mov.l   %1,%0
4919         sts.l   %1,%0
4920         sts.l   %1,%0
4921         lds     %1,%0
4922         lds     %1,%0
4923         lds.l   %1,%0
4924         lds.l   %1,%0
4925         fake    %1,%0"
4926   [(set_attr "type" "pcload_si,move,movi8,mt_group,load_si,mac_gp,prget,arith,mac_mem,store,pstore,gp_mac,prset,mem_mac,pload,pcload_si")
4927    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4928
4929 ;; t/r must come after r/r, lest reload will try to reload stuff like
4930 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4931 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4932 ;; will require a reload.
4933 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4934 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4935 (define_insn "movsi_ie"
4936   [(set (match_operand:SI 0 "general_movdst_operand"
4937             "=r,r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4938         (match_operand:SI 1 "general_movsrc_operand"
4939          "Q,r,I08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4940   "(TARGET_SH2E || TARGET_SH2A)
4941    && (register_operand (operands[0], SImode)
4942        || register_operand (operands[1], SImode))"
4943   "@
4944         mov.l   %1,%0
4945         mov     %1,%0
4946         mov     %1,%0
4947         movi20  %1,%0
4948         cmp/pl  %1
4949         mov.l   %1,%0
4950         sts     %1,%0
4951         sts     %1,%0
4952         movt    %0
4953         mov.l   %1,%0
4954         sts.l   %1,%0
4955         sts.l   %1,%0
4956         lds     %1,%0
4957         lds     %1,%0
4958         lds.l   %1,%0
4959         lds.l   %1,%0
4960         lds.l   %1,%0
4961         sts.l   %1,%0
4962         fake    %1,%0
4963         lds     %1,%0
4964         sts     %1,%0
4965         fsts    fpul,%0
4966         flds    %1,fpul
4967         fmov    %1,%0
4968         ! move optimized away"
4969   [(set_attr "type" "pcload_si,move,movi8,move,*,load_si,mac_gp,prget,arith,store,mac_mem,pstore,gp_mac,prset,mem_mac,pload,load,fstore,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
4970    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
4971    (set_attr "length" "*,*,*,4,*,4,*,*,*,4,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
4972
4973 (define_insn "movsi_i_lowpart"
4974   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,r,m,r"))
4975         (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,t,r,i"))]
4976    "TARGET_SH1
4977     && (register_operand (operands[0], SImode)
4978         || register_operand (operands[1], SImode))"
4979   "@
4980         mov.l   %1,%0
4981         mov     %1,%0
4982         mov     %1,%0
4983         mov.l   %1,%0
4984         sts     %1,%0
4985         sts     %1,%0
4986         movt    %0
4987         mov.l   %1,%0
4988         fake    %1,%0"
4989   [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,arith,store,pcload")])
4990
4991 (define_insn_and_split "load_ra"
4992   [(set (match_operand:SI 0 "general_movdst_operand" "")
4993         (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
4994   "TARGET_SH1"
4995   "#"
4996   "&& ! currently_expanding_to_rtl"
4997   [(set (match_dup 0) (match_dup 1))]
4998   "
4999 {
5000   if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
5001     operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
5002 }")
5003
5004 ;; The '?'s in the following constraints may not reflect the time taken
5005 ;; to perform the move. They are there to discourage the use of floating-
5006 ;; point registers for storing integer values.
5007 (define_insn "*movsi_media"
5008   [(set (match_operand:SI 0 "general_movdst_operand"
5009                 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
5010         (match_operand:SI 1 "general_movsrc_operand"
5011          "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5012   "TARGET_SHMEDIA_FPU
5013    && (register_operand (operands[0], SImode)
5014        || sh_register_operand (operands[1], SImode)
5015        || GET_CODE (operands[1]) == TRUNCATE)"
5016   "@
5017         add.l   %1, r63, %0
5018         movi    %1, %0
5019         #
5020         ld%M1.l %m1, %0
5021         st%M0.l %m0, %N1
5022         fld%M1.s        %m1, %0
5023         fst%M0.s        %m0, %1
5024         fmov.ls %N1, %0
5025         fmov.sl %1, %0
5026         fmov.s  %1, %0
5027         ptabs   %1, %0
5028         gettr   %1, %0
5029         pt      %1, %0"
5030   [(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")
5031    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
5032    (set (attr "highpart")
5033         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5034                (const_string "user")]
5035               (const_string "ignore")))])
5036
5037 (define_insn "*movsi_media_nofpu"
5038   [(set (match_operand:SI 0 "general_movdst_operand"
5039                 "=r,r,r,r,m,*b,r,*b")
5040         (match_operand:SI 1 "general_movsrc_operand"
5041          "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
5042   "TARGET_SHMEDIA
5043    && (register_operand (operands[0], SImode)
5044        || sh_register_operand (operands[1], SImode)
5045        || GET_CODE (operands[1]) == TRUNCATE)"
5046   "@
5047         add.l   %1, r63, %0
5048         movi    %1, %0
5049         #
5050         ld%M1.l %m1, %0
5051         st%M0.l %m0, %N1
5052         ptabs   %1, %0
5053         gettr   %1, %0
5054         pt      %1, %0"
5055   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5056    (set_attr "length" "4,4,8,4,4,4,4,12")
5057    (set (attr "highpart")
5058         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5059                (const_string "user")]
5060               (const_string "ignore")))])
5061
5062 (define_expand "movsi_const"
5063   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5064         (const:SI (sign_extend:SI
5065                    (truncate:HI
5066                     (ashiftrt:SI
5067                      (match_operand:DI 1 "immediate_operand" "s")
5068                      (const_int 16))))))
5069    (set (match_dup 0)
5070         (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5071                 (const:SI
5072                   (zero_extend:SI
5073                    (truncate:HI (match_dup 1))))))]
5074   "TARGET_SHMEDIA && reload_completed
5075    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5076   "
5077 {
5078   if (GET_CODE (operands[1]) == LABEL_REF
5079       && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5080     LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5081   else if (GOTOFF_P (operands[1]))
5082     {
5083       rtx unspec = XEXP (operands[1], 0);
5084
5085       if (! UNSPEC_GOTOFF_P (unspec))
5086         {
5087           unspec = XEXP (unspec, 0);
5088           if (! UNSPEC_GOTOFF_P (unspec))
5089             abort ();
5090         }
5091       if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5092           && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5093         LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5094     }
5095 }")
5096
5097 (define_expand "movsi_const_16bit"
5098   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5099         (const:SI (sign_extend:SI
5100                    (truncate:HI
5101                     (match_operand:DI 1 "immediate_operand" "s")))))]
5102   "TARGET_SHMEDIA && flag_pic && reload_completed
5103    && GET_CODE (operands[1]) == SYMBOL_REF"
5104   "")
5105
5106 (define_split
5107   [(set (match_operand:SI 0 "arith_reg_dest" "")
5108         (match_operand:SI 1 "immediate_operand" ""))]
5109   "TARGET_SHMEDIA && reload_completed
5110    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5111   [(const_int 0)]
5112   "
5113 {
5114   rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5115
5116   set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5117
5118   DONE;
5119 }")
5120
5121 (define_split
5122   [(set (match_operand:SI 0 "register_operand" "")
5123         (match_operand:SI 1 "immediate_operand" ""))]
5124   "TARGET_SHMEDIA && reload_completed
5125    && ((GET_CODE (operands[1]) == CONST_INT
5126         && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
5127        || GET_CODE (operands[1]) == CONST_DOUBLE)"
5128   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5129
5130 (define_expand "movsi"
5131   [(set (match_operand:SI 0 "general_movdst_operand" "")
5132         (match_operand:SI 1 "general_movsrc_operand" ""))]
5133   ""
5134   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
5135
5136 (define_expand "ic_invalidate_line"
5137   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5138                                 (match_dup 1)] UNSPEC_ICACHE)
5139               (clobber (scratch:SI))])]
5140   "TARGET_HARD_SH4 || TARGET_SH5"
5141   "
5142 {
5143   if (TARGET_SHMEDIA)
5144     {
5145       emit_insn (gen_ic_invalidate_line_media (operands[0]));
5146       DONE;
5147     }
5148   else if (TARGET_SHCOMPACT)
5149     {
5150       operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
5151       operands[1] = force_reg (Pmode, operands[1]);
5152       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5153       DONE;
5154     }
5155   else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
5156     {
5157       emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5158       DONE;
5159     }
5160   operands[0] = force_reg (Pmode, operands[0]);
5161   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5162                                                                Pmode)));
5163 }")
5164
5165 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
5166 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5167 ;; the requirement *1*00 for associative address writes.  The alignment of
5168 ;; %0 implies that its least significant bit is cleared,
5169 ;; thus we clear the V bit of a matching entry if there is one.
5170 (define_insn "ic_invalidate_line_i"
5171   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5172                      (match_operand:SI 1 "register_operand" "r")]
5173                      UNSPEC_ICACHE)
5174    (clobber (match_scratch:SI 2 "=&r"))]
5175   "TARGET_HARD_SH4"
5176   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5177   [(set_attr "length" "8")
5178    (set_attr "type" "cwb")])
5179
5180 (define_insn "ic_invalidate_line_sh4a"
5181   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5182                     UNSPEC_ICACHE)]
5183   "TARGET_SH4A_ARCH || TARGET_SH4_300"
5184   "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5185   [(set_attr "length" "16")
5186    (set_attr "type" "cwb")])
5187
5188 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5189 ;; an add in the code that calculates the address.
5190 (define_insn "ic_invalidate_line_media"
5191   [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5192                     UNSPEC_ICACHE)]
5193   "TARGET_SHMEDIA"
5194   "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
5195   [(set_attr "length" "16")
5196    (set_attr "type" "invalidate_line_media")])
5197
5198 (define_insn "ic_invalidate_line_compact"
5199   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5200                      (match_operand:SI 1 "register_operand" "r")]
5201                     UNSPEC_ICACHE)
5202    (clobber (reg:SI PR_REG))]
5203   "TARGET_SHCOMPACT"
5204   "jsr @%1%#"
5205   [(set_attr "type" "sfunc")
5206    (set_attr "needs_delay_slot" "yes")])
5207
5208 (define_expand "initialize_trampoline"
5209   [(match_operand:SI 0 "" "")
5210    (match_operand:SI 1 "" "")
5211    (match_operand:SI 2 "" "")]
5212   "TARGET_SHCOMPACT"
5213   "
5214 {
5215   rtx sfun, tramp;
5216
5217   tramp = force_reg (Pmode, operands[0]);
5218   sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5219                                             SFUNC_STATIC));
5220   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5221   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5222
5223   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5224   DONE;
5225 }")
5226
5227 (define_insn "initialize_trampoline_compact"
5228   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5229                      (match_operand:SI 1 "register_operand" "r")
5230                      (reg:SI R2_REG) (reg:SI R3_REG)]
5231                     UNSPEC_INIT_TRAMP)
5232
5233    (clobber (reg:SI PR_REG))]
5234   "TARGET_SHCOMPACT"
5235   "jsr @%1%#"
5236   [(set_attr "type" "sfunc")
5237    (set_attr "needs_delay_slot" "yes")])
5238
5239 (define_insn "movqi_i"
5240   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m,r,r,l")
5241         (match_operand:QI 1 "general_movsrc_operand"  "r,i,m,r,t,l,r"))]
5242   "TARGET_SH1
5243    && (arith_reg_operand (operands[0], QImode)
5244        || arith_reg_operand (operands[1], QImode))"
5245   "@
5246         mov     %1,%0
5247         mov     %1,%0
5248         mov.b   %1,%0
5249         mov.b   %1,%0
5250         movt    %0
5251         sts     %1,%0
5252         lds     %1,%0"
5253  [(set_attr "type" "move,movi8,load,store,arith,prget,prset")])
5254
5255 (define_insn "*movqi_media"
5256   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5257         (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5258   "TARGET_SHMEDIA
5259    && (arith_reg_operand (operands[0], QImode)
5260        || extend_reg_or_0_operand (operands[1], QImode))"
5261   "@
5262         add.l   %1, r63, %0
5263         movi    %1, %0
5264         ld%M1.ub        %m1, %0
5265         st%M0.b %m0, %N1"
5266   [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5267    (set (attr "highpart")
5268         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5269                (const_string "user")]
5270               (const_string "ignore")))])
5271
5272 (define_expand "movqi"
5273   [(set (match_operand:QI 0 "general_operand" "")
5274         (match_operand:QI 1 "general_operand"  ""))]
5275   ""
5276   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5277
5278 (define_expand "reload_inqi"
5279   [(set (match_operand:SI 2 "" "=&r")
5280         (match_operand:QI 1 "inqhi_operand" ""))
5281    (set (match_operand:QI 0 "arith_reg_operand" "=r")
5282         (truncate:QI (match_dup 3)))]
5283   "TARGET_SHMEDIA"
5284   "
5285 {
5286   rtx inner = XEXP (operands[1], 0);
5287   int regno = REGNO (inner);
5288
5289   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5290   operands[1] = gen_rtx_REG (SImode, regno);
5291   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5292 }")
5293
5294 /* When storing r0, we have to avoid reg+reg addressing.  */
5295 (define_insn "movhi_i"
5296   [(set (match_operand:HI 0 "general_movdst_operand"   "=r,r,r,r,m,r,l,r")
5297         (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5298   "TARGET_SH1
5299    && (arith_reg_operand (operands[0], HImode)
5300        || arith_reg_operand (operands[1], HImode))
5301    && (GET_CODE (operands[0]) != MEM
5302        || GET_CODE (XEXP (operands[0], 0)) != PLUS
5303        || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
5304        || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5305   "@
5306         mov.w   %1,%0
5307         mov     %1,%0
5308         mov.w   %1,%0
5309         movt    %0
5310         mov.w   %1,%0
5311         sts     %1,%0
5312         lds     %1,%0
5313         fake    %1,%0"
5314   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5315
5316 (define_insn "*movhi_media"
5317   [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
5318         (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5319   "TARGET_SHMEDIA
5320    && (arith_reg_operand (operands[0], HImode)
5321        || arith_reg_or_0_operand (operands[1], HImode))"
5322   "@
5323         add.l   %1, r63, %0
5324         movi    %1, %0
5325         #
5326         ld%M1.w %m1, %0
5327         st%M0.w %m0, %N1"
5328   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5329    (set (attr "highpart")
5330         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5331                (const_string "user")]
5332               (const_string "ignore")))])
5333
5334 (define_split
5335   [(set (match_operand:HI 0 "register_operand" "")
5336         (match_operand:HI 1 "immediate_operand" ""))]
5337   "TARGET_SHMEDIA && reload_completed
5338    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5339   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5340
5341 (define_expand "movhi"
5342   [(set (match_operand:HI 0 "general_movdst_operand" "")
5343         (match_operand:HI 1 "general_movsrc_operand"  ""))]
5344   ""
5345   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5346
5347 (define_expand "reload_inhi"
5348   [(set (match_operand:SI 2 "" "=&r")
5349         (match_operand:HI 1 "inqhi_operand" ""))
5350    (set (match_operand:HI 0 "arith_reg_operand" "=r")
5351         (truncate:HI (match_dup 3)))]
5352   "TARGET_SHMEDIA"
5353   "
5354 {
5355   rtx inner = XEXP (operands[1], 0);
5356   int regno = REGNO (inner);
5357
5358   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5359   operands[1] = gen_rtx_REG (SImode, regno);
5360   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5361 }")
5362
5363 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5364 ;; compiled with -m2 -ml -O3 -funroll-loops
5365 (define_insn "*movdi_i"
5366   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5367         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5368   "TARGET_SH1
5369    && (arith_reg_operand (operands[0], DImode)
5370        || arith_reg_operand (operands[1], DImode))"
5371   "* return output_movedouble (insn, operands, DImode);"
5372   [(set_attr "length" "4")
5373    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5374
5375 ;; If the output is a register and the input is memory or a register, we have
5376 ;; to be careful and see which word needs to be loaded first.
5377
5378 (define_split
5379   [(set (match_operand:DI 0 "general_movdst_operand" "")
5380         (match_operand:DI 1 "general_movsrc_operand" ""))]
5381   "TARGET_SH1 && reload_completed"
5382   [(set (match_dup 2) (match_dup 3))
5383    (set (match_dup 4) (match_dup 5))]
5384   "
5385 {
5386   int regno;
5387
5388   if ((GET_CODE (operands[0]) == MEM
5389        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5390       || (GET_CODE (operands[1]) == MEM
5391           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5392     FAIL;
5393
5394   switch (GET_CODE (operands[0]))
5395     {
5396     case REG:
5397       regno = REGNO (operands[0]);
5398       break;
5399     case SUBREG:
5400       regno = subreg_regno (operands[0]);
5401       break;
5402     case MEM:
5403       regno = -1;
5404       break;
5405     default:
5406       gcc_unreachable ();
5407     }
5408
5409   if (regno == -1
5410       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5411     {
5412       operands[2] = operand_subword (operands[0], 0, 0, DImode);
5413       operands[3] = operand_subword (operands[1], 0, 0, DImode);
5414       operands[4] = operand_subword (operands[0], 1, 0, DImode);
5415       operands[5] = operand_subword (operands[1], 1, 0, DImode);
5416     }
5417   else
5418     {
5419       operands[2] = operand_subword (operands[0], 1, 0, DImode);
5420       operands[3] = operand_subword (operands[1], 1, 0, DImode);
5421       operands[4] = operand_subword (operands[0], 0, 0, DImode);
5422       operands[5] = operand_subword (operands[1], 0, 0, DImode);
5423     }
5424
5425   if (operands[2] == 0 || operands[3] == 0
5426       || operands[4] == 0 || operands[5] == 0)
5427     FAIL;
5428 }")
5429
5430 ;; The '?'s in the following constraints may not reflect the time taken
5431 ;; to perform the move. They are there to discourage the use of floating-
5432 ;; point registers for storing integer values.
5433 (define_insn "*movdi_media"
5434   [(set (match_operand:DI 0 "general_movdst_operand"
5435                  "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5436         (match_operand:DI 1 "general_movsrc_operand"
5437          "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5438   "TARGET_SHMEDIA_FPU
5439    && (register_operand (operands[0], DImode)
5440        || sh_register_operand (operands[1], DImode))"
5441   "@
5442         add     %1, r63, %0
5443         movi    %1, %0
5444         #
5445         ld%M1.q %m1, %0
5446         st%M0.q %m0, %N1
5447         fld%M1.d        %m1, %0
5448         fst%M0.d        %m0, %1
5449         fmov.qd %N1, %0
5450         fmov.dq %1, %0
5451         fmov.d  %1, %0
5452         ptabs   %1, %0
5453         gettr   %1, %0
5454         pt      %1, %0"
5455   [(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")
5456    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5457
5458 (define_insn "*movdi_media_nofpu"
5459   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5460         (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5461   "TARGET_SHMEDIA
5462    && (register_operand (operands[0], DImode)
5463        || sh_register_operand (operands[1], DImode))"
5464   "@
5465         add     %1, r63, %0
5466         movi    %1, %0
5467         #
5468         ld%M1.q %m1, %0
5469         st%M0.q %m0, %N1
5470         ptabs   %1, %0
5471         gettr   %1, %0
5472         pt      %1, %0"
5473   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5474    (set_attr "length" "4,4,16,4,4,4,4,*")])
5475
5476 (define_insn "*movdi_media_I16"
5477   [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5478         (match_operand:DI 1 "const_int_operand" "I16"))]
5479   "TARGET_SHMEDIA && reload_completed"
5480   "movi %1, %0"
5481   [(set_attr "type" "arith_media")
5482    (set_attr "length" "4")])
5483
5484 (define_split
5485   [(set (match_operand:DI 0 "arith_reg_dest" "")
5486         (match_operand:DI 1 "immediate_operand" ""))]
5487   "TARGET_SHMEDIA && reload_completed
5488    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5489   [(set (match_dup 0) (match_dup 1))]
5490   "
5491 {
5492   rtx insn;
5493
5494   if (TARGET_SHMEDIA64)
5495     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5496   else
5497     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5498
5499   set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5500
5501   DONE;
5502 }")
5503
5504 (define_expand "movdi_const"
5505   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5506         (const:DI (sign_extend:DI
5507                    (truncate:HI
5508                     (ashiftrt:DI
5509                      (match_operand:DI 1 "immediate_operand" "s")
5510                      (const_int 48))))))
5511    (set (match_dup 0)
5512         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5513                 (const:DI
5514                  (zero_extend:DI
5515                   (truncate:HI
5516                    (ashiftrt:SI
5517                     (match_dup 1)
5518                     (const_int 32)))))))
5519    (set (match_dup 0)
5520         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5521                 (const:DI
5522                  (zero_extend:DI
5523                   (truncate:HI
5524                    (ashiftrt:SI
5525                     (match_dup 1)
5526                     (const_int 16)))))))
5527    (set (match_dup 0)
5528         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5529                 (const:DI
5530                  (zero_extend:DI
5531                   (truncate:HI
5532                    (match_dup 1))))))]
5533   "TARGET_SHMEDIA64 && reload_completed
5534    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5535   "
5536 {
5537   sh_mark_label (operands[1], 4);
5538 }")
5539
5540 (define_expand "movdi_const_32bit"
5541   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5542         (const:DI (sign_extend:DI
5543                    (truncate:HI
5544                     (ashiftrt:DI
5545                      (match_operand:DI 1 "immediate_operand" "s")
5546                      (const_int 16))))))
5547    (set (match_dup 0)
5548         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5549                 (const:DI
5550                  (zero_extend:DI
5551                   (truncate:HI
5552                    (match_dup 1))))))]
5553   "TARGET_SHMEDIA32 && reload_completed
5554    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5555   "
5556 {
5557   sh_mark_label (operands[1], 2);
5558 }")
5559
5560 (define_expand "movdi_const_16bit"
5561   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5562         (const:DI (sign_extend:DI
5563                    (truncate:HI
5564                     (match_operand:DI 1 "immediate_operand" "s")))))]
5565   "TARGET_SHMEDIA && flag_pic && reload_completed
5566    && GET_CODE (operands[1]) == SYMBOL_REF"
5567   "")
5568
5569 (define_split
5570   [(set (match_operand:DI 0 "ext_dest_operand" "")
5571         (match_operand:DI 1 "immediate_operand" ""))]
5572   "TARGET_SHMEDIA && reload_completed
5573    && GET_CODE (operands[1]) == CONST_INT
5574    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5575   [(set (match_dup 0) (match_dup 2))
5576    (match_dup 1)]
5577   "
5578 {
5579   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5580   unsigned HOST_WIDE_INT low = val;
5581   unsigned HOST_WIDE_INT high = val;
5582   unsigned HOST_WIDE_INT sign;
5583   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5584
5585   /* Zero-extend the 16 least-significant bits.  */
5586   low &= 0xffff;
5587
5588   /* Arithmetic shift right the word by 16 bits.  */
5589   high >>= 16;
5590   if (GET_CODE (operands[0]) == SUBREG
5591       && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5592     {
5593       high &= 0xffff;
5594       high ^= 0x8000;
5595       high -= 0x8000;
5596     }
5597   else
5598     {
5599       sign = 1;
5600       sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5601       high ^= sign;
5602       high -= sign;
5603     }
5604   do
5605     {
5606       /* If we can't generate the constant with a two-insn movi / shori
5607          sequence, try some other strategies.  */
5608       if (! CONST_OK_FOR_I16 (high))
5609         {
5610           /* Try constant load / left shift.  We know VAL != 0.  */
5611           val2 = val ^ (val-1);
5612           if (val2 > 0x1ffff)
5613             {
5614               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5615
5616               if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5617                   || (! CONST_OK_FOR_I16 (high >> 16)
5618                       && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5619                 {
5620                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5621                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
5622                                                    GEN_INT (trailing_zeroes));
5623                   break;
5624                 }
5625             }
5626           /* Try constant load / right shift.  */
5627           val2 = (val >> 15) + 1;
5628           if (val2 == (val2 & -val2))
5629             {
5630               int shift = 49 - exact_log2 (val2);
5631
5632               val2 = trunc_int_for_mode (val << shift, DImode);
5633               if (CONST_OK_FOR_I16 (val2))
5634                 {
5635                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5636                                                    GEN_INT (shift));
5637                   break;
5638                 }
5639             }
5640           /* Try mperm.w .  */
5641           val2 = val & 0xffff;
5642           if ((val >> 16 & 0xffff) == val2
5643               && (val >> 32 & 0xffff) == val2
5644               && (val >> 48 & 0xffff) == val2)
5645             {
5646               val2 = (HOST_WIDE_INT) val >> 48;
5647               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5648               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5649               break;
5650             }
5651           /* Try movi / mshflo.l  */
5652           val2 = (HOST_WIDE_INT) val >> 32;
5653           if (val2 == ((unsigned HOST_WIDE_INT)
5654                         trunc_int_for_mode (val, SImode)))
5655             {
5656               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5657                                              operands[0]);
5658               break;
5659             }
5660           /* Try movi / mshflo.l w/ r63.  */
5661           val2 = val + ((HOST_WIDE_INT) -1 << 32);
5662           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5663             {
5664               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5665                                              const0_rtx);
5666               break;
5667             }
5668         }
5669       val2 = high;
5670       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5671     }
5672   while (0);
5673   operands[2] = GEN_INT (val2);
5674 }")
5675
5676 (define_split
5677   [(set (match_operand:DI 0 "ext_dest_operand" "")
5678         (match_operand:DI 1 "immediate_operand" ""))]
5679   "TARGET_SHMEDIA && reload_completed
5680    && GET_CODE (operands[1]) == CONST_DOUBLE"
5681   [(set (match_dup 0) (match_dup 2))
5682   (set (match_dup 0)
5683        (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5684   "
5685 {
5686   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5687   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5688   unsigned HOST_WIDE_INT val = low;
5689   unsigned HOST_WIDE_INT sign;
5690
5691   /* Zero-extend the 16 least-significant bits.  */
5692   val &= 0xffff;
5693   operands[1] = GEN_INT (val);
5694
5695   /* Arithmetic shift right the double-word by 16 bits.  */
5696   low >>= 16;
5697   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5698   high >>= 16;
5699   sign = 1;
5700   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5701   high ^= sign;
5702   high -= sign;
5703
5704   /* This will only be true if high is a sign-extension of low, i.e.,
5705      it must be either 0 or (unsigned)-1, and be zero iff the
5706      most-significant bit of low is set.  */
5707   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5708     operands[2] = GEN_INT (low);
5709   else
5710     operands[2] = immed_double_const (low, high, DImode);
5711 }")
5712
5713 (define_insn "shori_media"
5714   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5715         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5716                            (const_int 16))
5717                 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5718   "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5719   "@
5720         shori   %u2, %0
5721         #"
5722   [(set_attr "type" "arith_media,*")])
5723
5724 (define_insn "*shori_media_si"
5725   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5726         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5727                            (const_int 16))
5728                 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5729   "TARGET_SHMEDIA"
5730   "shori        %u2, %0")
5731
5732 (define_expand "movdi"
5733   [(set (match_operand:DI 0 "general_movdst_operand" "")
5734         (match_operand:DI 1 "general_movsrc_operand" ""))]
5735   ""
5736   "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5737
5738 (define_insn "movdf_media"
5739   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5740         (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5741   "TARGET_SHMEDIA_FPU
5742    && (register_operand (operands[0], DFmode)
5743        || sh_register_operand (operands[1], DFmode))"
5744   "@
5745         fmov.d  %1, %0
5746         fmov.qd %N1, %0
5747         fmov.dq %1, %0
5748         add     %1, r63, %0
5749         #
5750         fld%M1.d        %m1, %0
5751         fst%M0.d        %m0, %1
5752         ld%M1.q %m1, %0
5753         st%M0.q %m0, %N1"
5754   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5755
5756 (define_insn "movdf_media_nofpu"
5757   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5758         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5759   "TARGET_SHMEDIA
5760    && (register_operand (operands[0], DFmode)
5761        || sh_register_operand (operands[1], DFmode))"
5762   "@
5763         add     %1, r63, %0
5764         #
5765         ld%M1.q %m1, %0
5766         st%M0.q %m0, %N1"
5767   [(set_attr "type" "arith_media,*,load_media,store_media")])
5768
5769 (define_split
5770   [(set (match_operand:DF 0 "arith_reg_dest" "")
5771         (match_operand:DF 1 "immediate_operand" ""))]
5772   "TARGET_SHMEDIA && reload_completed"
5773   [(set (match_dup 3) (match_dup 2))]
5774   "
5775 {
5776   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5777   long values[2];
5778   REAL_VALUE_TYPE value;
5779
5780   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5781   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5782
5783   if (HOST_BITS_PER_WIDE_INT >= 64)
5784     operands[2] = immed_double_const ((unsigned long) values[endian]
5785                                       | ((HOST_WIDE_INT) values[1 - endian]
5786                                          << 32), 0, DImode);
5787   else
5788     {
5789       gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5790       operands[2] = immed_double_const (values[endian], values[1 - endian],
5791                                         DImode);
5792     }
5793
5794   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5795 }")
5796
5797 ;; ??? This should be a define expand.
5798
5799 (define_insn "movdf_k"
5800   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5801         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5802   "TARGET_SH1
5803    && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5804        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5805        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
5806        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
5807    && (arith_reg_operand (operands[0], DFmode)
5808        || arith_reg_operand (operands[1], DFmode))"
5809   "* return output_movedouble (insn, operands, DFmode);"
5810   [(set_attr "length" "4")
5811    (set_attr "type" "move,pcload,load,store")])
5812
5813 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5814 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5815 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5816 ;; the d/m/c/X alternative, which is split later into single-precision
5817 ;; instructions.  And when not optimizing, no splits are done before fixing
5818 ;; up pcloads, so we need usable length information for that.
5819 (define_insn "movdf_i4"
5820   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5821         (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5822    (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5823    (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
5824   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5825    && (arith_reg_operand (operands[0], DFmode)
5826        || arith_reg_operand (operands[1], DFmode))"
5827   "@
5828         fmov    %1,%0
5829         #
5830         #
5831         fmov.d  %1,%0
5832         fmov.d  %1,%0
5833         #
5834         #
5835         #
5836         #
5837         #"
5838   [(set_attr_alternative "length"
5839      [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
5840       (const_int 4)
5841       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5842       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5843       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5844       (const_int 4)
5845       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5846       ;; We can't use 4-byte push/pop on SHcompact, so we have to
5847       ;; increment or decrement r15 explicitly.
5848       (if_then_else
5849        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5850        (const_int 10) (const_int 8))
5851       (if_then_else
5852        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5853        (const_int 10) (const_int 8))])
5854    (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
5855    (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5856    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5857                                            (const_string "double")
5858                                            (const_string "none")))])
5859
5860 ;; Moving DFmode between fp/general registers through memory
5861 ;; (the top of the stack) is faster than moving through fpul even for
5862 ;; little endian.  Because the type of an instruction is important for its
5863 ;; scheduling,  it is beneficial to split these operations, rather than
5864 ;; emitting them in one single chunk, even if this will expose a stack
5865 ;; use that will prevent scheduling of other stack accesses beyond this
5866 ;; instruction.
5867 (define_split
5868   [(set (match_operand:DF 0 "register_operand" "")
5869         (match_operand:DF 1 "register_operand" ""))
5870    (use (match_operand:PSI 2 "fpscr_operand" ""))
5871    (clobber (match_scratch:SI 3 "=X"))]
5872   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5873    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5874   [(const_int 0)]
5875   "
5876 {
5877   rtx insn, tos;
5878
5879   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5880     {
5881       emit_move_insn (stack_pointer_rtx,
5882                       plus_constant (stack_pointer_rtx, -8));
5883       tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5884     }
5885   else
5886     tos = gen_tmp_stack_mem (DFmode,
5887                              gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5888   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5889   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5890     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5891   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5892     tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5893   else
5894     tos = gen_tmp_stack_mem (DFmode,
5895                              gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5896   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5897   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5898     emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5899   else
5900     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5901   DONE;
5902 }")
5903
5904 ;; local-alloc sometimes allocates scratch registers even when not required,
5905 ;; so we must be prepared to handle these.
5906
5907 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5908 (define_split
5909   [(set (match_operand:DF 0 "general_movdst_operand" "")
5910         (match_operand:DF 1 "general_movsrc_operand"  ""))
5911    (use (match_operand:PSI 2 "fpscr_operand" ""))
5912    (clobber (match_scratch:SI 3 ""))]
5913   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5914    && reload_completed
5915    && true_regnum (operands[0]) < 16
5916    && true_regnum (operands[1]) < 16"
5917   [(set (match_dup 0) (match_dup 1))]
5918   "
5919 {
5920   /* If this was a reg <-> mem operation with base + index reg addressing,
5921      we have to handle this in a special way.  */
5922   rtx mem = operands[0];
5923   int store_p = 1;
5924   if (! memory_operand (mem, DFmode))
5925     {
5926       mem = operands[1];
5927       store_p = 0;
5928     }
5929   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
5930     mem = SUBREG_REG (mem);
5931   if (GET_CODE (mem) == MEM)
5932     {
5933       rtx addr = XEXP (mem, 0);
5934       if (GET_CODE (addr) == PLUS
5935           && GET_CODE (XEXP (addr, 0)) == REG
5936           && GET_CODE (XEXP (addr, 1)) == REG)
5937         {
5938           int offset;
5939           rtx reg0 = gen_rtx_REG (Pmode, 0);
5940           rtx regop = operands[store_p], word0 ,word1;
5941
5942           if (GET_CODE (regop) == SUBREG)
5943             alter_subreg (&regop);
5944           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
5945             offset = 2;
5946           else
5947             offset = 4;
5948           mem = copy_rtx (mem);
5949           PUT_MODE (mem, SImode);
5950           word0 = gen_rtx_SUBREG (SImode, regop, 0);
5951           alter_subreg (&word0);
5952           word1 = gen_rtx_SUBREG (SImode, regop, 4);
5953           alter_subreg (&word1);
5954           if (store_p || ! refers_to_regno_p (REGNO (word0),
5955                                               REGNO (word0) + 1, addr, 0))
5956             {
5957               emit_insn (store_p
5958                          ? gen_movsi_ie (mem, word0)
5959                          : gen_movsi_ie (word0, mem));
5960               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5961               mem = copy_rtx (mem);
5962               emit_insn (store_p
5963                          ? gen_movsi_ie (mem, word1)
5964                          : gen_movsi_ie (word1, mem));
5965               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5966             }
5967           else
5968             {
5969               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5970               emit_insn (gen_movsi_ie (word1, mem));
5971               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5972               mem = copy_rtx (mem);
5973               emit_insn (gen_movsi_ie (word0, mem));
5974             }
5975           DONE;
5976         }
5977     }
5978 }")
5979
5980 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
5981 (define_split
5982   [(set (match_operand:DF 0 "register_operand" "")
5983         (match_operand:DF 1 "memory_operand"  ""))
5984    (use (match_operand:PSI 2 "fpscr_operand" ""))
5985    (clobber (reg:SI R0_REG))]
5986   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
5987   [(parallel [(set (match_dup 0) (match_dup 1))
5988               (use (match_dup 2))
5989               (clobber (scratch:SI))])]
5990   "")
5991
5992 (define_expand "reload_indf__frn"
5993   [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
5994                    (match_operand:DF 1 "immediate_operand" "FQ"))
5995               (use (reg:PSI FPSCR_REG))
5996               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5997   "TARGET_SH1"
5998   "")
5999
6000 (define_expand "reload_outdf__RnFRm"
6001   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
6002                    (match_operand:DF 1 "register_operand" "af,r"))
6003               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
6004   "TARGET_SH1"
6005   "")
6006
6007 ;; Simplify no-op moves.
6008 (define_split
6009   [(set (match_operand:SF 0 "register_operand" "")
6010         (match_operand:SF 1 "register_operand" ""))
6011    (use (match_operand:PSI 2 "fpscr_operand" ""))
6012    (clobber (match_scratch:SI 3 ""))]
6013   "TARGET_SH2E && reload_completed
6014    && true_regnum (operands[0]) == true_regnum (operands[1])"
6015   [(set (match_dup 0) (match_dup 0))]
6016   "")
6017
6018 ;; fmovd substitute post-reload splits
6019 (define_split
6020   [(set (match_operand:DF 0 "register_operand" "")
6021         (match_operand:DF 1 "register_operand" ""))
6022    (use (match_operand:PSI 2 "fpscr_operand" ""))
6023    (clobber (match_scratch:SI 3 ""))]
6024   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
6025    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6026    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6027   [(const_int 0)]
6028   "
6029 {
6030   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
6031   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
6032                            gen_rtx_REG (SFmode, src), operands[2]));
6033   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
6034                            gen_rtx_REG (SFmode, src + 1), operands[2]));
6035   DONE;
6036 }")
6037
6038 (define_split
6039   [(set (match_operand:DF 0 "register_operand" "")
6040         (mem:DF (match_operand:SI 1 "register_operand" "")))
6041    (use (match_operand:PSI 2 "fpscr_operand" ""))
6042    (clobber (match_scratch:SI 3 ""))]
6043   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6044    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6045    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
6046   [(const_int 0)]
6047   "
6048 {
6049   int regno = true_regnum (operands[0]);
6050   rtx insn;
6051   rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
6052   rtx mem2
6053     = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6054   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6055                                            regno + !! TARGET_LITTLE_ENDIAN),
6056                                   mem2, operands[2]));
6057   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
6058   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6059                                                regno + ! TARGET_LITTLE_ENDIAN),
6060                                   change_address (mem, SFmode, NULL_RTX),
6061                                   operands[2]));
6062   DONE;
6063 }")
6064
6065 (define_split
6066   [(set (match_operand:DF 0 "register_operand" "")
6067         (match_operand:DF 1 "memory_operand" ""))
6068    (use (match_operand:PSI 2 "fpscr_operand" ""))
6069    (clobber (match_scratch:SI 3 ""))]
6070   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6071    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6072   [(const_int 0)]
6073   "
6074 {
6075   int regno = true_regnum (operands[0]);
6076   rtx addr, insn, adjust = NULL_RTX;
6077   rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6078   rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
6079   rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
6080
6081   operands[1] = copy_rtx (mem2);
6082   addr = XEXP (mem2, 0);
6083   if (GET_CODE (addr) != POST_INC)
6084     {
6085       /* If we have to modify the stack pointer, the value that we have
6086          read with post-increment might be modified by an interrupt,
6087          so write it back.  */
6088       if (REGNO (addr) == STACK_POINTER_REGNUM)
6089         adjust = gen_push_e (reg0);
6090       else
6091         adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
6092       XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6093     }
6094   addr = XEXP (addr, 0);
6095   insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6096   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6097   insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6098   if (adjust)
6099     emit_insn (adjust);
6100   else
6101     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6102   DONE;
6103 }")
6104
6105 (define_split
6106   [(set (match_operand:DF 0 "memory_operand" "")
6107         (match_operand:DF 1 "register_operand" ""))
6108    (use (match_operand:PSI 2 "fpscr_operand" ""))
6109    (clobber (match_scratch:SI 3 ""))]
6110   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6111    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6112   [(const_int 0)]
6113   "
6114 {
6115   int regno = true_regnum (operands[1]);
6116   rtx insn, addr, adjust = NULL_RTX;
6117
6118   operands[0] = copy_rtx (operands[0]);
6119   PUT_MODE (operands[0], SFmode);
6120   insn = emit_insn (gen_movsf_ie (operands[0],
6121                                   gen_rtx_REG (SFmode,
6122                                            regno + ! TARGET_LITTLE_ENDIAN),
6123                                   operands[2]));
6124   operands[0] = copy_rtx (operands[0]);
6125   addr = XEXP (operands[0], 0);
6126   if (GET_CODE (addr) != PRE_DEC)
6127     {
6128       adjust = gen_addsi3 (addr, addr, GEN_INT (4));
6129       emit_insn_before (adjust, insn);
6130       XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6131     }
6132   addr = XEXP (addr, 0);
6133   if (! adjust)
6134     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6135   insn = emit_insn (gen_movsf_ie (operands[0],
6136                                   gen_rtx_REG (SFmode,
6137                                            regno + !! TARGET_LITTLE_ENDIAN),
6138                                   operands[2]));
6139   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6140   DONE;
6141 }")
6142
6143 ;; If the output is a register and the input is memory or a register, we have
6144 ;; to be careful and see which word needs to be loaded first.
6145
6146 (define_split
6147   [(set (match_operand:DF 0 "general_movdst_operand" "")
6148         (match_operand:DF 1 "general_movsrc_operand" ""))]
6149   "TARGET_SH1 && reload_completed"
6150   [(set (match_dup 2) (match_dup 3))
6151    (set (match_dup 4) (match_dup 5))]
6152   "
6153 {
6154   int regno;
6155
6156   if ((GET_CODE (operands[0]) == MEM
6157        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6158       || (GET_CODE (operands[1]) == MEM
6159           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6160     FAIL;
6161
6162   switch (GET_CODE (operands[0]))
6163     {
6164     case REG:
6165       regno = REGNO (operands[0]);
6166       break;
6167     case SUBREG:
6168       regno = subreg_regno (operands[0]);
6169       break;
6170     case MEM:
6171       regno = -1;
6172       break;
6173     default:
6174       gcc_unreachable ();
6175     }
6176
6177   if (regno == -1
6178       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6179     {
6180       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6181       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6182       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6183       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6184     }
6185   else
6186     {
6187       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6188       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6189       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6190       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6191     }
6192
6193   if (operands[2] == 0 || operands[3] == 0
6194       || operands[4] == 0 || operands[5] == 0)
6195     FAIL;
6196 }")
6197
6198 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6199 ;; used only once, let combine add in the index again.
6200
6201 (define_split
6202   [(set (match_operand:SI 0 "register_operand" "")
6203         (match_operand:SI 1 "" ""))
6204    (clobber (match_operand 2 "register_operand" ""))]
6205   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6206    && ALLOW_INDEXED_ADDRESS"
6207   [(use (reg:SI R0_REG))]
6208   "
6209 {
6210   rtx addr, reg, const_int;
6211
6212   if (GET_CODE (operands[1]) != MEM)
6213     FAIL;
6214   addr = XEXP (operands[1], 0);
6215   if (GET_CODE (addr) != PLUS)
6216     FAIL;
6217   reg = XEXP (addr, 0);
6218   const_int = XEXP (addr, 1);
6219   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6220          && GET_CODE (const_int) == CONST_INT))
6221     FAIL;
6222   emit_move_insn (operands[2], const_int);
6223   emit_move_insn (operands[0],
6224                   change_address (operands[1], VOIDmode,
6225                                   gen_rtx_PLUS (SImode, reg, operands[2])));
6226   DONE;
6227 }")
6228
6229 (define_split
6230   [(set (match_operand:SI 1 "" "")
6231         (match_operand:SI 0 "register_operand" ""))
6232    (clobber (match_operand 2 "register_operand" ""))]
6233   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6234    && ALLOW_INDEXED_ADDRESS"
6235   [(use (reg:SI R0_REG))]
6236   "
6237 {
6238   rtx addr, reg, const_int;
6239
6240   if (GET_CODE (operands[1]) != MEM)
6241     FAIL;
6242   addr = XEXP (operands[1], 0);
6243   if (GET_CODE (addr) != PLUS)
6244     FAIL;
6245   reg = XEXP (addr, 0);
6246   const_int = XEXP (addr, 1);
6247   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6248          && GET_CODE (const_int) == CONST_INT))
6249     FAIL;
6250   emit_move_insn (operands[2], const_int);
6251   emit_move_insn (change_address (operands[1], VOIDmode,
6252                                   gen_rtx_PLUS (SImode, reg, operands[2])),
6253                   operands[0]);
6254   DONE;
6255 }")
6256
6257 (define_expand "movdf"
6258   [(set (match_operand:DF 0 "general_movdst_operand" "")
6259         (match_operand:DF 1 "general_movsrc_operand" ""))]
6260   ""
6261   "
6262 {
6263   if (prepare_move_operands (operands, DFmode)) DONE;
6264   if (TARGET_SHMEDIA)
6265     {
6266       if (TARGET_SHMEDIA_FPU)
6267         emit_insn (gen_movdf_media (operands[0], operands[1]));
6268       else
6269         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6270       DONE;
6271     }
6272   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6273     {
6274       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6275       DONE;
6276     }
6277 }")
6278
6279 ;;This is incompatible with the way gcc uses subregs.
6280 ;;(define_insn "movv2sf_i"
6281 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6282 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6283 ;;  "TARGET_SHMEDIA_FPU
6284 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
6285 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
6286 ;;  "@
6287 ;;      #
6288 ;;      fld%M1.p        %m1, %0
6289 ;;      fst%M0.p        %m0, %1"
6290 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
6291
6292 (define_insn_and_split "movv2sf_i"
6293   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6294         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6295   "TARGET_SHMEDIA_FPU"
6296   "#"
6297   "TARGET_SHMEDIA_FPU && reload_completed"
6298   [(set (match_dup 0) (match_dup 1))]
6299   "
6300 {
6301   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6302   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6303 }")
6304
6305 (define_expand "movv2sf"
6306   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6307         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6308   "TARGET_SHMEDIA_FPU"
6309   "
6310 {
6311   if (prepare_move_operands (operands, V2SFmode))
6312     DONE;
6313 }")
6314
6315 (define_expand "addv2sf3"
6316   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6317    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6318    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6319   "TARGET_SHMEDIA_FPU"
6320   "
6321 {
6322   sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6323   DONE;
6324 }")
6325
6326 (define_expand "subv2sf3"
6327   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6328    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6329    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6330   "TARGET_SHMEDIA_FPU"
6331   "
6332 {
6333   sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6334   DONE;
6335 }")
6336
6337 (define_expand "mulv2sf3"
6338   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6339    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6340    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6341   "TARGET_SHMEDIA_FPU"
6342   "
6343 {
6344   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6345   DONE;
6346 }")
6347
6348 (define_expand "divv2sf3"
6349   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6350    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6351    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6352   "TARGET_SHMEDIA_FPU"
6353   "
6354 {
6355   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6356   DONE;
6357 }")
6358
6359 (define_insn_and_split "*movv4sf_i"
6360   [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6361         (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6362   "TARGET_SHMEDIA_FPU"
6363   "#"
6364   "&& reload_completed"
6365   [(const_int 0)]
6366   "
6367 {
6368   int i;
6369
6370   for (i = 0; i < 4/2; i++)
6371     {
6372       rtx x, y;
6373
6374       if (GET_CODE (operands[0]) == MEM)
6375         x = adjust_address (operands[0], V2SFmode,
6376                             i * GET_MODE_SIZE (V2SFmode));
6377       else
6378         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6379
6380       if (GET_CODE (operands[1]) == MEM)
6381         y = adjust_address (operands[1], V2SFmode,
6382                             i * GET_MODE_SIZE (V2SFmode));
6383       else
6384         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6385
6386       emit_insn (gen_movv2sf_i (x, y));
6387     }
6388
6389   DONE;
6390 }"
6391   [(set_attr "length" "8")])
6392
6393 (define_expand "movv4sf"
6394   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6395         (match_operand:V4SF 1 "general_operand" ""))]
6396   "TARGET_SHMEDIA_FPU"
6397   "
6398 {
6399   if (prepare_move_operands (operands, V4SFmode))
6400     DONE;
6401 }")
6402
6403 (define_insn_and_split "*movv16sf_i"
6404   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6405         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6406   "TARGET_SHMEDIA_FPU"
6407   "#"
6408   "&& reload_completed"
6409   [(const_int 0)]
6410   "
6411 {
6412   int i;
6413
6414   for (i = 0; i < 16/2; i++)
6415     {
6416       rtx x,y;
6417
6418       if (GET_CODE (operands[0]) == MEM)
6419         x = adjust_address (operands[0], V2SFmode,
6420                             i * GET_MODE_SIZE (V2SFmode));
6421       else
6422         {
6423           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6424           alter_subreg (&x);
6425         }
6426
6427       if (GET_CODE (operands[1]) == MEM)
6428         y = adjust_address (operands[1], V2SFmode,
6429                             i * GET_MODE_SIZE (V2SFmode));
6430       else
6431         {
6432           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6433           alter_subreg (&y);
6434         }
6435
6436       emit_insn (gen_movv2sf_i (x, y));
6437     }
6438
6439   DONE;
6440 }"
6441   [(set_attr "length" "32")])
6442
6443 (define_expand "movv16sf"
6444   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6445         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6446   "TARGET_SHMEDIA_FPU"
6447   "
6448 {
6449   if (prepare_move_operands (operands, V16SFmode))
6450     DONE;
6451 }")
6452
6453 (define_insn "movsf_media"
6454   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6455         (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6456   "TARGET_SHMEDIA_FPU
6457    && (register_operand (operands[0], SFmode)
6458        || sh_register_operand (operands[1], SFmode))"
6459   "@
6460         fmov.s  %1, %0
6461         fmov.ls %N1, %0
6462         fmov.sl %1, %0
6463         add.l   %1, r63, %0
6464         #
6465         fld%M1.s        %m1, %0
6466         fst%M0.s        %m0, %1
6467         ld%M1.l %m1, %0
6468         st%M0.l %m0, %N1"
6469   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6470    (set (attr "highpart")
6471         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6472                (const_string "user")]
6473               (const_string "ignore")))])
6474
6475 (define_insn "movsf_media_nofpu"
6476   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6477         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6478   "TARGET_SHMEDIA
6479    && (register_operand (operands[0], SFmode)
6480        || sh_register_operand (operands[1], SFmode))"
6481   "@
6482         add.l   %1, r63, %0
6483         #
6484         ld%M1.l %m1, %0
6485         st%M0.l %m0, %N1"
6486   [(set_attr "type" "arith_media,*,load_media,store_media")
6487    (set (attr "highpart")
6488         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6489                (const_string "user")]
6490               (const_string "ignore")))])
6491
6492 (define_split
6493   [(set (match_operand:SF 0 "arith_reg_dest" "")
6494         (match_operand:SF 1 "immediate_operand" ""))]
6495   "TARGET_SHMEDIA && reload_completed
6496    && ! FP_REGISTER_P (true_regnum (operands[0]))"
6497   [(set (match_dup 3) (match_dup 2))]
6498   "
6499 {
6500   long values;
6501   REAL_VALUE_TYPE value;
6502
6503   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6504   REAL_VALUE_TO_TARGET_SINGLE (value, values);
6505   operands[2] = GEN_INT (values);
6506
6507   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6508 }")
6509
6510 (define_insn "movsf_i"
6511   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6512         (match_operand:SF 1 "general_movsrc_operand"  "r,G,FQ,mr,r,r,l"))]
6513   "TARGET_SH1
6514    && (! TARGET_SH2E
6515        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6516        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
6517        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
6518    && (arith_reg_operand (operands[0], SFmode)
6519        || arith_reg_operand (operands[1], SFmode))"
6520   "@
6521         mov     %1,%0
6522         mov     #0,%0
6523         mov.l   %1,%0
6524         mov.l   %1,%0
6525         mov.l   %1,%0
6526         lds     %1,%0
6527         sts     %1,%0"
6528   [(set_attr "type" "move,move,pcload,load,store,move,move")])
6529
6530 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6531 ;; update_flow_info would not know where to put REG_EQUAL notes
6532 ;; when the destination changes mode.
6533 (define_insn "movsf_ie"
6534   [(set (match_operand:SF 0 "general_movdst_operand"
6535          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6536         (match_operand:SF 1 "general_movsrc_operand"
6537           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6538    (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"))
6539    (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6540
6541   "TARGET_SH2E
6542    && (arith_reg_operand (operands[0], SFmode)
6543        || arith_reg_operand (operands[1], SFmode)
6544        || arith_reg_operand (operands[3], SImode)
6545        || (fpul_operand (operands[0], SFmode)
6546            && memory_operand (operands[1], SFmode)
6547            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6548        || (fpul_operand (operands[1], SFmode)
6549            && memory_operand (operands[0], SFmode)
6550            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6551   "@
6552         fmov    %1,%0
6553         mov     %1,%0
6554         fldi0   %0
6555         fldi1   %0
6556         #
6557         fmov.s  %1,%0
6558         fmov.s  %1,%0
6559         mov.l   %1,%0
6560         mov.l   %1,%0
6561         mov.l   %1,%0
6562         fsts    fpul,%0
6563         flds    %1,fpul
6564         lds.l   %1,%0
6565         #
6566         sts     %1,%0
6567         lds     %1,%0
6568         sts.l   %1,%0
6569         lds.l   %1,%0
6570         ! move optimized away"
6571   [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
6572    (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6573    (set_attr "length" "*,*,*,*,4,4,4,*,*,*,2,2,2,4,2,2,2,2,0")
6574    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6575                                            (const_string "single")
6576                                            (const_string "none")))])
6577
6578 (define_split
6579   [(set (match_operand:SF 0 "register_operand" "")
6580         (match_operand:SF 1 "register_operand" ""))
6581    (use (match_operand:PSI 2 "fpscr_operand" ""))
6582    (clobber (reg:SI FPUL_REG))]
6583   "TARGET_SH1"
6584   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6585               (use (match_dup 2))
6586               (clobber (scratch:SI))])
6587    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6588               (use (match_dup 2))
6589               (clobber (scratch:SI))])]
6590   "")
6591
6592 (define_expand "movsf"
6593   [(set (match_operand:SF 0 "general_movdst_operand" "")
6594         (match_operand:SF 1 "general_movsrc_operand" ""))]
6595   ""
6596   "
6597 {
6598   if (prepare_move_operands (operands, SFmode))
6599     DONE;
6600   if (TARGET_SHMEDIA)
6601     {
6602       if (TARGET_SHMEDIA_FPU)
6603         emit_insn (gen_movsf_media (operands[0], operands[1]));
6604       else
6605         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6606       DONE;
6607     }
6608   if (TARGET_SH2E)
6609     {
6610       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6611       DONE;
6612     }
6613 }")
6614
6615 (define_insn "mov_nop"
6616   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6617   "TARGET_SH2E"
6618   ""
6619   [(set_attr "length" "0")
6620    (set_attr "type" "nil")])
6621
6622 (define_expand "reload_insf__frn"
6623   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6624                    (match_operand:SF 1 "immediate_operand" "FQ"))
6625               (use (reg:PSI FPSCR_REG))
6626               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6627   "TARGET_SH1"
6628   "")
6629
6630 (define_expand "reload_insi__i_fpul"
6631   [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6632                    (match_operand:SI 1 "immediate_operand" "i"))
6633               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6634   "TARGET_SH1"
6635   "")
6636
6637 (define_expand "ptabs"
6638   [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6639   "TARGET_SHMEDIA"
6640   "
6641 {
6642   if (!TARGET_PT_FIXED)
6643     {
6644       rtx eq = operands[1];
6645
6646       /* ??? For canonical RTL we really should remove any CONST from EQ
6647          before wrapping it in the AND, and finally wrap the EQ into a
6648          const if is constant.  However, for reload we must expose the
6649          input register or symbolic constant, and we can't have
6650          different insn structures outside of the operands for different
6651          alternatives of the same pattern.  */
6652       eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6653                        GEN_INT (3));
6654       operands[1]
6655         = (gen_rtx_IF_THEN_ELSE
6656             (PDImode,
6657              eq,
6658              gen_rtx_MEM (PDImode, operands[1]),
6659              gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6660                             PDImode, operands[1])));
6661     }
6662 }")
6663
6664 ;; expanded by ptabs expander.
6665 (define_insn "*extendsipdi_media"
6666   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6667         (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6668                                                           "r,Csy")
6669                                       (const_int 3))
6670                               (const_int 3))
6671                           (mem:PDI (match_dup 1))
6672                           (sign_extend:PDI (match_dup 1))))]
6673   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6674   "@
6675         ptabs   %1, %0
6676         pt      %1, %0"
6677   [(set_attr "type"   "ptabs_media,pt_media")
6678    (set_attr "length" "4,*")])
6679
6680 (define_insn "*truncdipdi_media"
6681   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6682         (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6683                                                           "r,Csy")
6684                                       (const_int 3))
6685                               (const_int 3))
6686                           (mem:PDI (match_dup 1))
6687                           (truncate:PDI (match_dup 1))))]
6688   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6689   "@
6690         ptabs   %1, %0
6691         pt      %1, %0"
6692   [(set_attr "type"   "ptabs_media,pt_media")
6693    (set_attr "length" "4,*")])
6694
6695 (define_insn "*movsi_y"
6696   [(set (match_operand:SI 0 "register_operand" "=y,y")
6697         (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6698    (clobber (match_scratch:SI 2 "=&z,r"))]
6699   "TARGET_SH2E
6700    && (reload_in_progress || reload_completed)"
6701   "#"
6702   [(set_attr "length" "4")
6703    (set_attr "type" "pcload,move")])
6704
6705 (define_split
6706   [(set (match_operand:SI 0 "register_operand" "")
6707         (match_operand:SI 1 "immediate_operand" ""))
6708    (clobber (match_operand:SI 2 "register_operand" ""))]
6709   "TARGET_SH1"
6710   [(set (match_dup 2) (match_dup 1))
6711    (set (match_dup 0) (match_dup 2))]
6712   "")
6713
6714 (define_split
6715   [(set (match_operand:SI 0 "register_operand" "")
6716         (match_operand:SI 1 "memory_operand" ""))
6717    (clobber (reg:SI R0_REG))]
6718   "TARGET_SH1"
6719   [(set (match_dup 0) (match_dup 1))]
6720   "")
6721 \f
6722 ;; ------------------------------------------------------------------------
6723 ;; Define the real conditional branch instructions.
6724 ;; ------------------------------------------------------------------------
6725
6726 (define_insn "branch_true"
6727   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6728                            (label_ref (match_operand 0 "" ""))
6729                            (pc)))]
6730   "TARGET_SH1"
6731   "* return output_branch (1, insn, operands);"
6732   [(set_attr "type" "cbranch")])
6733
6734 (define_insn "branch_false"
6735   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6736                            (label_ref (match_operand 0 "" ""))
6737                            (pc)))]
6738   "TARGET_SH1"
6739   "* return output_branch (0, insn, operands);"
6740   [(set_attr "type" "cbranch")])
6741
6742 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6743 ;; which destination is too far away.
6744 ;; The const_int_operand is distinct for each branch target; it avoids
6745 ;; unwanted matches with redundant_insn.
6746 (define_insn "block_branch_redirect"
6747   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6748   "TARGET_SH1"
6749   ""
6750   [(set_attr "length" "0")])
6751
6752 ;; This one has the additional purpose to record a possible scratch register
6753 ;; for the following branch.
6754 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6755 ;; because the insn then might be deemed dead and deleted.  And we can't
6756 ;; make the use in the jump insn explicit because that would disable
6757 ;; delay slot scheduling from the target.
6758 (define_insn "indirect_jump_scratch"
6759   [(set (match_operand:SI 0 "register_operand" "=r")
6760         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6761    (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6762   "TARGET_SH1"
6763   ""
6764   [(set_attr "length" "0")])
6765
6766 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6767 ;; being pulled into the delay slot of a condbranch that has been made to
6768 ;; jump around the unconditional jump because it was out of range.
6769 (define_insn "stuff_delay_slot"
6770   [(set (pc)
6771         (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
6772    (set (reg:SI T_REG) (match_operand:SI 1 "const_int_operand" ""))]
6773   "TARGET_SH1"
6774   ""
6775   [(set_attr "length" "0")
6776    (set_attr "cond_delay_slot" "yes")])
6777 \f
6778 ;; Conditional branch insns
6779
6780 (define_expand "beq_media"
6781   [(set (pc)
6782         (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
6783                           (match_operand:DI 2 "arith_operand" "r,I06"))
6784                       (match_operand 0 "" "")
6785                       (pc)))]
6786   "TARGET_SHMEDIA"
6787   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6788
6789 (define_insn "*beq_media_i"
6790   [(set (pc)
6791         (if_then_else (match_operator 3 "equality_comparison_operator"
6792                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
6793                          (match_operand:DI 2 "arith_operand" "r,I06")])
6794                       (match_operand 0 "target_operand" "b,b")
6795                       (pc)))]
6796   "TARGET_SHMEDIA"
6797   "@
6798         b%o3%'  %1, %2, %0%>
6799         b%o3i%' %1, %2, %0%>"
6800   [(set_attr "type" "cbranch_media")])
6801
6802 (define_insn "*beq_media_i32"
6803   [(set (pc)
6804         (if_then_else (match_operator 3 "equality_comparison_operator"
6805                         [(match_operand:SI 1 "arith_reg_operand" "r,r")
6806                          (match_operand:SI 2 "arith_operand" "r,I06")])
6807                       (match_operand 0 "target_operand" "b,b")
6808                       (pc)))]
6809   "TARGET_SHMEDIA"
6810   "@
6811         b%o3%'  %1, %2, %0%>
6812         b%o3i%' %1, %2, %0%>"
6813   [(set_attr "type" "cbranch_media")])
6814
6815 (define_expand "bne_media"
6816   [(set (pc)
6817         (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
6818                           (match_operand:DI 2 "arith_operand" "r,I06"))
6819                       (match_operand 0 "" "")
6820                       (pc)))]
6821   "TARGET_SHMEDIA"
6822   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6823
6824 (define_expand "bgt_media"
6825   [(set (pc)
6826         (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "")
6827                           (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6828                       (match_operand 0 "" "")
6829                       (pc)))]
6830   "TARGET_SHMEDIA"
6831   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6832
6833 (define_expand "bge_media"
6834   [(set (pc)
6835         (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "")
6836                           (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6837                       (match_operand 0 "" "")
6838                       (pc)))]
6839   "TARGET_SHMEDIA"
6840   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6841
6842 (define_expand "bgtu_media"
6843   [(set (pc)
6844         (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6845                            (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6846                       (match_operand 0 "" "")
6847                       (pc)))]
6848   "TARGET_SHMEDIA"
6849   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6850
6851 (define_expand "bgeu_media"
6852   [(set (pc)
6853         (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6854                            (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6855                       (match_operand 0 "" "")
6856                       (pc)))]
6857   "TARGET_SHMEDIA"
6858   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6859
6860 (define_insn "*bgt_media_i"
6861   [(set (pc)
6862         (if_then_else (match_operator 3 "greater_comparison_operator"
6863                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6864                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6865                       (match_operand 0 "target_operand" "b")
6866                       (pc)))]
6867   "TARGET_SHMEDIA"
6868   "b%o3%'       %N1, %N2, %0%>"
6869   [(set_attr "type" "cbranch_media")])
6870
6871 (define_insn "*bgt_media_i32"
6872   [(set (pc)
6873         (if_then_else (match_operator 3 "greater_comparison_operator"
6874                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6875                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6876                       (match_operand 0 "target_operand" "b")
6877                       (pc)))]
6878   "TARGET_SHMEDIA"
6879   "b%o3%'       %N1, %N2, %0%>"
6880   [(set_attr "type" "cbranch_media")])
6881
6882 ;; These are only needed to make invert_jump() happy - otherwise, jump
6883 ;; optimization will be silently disabled.
6884 (define_insn "*blt_media_i"
6885   [(set (pc)
6886         (if_then_else (match_operator 3 "less_comparison_operator"
6887                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6888                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6889                       (match_operand 0 "target_operand" "b")
6890                       (pc)))]
6891   "TARGET_SHMEDIA"
6892   "b%o3%'       %N2, %N1, %0%>"
6893   [(set_attr "type" "cbranch_media")])
6894
6895 (define_insn "*blt_media_i32"
6896   [(set (pc)
6897         (if_then_else (match_operator 3 "less_comparison_operator"
6898                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6899                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6900                       (match_operand 0 "target_operand" "b")
6901                       (pc)))]
6902   "TARGET_SHMEDIA"
6903   "b%o3%'       %N2, %N1, %0%>"
6904   [(set_attr "type" "cbranch_media")])
6905
6906 (define_expand "beq"
6907   [(set (pc)
6908         (if_then_else (ne (reg:SI T_REG) (const_int 0))
6909                       (label_ref (match_operand 0 "" ""))
6910                       (pc)))]
6911   ""
6912   "
6913 {
6914   if (TARGET_SHMEDIA)
6915     {
6916       enum machine_mode mode = GET_MODE (sh_compare_op0);
6917
6918       if (mode != DImode && mode != SImode)
6919         {
6920           rtx tmp = gen_reg_rtx (DImode);
6921
6922           emit_insn (gen_seq (tmp));
6923           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6924           DONE;
6925         }
6926
6927       sh_compare_op0 = force_reg (mode, sh_compare_op0);
6928       if (CONSTANT_P (sh_compare_op1)
6929           && (GET_CODE (sh_compare_op1) != CONST_INT
6930               || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6931         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6932       emit_jump_insn (gen_beq_media (operands[0],
6933                                      sh_compare_op0, sh_compare_op1));
6934       DONE;
6935     }
6936
6937   from_compare (operands, EQ);
6938 }")
6939
6940 (define_expand "bne"
6941   [(set (pc)
6942         (if_then_else (eq (reg:SI T_REG) (const_int 0))
6943                       (label_ref (match_operand 0 "" ""))
6944                       (pc)))]
6945   ""
6946   "
6947 {
6948   if (TARGET_SHMEDIA)
6949     {
6950       enum machine_mode mode = GET_MODE (sh_compare_op0);
6951
6952       if (mode != DImode && mode != SImode)
6953         {
6954           rtx tmp = gen_reg_rtx (DImode);
6955
6956           emit_insn (gen_seq (tmp));
6957           emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
6958           DONE;
6959         }
6960
6961       sh_compare_op0 = force_reg (mode, sh_compare_op0);
6962       if (CONSTANT_P (sh_compare_op1)
6963           && (GET_CODE (sh_compare_op1) != CONST_INT
6964               || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6965         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6966       emit_jump_insn (gen_bne_media (operands[0],
6967                                      sh_compare_op0, sh_compare_op1));
6968       DONE;
6969     }
6970
6971   from_compare (operands, EQ);
6972 }")
6973
6974 (define_expand "bgt"
6975   [(set (pc)
6976         (if_then_else (ne (reg:SI T_REG) (const_int 0))
6977                       (label_ref (match_operand 0 "" ""))
6978                       (pc)))]
6979   ""
6980   "
6981 {
6982   if (TARGET_SHMEDIA)
6983     {
6984       enum machine_mode mode = GET_MODE (sh_compare_op0);
6985
6986       if (mode != DImode && mode != SImode)
6987         {
6988           rtx tmp = gen_reg_rtx (DImode);
6989
6990           emit_insn (gen_sgt (tmp));
6991           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6992           DONE;
6993         }
6994
6995       if (sh_compare_op0 != const0_rtx)
6996         sh_compare_op0 = force_reg (mode, sh_compare_op0);
6997       if (sh_compare_op1 != const0_rtx)
6998         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6999       emit_jump_insn (gen_bgt_media (operands[0],
7000                                      sh_compare_op0, sh_compare_op1));
7001       DONE;
7002     }
7003
7004   from_compare (operands, GT);
7005 }")
7006
7007 (define_expand "blt"
7008   [(set (pc)
7009         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7010                       (label_ref (match_operand 0 "" ""))
7011                       (pc)))]
7012   ""
7013   "
7014 {
7015   if (TARGET_SHMEDIA)
7016     {
7017       enum machine_mode mode = GET_MODE (sh_compare_op0);
7018
7019       if (mode != DImode && mode != SImode)
7020         {
7021           rtx tmp = gen_reg_rtx (DImode);
7022
7023           emit_insn (gen_slt (tmp));
7024           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7025           DONE;
7026         }
7027
7028       if (sh_compare_op0 != const0_rtx)
7029         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7030       if (sh_compare_op1 != const0_rtx)
7031         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7032       emit_jump_insn (gen_bgt_media (operands[0],
7033                                      sh_compare_op1, sh_compare_op0));
7034       DONE;
7035     }
7036
7037   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7038     {
7039       rtx tmp = sh_compare_op0;
7040       sh_compare_op0 = sh_compare_op1;
7041       sh_compare_op1 = tmp;
7042       emit_insn (gen_bgt (operands[0]));
7043       DONE;
7044     }
7045   from_compare (operands, GE);
7046 }")
7047
7048 (define_expand "ble"
7049   [(set (pc)
7050         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7051                       (label_ref (match_operand 0 "" ""))
7052                       (pc)))]
7053   ""
7054   "
7055 {
7056   if (TARGET_SHMEDIA)
7057     {
7058       enum machine_mode mode = GET_MODE (sh_compare_op0);
7059
7060       if (mode != DImode && mode != SImode)
7061         {
7062           rtx tmp = gen_reg_rtx (DImode);
7063
7064           emit_insn (gen_sle (tmp));
7065           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7066           DONE;
7067         }
7068
7069       if (sh_compare_op0 != const0_rtx)
7070         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7071       if (sh_compare_op1 != const0_rtx)
7072         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7073       emit_jump_insn (gen_bge_media (operands[0],
7074                                      sh_compare_op1, sh_compare_op0));
7075       DONE;
7076     }
7077
7078   if (TARGET_SH2E
7079       && TARGET_IEEE
7080       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7081     {
7082       rtx tmp = sh_compare_op0;
7083       sh_compare_op0 = sh_compare_op1;
7084       sh_compare_op1 = tmp;
7085       emit_insn (gen_bge (operands[0]));
7086       DONE;
7087     }
7088   from_compare (operands, GT);
7089 }")
7090
7091 (define_expand "bge"
7092   [(set (pc)
7093         (if_then_else (ne (reg:SI T_REG) (const_int 0))
7094                       (label_ref (match_operand 0 "" ""))
7095                       (pc)))]
7096   ""
7097   "
7098 {
7099   if (TARGET_SHMEDIA)
7100     {
7101       enum machine_mode mode = GET_MODE (sh_compare_op0);
7102
7103       if (mode != DImode && mode != SImode)
7104         {
7105           rtx tmp = gen_reg_rtx (DImode);
7106
7107           emit_insn (gen_sge (tmp));
7108           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7109           DONE;
7110         }
7111
7112       if (sh_compare_op0 != const0_rtx)
7113         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7114       if (sh_compare_op1 != const0_rtx)
7115         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7116       emit_jump_insn (gen_bge_media (operands[0],
7117                                      sh_compare_op0, sh_compare_op1));
7118       DONE;
7119     }
7120
7121   if (TARGET_SH2E
7122       && ! TARGET_IEEE
7123       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7124     {
7125       rtx tmp = sh_compare_op0;
7126       sh_compare_op0 = sh_compare_op1;
7127       sh_compare_op1 = tmp;
7128       emit_insn (gen_ble (operands[0]));
7129       DONE;
7130     }
7131   from_compare (operands, GE);
7132 }")
7133
7134 (define_expand "bgtu"
7135   [(set (pc)
7136         (if_then_else (ne (reg:SI T_REG) (const_int 0))
7137                       (label_ref (match_operand 0 "" ""))
7138                       (pc)))]
7139   ""
7140   "
7141 {
7142   if (TARGET_SHMEDIA)
7143     {
7144       enum machine_mode mode = GET_MODE (sh_compare_op0);
7145
7146       if (sh_compare_op0 != const0_rtx)
7147         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7148       if (sh_compare_op1 != const0_rtx)
7149         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7150       emit_jump_insn (gen_bgtu_media (operands[0],
7151                                       sh_compare_op0, sh_compare_op1));
7152       DONE;
7153     }
7154
7155   from_compare (operands, GTU);
7156 }")
7157
7158 (define_expand "bltu"
7159   [(set (pc)
7160         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7161                       (label_ref (match_operand 0 "" ""))
7162                       (pc)))]
7163   ""
7164   "
7165 {
7166   if (TARGET_SHMEDIA)
7167     {
7168       enum machine_mode mode = GET_MODE (sh_compare_op0);
7169
7170       if (sh_compare_op0 != const0_rtx)
7171         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7172       if (sh_compare_op1 != const0_rtx)
7173         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7174       emit_jump_insn (gen_bgtu_media (operands[0],
7175                                       sh_compare_op1, sh_compare_op0));
7176       DONE;
7177     }
7178
7179   from_compare (operands, GEU);
7180 }")
7181
7182 (define_expand "bgeu"
7183   [(set (pc)
7184         (if_then_else (ne (reg:SI T_REG) (const_int 0))
7185                       (label_ref (match_operand 0 "" ""))
7186                       (pc)))]
7187   ""
7188   "
7189 {
7190   if (TARGET_SHMEDIA)
7191     {
7192       enum machine_mode mode = GET_MODE (sh_compare_op0);
7193
7194       if (sh_compare_op0 != const0_rtx)
7195         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7196       if (sh_compare_op1 != const0_rtx)
7197         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7198       emit_jump_insn (gen_bgeu_media (operands[0],
7199                                       sh_compare_op0, sh_compare_op1));
7200       DONE;
7201     }
7202
7203   from_compare (operands, GEU);
7204 }")
7205
7206 (define_expand "bleu"
7207   [(set (pc)
7208         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7209                       (label_ref (match_operand 0 "" ""))
7210                       (pc)))]
7211   ""
7212   "
7213 {
7214   if (TARGET_SHMEDIA)
7215     {
7216       enum machine_mode mode = GET_MODE (sh_compare_op0);
7217
7218       if (sh_compare_op0 != const0_rtx)
7219         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7220       if (sh_compare_op1 != const0_rtx)
7221         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7222       emit_jump_insn (gen_bgeu_media (operands[0],
7223                                       sh_compare_op1, sh_compare_op0));
7224       DONE;
7225     }
7226
7227   from_compare (operands, GTU);
7228 }")
7229
7230 (define_expand "bunordered"
7231   [(set (match_dup 1) (unordered:SI (match_dup 2) (match_dup 3)))
7232    (set (pc)
7233         (if_then_else (ne (match_dup 1) (const_int 0))
7234                       (match_operand 0 "" "")
7235                       (pc)))]
7236   "TARGET_SHMEDIA"
7237   "
7238 {
7239   operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);
7240   operands[1] = gen_reg_rtx (SImode);
7241   operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7242   operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7243 }")
7244
7245 ;; combiner splitter for test-and-branch on single bit in register.  This
7246 ;; is endian dependent because the non-paradoxical subreg looks different
7247 ;; on big endian.
7248 (define_split
7249   [(set (pc)
7250         (if_then_else
7251           (match_operator 3 "equality_comparison_operator"
7252             [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7253                                                       "extend_reg_operand" "")
7254                                                     0)
7255                                          (const_int 1)
7256                                          (match_operand 2
7257                                           "const_int_operand" "")) 0)
7258              (const_int 0)])
7259           (match_operand 0 "target_operand" "")
7260           (pc)))
7261    (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7262   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7263   [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7264    (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7265
7266   "
7267 {
7268   operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7269   operands[6] = (GET_CODE (operands[3]) == EQ
7270                  ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7271                  : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7272 }")
7273 \f
7274 ;; ------------------------------------------------------------------------
7275 ;; Jump and linkage insns
7276 ;; ------------------------------------------------------------------------
7277
7278 (define_insn "jump_compact"
7279   [(set (pc)
7280         (label_ref (match_operand 0 "" "")))]
7281   "TARGET_SH1"
7282   "*
7283 {
7284   /* The length is 16 if the delay slot is unfilled.  */
7285   if (get_attr_length(insn) > 4)
7286     return output_far_jump(insn, operands[0]);
7287   else
7288     return   \"bra      %l0%#\";
7289 }"
7290   [(set_attr "type" "jump")
7291    (set_attr "needs_delay_slot" "yes")])
7292
7293 ;; ??? It would be much saner to explicitly use the scratch register
7294 ;; in the jump insn, and have indirect_jump_scratch only set it,
7295 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7296 ;; from the target then, as it uses simplejump_p.
7297 ;;(define_insn "jump_compact_far"
7298 ;;  [(set (pc)
7299 ;;      (label_ref (match_operand 0 "" "")))
7300 ;;   (use (match_operand 1 "register_operand" "r")]
7301 ;;  "TARGET_SH1"
7302 ;;  "* return output_far_jump(insn, operands[0], operands[1]);"
7303 ;;  [(set_attr "type" "jump")
7304 ;;   (set_attr "needs_delay_slot" "yes")])
7305
7306 (define_insn "jump_media"
7307   [(set (pc)
7308         (match_operand 0 "target_operand" "b"))]
7309   "TARGET_SHMEDIA"
7310   "blink        %0, r63%>"
7311   [(set_attr "type" "jump_media")])
7312
7313 (define_expand "jump"
7314   [(set (pc)
7315         (label_ref (match_operand 0 "" "")))]
7316   ""
7317   "
7318 {
7319   if (TARGET_SH1)
7320     emit_jump_insn (gen_jump_compact (operands[0]));
7321   else if (TARGET_SHMEDIA)
7322     {
7323       if (reload_in_progress || reload_completed)
7324         FAIL;
7325       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7326                                                          operands[0])));
7327     }
7328   DONE;
7329 }")
7330
7331 (define_insn "force_mode_for_call"
7332   [(use (reg:PSI FPSCR_REG))]
7333   "TARGET_SHCOMPACT"
7334   ""
7335   [(set_attr "length" "0")
7336    (set (attr "fp_mode")
7337         (if_then_else (eq_attr "fpu_single" "yes")
7338                       (const_string "single") (const_string "double")))])
7339
7340 (define_insn "calli"
7341   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7342          (match_operand 1 "" ""))
7343    (use (reg:PSI FPSCR_REG))
7344    (clobber (reg:SI PR_REG))]
7345   "TARGET_SH1"
7346   "jsr  @%0%#"
7347   [(set_attr "type" "call")
7348    (set (attr "fp_mode")
7349         (if_then_else (eq_attr "fpu_single" "yes")
7350                       (const_string "single") (const_string "double")))
7351    (set_attr "needs_delay_slot" "yes")
7352    (set_attr "fp_set" "unknown")])
7353
7354 ;; This is a pc-rel call, using bsrf, for use with PIC.
7355
7356 (define_insn "calli_pcrel"
7357   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7358          (match_operand 1 "" ""))
7359    (use (reg:PSI FPSCR_REG))
7360    (use (reg:SI PIC_REG))
7361    (use (match_operand 2 "" ""))
7362    (clobber (reg:SI PR_REG))]
7363   "TARGET_SH2"
7364   "bsrf %0\\n%O2:%#"
7365   [(set_attr "type" "call")
7366    (set (attr "fp_mode")
7367         (if_then_else (eq_attr "fpu_single" "yes")
7368                       (const_string "single") (const_string "double")))
7369    (set_attr "needs_delay_slot" "yes")
7370    (set_attr "fp_set" "unknown")])
7371
7372 (define_insn_and_split "call_pcrel"
7373   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7374          (match_operand 1 "" ""))
7375    (use (reg:PSI FPSCR_REG))
7376    (use (reg:SI PIC_REG))
7377    (clobber (reg:SI PR_REG))
7378    (clobber (match_scratch:SI 2 "=r"))]
7379   "TARGET_SH2"
7380   "#"
7381   "reload_completed"
7382   [(const_int 0)]
7383   "
7384 {
7385   rtx lab = PATTERN (gen_call_site ());
7386
7387   if (SYMBOL_REF_LOCAL_P (operands[0]))
7388     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7389   else
7390     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7391   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
7392   DONE;
7393 }"
7394   [(set_attr "type" "call")
7395    (set (attr "fp_mode")
7396         (if_then_else (eq_attr "fpu_single" "yes")
7397                       (const_string "single") (const_string "double")))
7398    (set_attr "needs_delay_slot" "yes")
7399    (set_attr "fp_set" "unknown")])
7400
7401 (define_insn "call_compact"
7402   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7403          (match_operand 1 "" ""))
7404    (match_operand 2 "immediate_operand" "n")
7405    (use (reg:SI R0_REG))
7406    (use (reg:SI R1_REG))
7407    (use (reg:PSI FPSCR_REG))
7408    (clobber (reg:SI PR_REG))]
7409   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7410   "jsr  @%0%#"
7411   [(set_attr "type" "call")
7412    (set (attr "fp_mode")
7413         (if_then_else (eq_attr "fpu_single" "yes")
7414                       (const_string "single") (const_string "double")))
7415    (set_attr "needs_delay_slot" "yes")])
7416
7417 (define_insn "call_compact_rettramp"
7418   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7419          (match_operand 1 "" ""))
7420    (match_operand 2 "immediate_operand" "n")
7421    (use (reg:SI R0_REG))
7422    (use (reg:SI R1_REG))
7423    (use (reg:PSI FPSCR_REG))
7424    (clobber (reg:SI R10_REG))
7425    (clobber (reg:SI PR_REG))]
7426   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7427   "jsr  @%0%#"
7428   [(set_attr "type" "call")
7429    (set (attr "fp_mode")
7430         (if_then_else (eq_attr "fpu_single" "yes")
7431                       (const_string "single") (const_string "double")))
7432    (set_attr "needs_delay_slot" "yes")])
7433
7434 (define_insn "call_media"
7435   [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7436          (match_operand 1 "" ""))
7437    (clobber (reg:DI PR_MEDIA_REG))]
7438   "TARGET_SHMEDIA"
7439   "blink        %0, r18"
7440   [(set_attr "type" "jump_media")])
7441
7442 (define_insn "call_valuei"
7443   [(set (match_operand 0 "" "=rf")
7444         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7445               (match_operand 2 "" "")))
7446    (use (reg:PSI FPSCR_REG))
7447    (clobber (reg:SI PR_REG))]
7448   "TARGET_SH1"
7449   "jsr  @%1%#"
7450   [(set_attr "type" "call")
7451    (set (attr "fp_mode")
7452         (if_then_else (eq_attr "fpu_single" "yes")
7453                       (const_string "single") (const_string "double")))
7454    (set_attr "needs_delay_slot" "yes")
7455    (set_attr "fp_set" "unknown")])
7456
7457 (define_insn "call_valuei_pcrel"
7458   [(set (match_operand 0 "" "=rf")
7459         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7460               (match_operand 2 "" "")))
7461    (use (reg:PSI FPSCR_REG))
7462    (use (reg:SI PIC_REG))
7463    (use (match_operand 3 "" ""))
7464    (clobber (reg:SI PR_REG))]
7465   "TARGET_SH2"
7466   "bsrf %1\\n%O3:%#"
7467   [(set_attr "type" "call")
7468    (set (attr "fp_mode")
7469         (if_then_else (eq_attr "fpu_single" "yes")
7470                       (const_string "single") (const_string "double")))
7471    (set_attr "needs_delay_slot" "yes")
7472    (set_attr "fp_set" "unknown")])
7473
7474 (define_insn_and_split "call_value_pcrel"
7475   [(set (match_operand 0 "" "=rf")
7476         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7477               (match_operand 2 "" "")))
7478    (use (reg:PSI FPSCR_REG))
7479    (use (reg:SI PIC_REG))
7480    (clobber (reg:SI PR_REG))
7481    (clobber (match_scratch:SI 3 "=r"))]
7482   "TARGET_SH2"
7483   "#"
7484   "reload_completed"
7485   [(const_int 0)]
7486   "
7487 {
7488   rtx lab = PATTERN (gen_call_site ());
7489
7490   if (SYMBOL_REF_LOCAL_P (operands[1]))
7491     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7492   else
7493     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7494   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7495                                          operands[2], copy_rtx (lab)));
7496   DONE;
7497 }"
7498   [(set_attr "type" "call")
7499    (set (attr "fp_mode")
7500         (if_then_else (eq_attr "fpu_single" "yes")
7501                       (const_string "single") (const_string "double")))
7502    (set_attr "needs_delay_slot" "yes")
7503    (set_attr "fp_set" "unknown")])
7504
7505 (define_insn "call_value_compact"
7506   [(set (match_operand 0 "" "=rf")
7507         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7508               (match_operand 2 "" "")))
7509    (match_operand 3 "immediate_operand" "n")
7510    (use (reg:SI R0_REG))
7511    (use (reg:SI R1_REG))
7512    (use (reg:PSI FPSCR_REG))
7513    (clobber (reg:SI PR_REG))]
7514   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7515   "jsr  @%1%#"
7516   [(set_attr "type" "call")
7517    (set (attr "fp_mode")
7518         (if_then_else (eq_attr "fpu_single" "yes")
7519                       (const_string "single") (const_string "double")))
7520    (set_attr "needs_delay_slot" "yes")])
7521
7522 (define_insn "call_value_compact_rettramp"
7523   [(set (match_operand 0 "" "=rf")
7524         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7525               (match_operand 2 "" "")))
7526    (match_operand 3 "immediate_operand" "n")
7527    (use (reg:SI R0_REG))
7528    (use (reg:SI R1_REG))
7529    (use (reg:PSI FPSCR_REG))
7530    (clobber (reg:SI R10_REG))
7531    (clobber (reg:SI PR_REG))]
7532   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7533   "jsr  @%1%#"
7534   [(set_attr "type" "call")
7535    (set (attr "fp_mode")
7536         (if_then_else (eq_attr "fpu_single" "yes")
7537                       (const_string "single") (const_string "double")))
7538    (set_attr "needs_delay_slot" "yes")])
7539
7540 (define_insn "call_value_media"
7541   [(set (match_operand 0 "" "=rf")
7542         (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7543               (match_operand 2 "" "")))
7544    (clobber (reg:DI PR_MEDIA_REG))]
7545   "TARGET_SHMEDIA"
7546   "blink        %1, r18"
7547   [(set_attr "type" "jump_media")])
7548
7549 (define_expand "call"
7550   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7551                             (match_operand 1 "" ""))
7552               (match_operand 2 "" "")
7553               (use (reg:PSI FPSCR_REG))
7554               (clobber (reg:SI PR_REG))])]
7555   ""
7556   "
7557 {
7558   if (TARGET_SHMEDIA)
7559     {
7560       operands[0] = shmedia_prepare_call_address (operands[0], 0);
7561       emit_call_insn (gen_call_media (operands[0], operands[1]));
7562       DONE;
7563     }
7564   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7565     {
7566       rtx cookie_rtx = operands[2];
7567       long cookie = INTVAL (cookie_rtx);
7568       rtx func = XEXP (operands[0], 0);
7569       rtx r0, r1;
7570
7571       if (flag_pic)
7572         {
7573           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7574             {
7575               rtx reg = gen_reg_rtx (Pmode);
7576
7577               emit_insn (gen_symGOTPLT2reg (reg, func));
7578               func = reg;
7579             }
7580           else
7581             func = legitimize_pic_address (func, Pmode, 0);
7582         }
7583
7584       r0 = gen_rtx_REG (SImode, R0_REG);
7585       r1 = gen_rtx_REG (SImode, R1_REG);
7586
7587       /* Since such a call function may use all call-clobbered
7588          registers, we force a mode switch earlier, so that we don't
7589          run out of registers when adjusting fpscr for the call.  */
7590       emit_insn (gen_force_mode_for_call ());
7591
7592       operands[0]
7593         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7594                            SFUNC_GOT);
7595       operands[0] = force_reg (SImode, operands[0]);
7596
7597       emit_move_insn (r0, func);
7598       emit_move_insn (r1, cookie_rtx);
7599
7600       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7601         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7602                                                    operands[2]));
7603       else
7604         emit_call_insn (gen_call_compact (operands[0], operands[1],
7605                                           operands[2]));
7606
7607       DONE;
7608     }
7609   else if (TARGET_SHCOMPACT && flag_pic
7610            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7611            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7612     {
7613       rtx reg = gen_reg_rtx (Pmode);
7614
7615       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7616       XEXP (operands[0], 0) = reg;
7617     }
7618   if (flag_pic && TARGET_SH2
7619       && GET_CODE (operands[0]) == MEM
7620       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7621     {
7622       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7623       DONE;
7624     }
7625   else
7626   {
7627     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7628     operands[1] = operands[2];
7629   }
7630
7631   emit_call_insn (gen_calli (operands[0], operands[1]));
7632   DONE;
7633 }")
7634
7635 (define_insn "call_pop_compact"
7636   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7637          (match_operand 1 "" ""))
7638    (match_operand 2 "immediate_operand" "n")
7639    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7640                                  (match_operand 3 "immediate_operand" "n")))
7641    (use (reg:SI R0_REG))
7642    (use (reg:SI R1_REG))
7643    (use (reg:PSI FPSCR_REG))
7644    (clobber (reg:SI PR_REG))]
7645   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7646   "jsr  @%0%#"
7647   [(set_attr "type" "call")
7648    (set (attr "fp_mode")
7649         (if_then_else (eq_attr "fpu_single" "yes")
7650                       (const_string "single") (const_string "double")))
7651    (set_attr "needs_delay_slot" "yes")])
7652
7653 (define_insn "call_pop_compact_rettramp"
7654   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7655          (match_operand 1 "" ""))
7656    (match_operand 2 "immediate_operand" "n")
7657    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7658                                  (match_operand 3 "immediate_operand" "n")))
7659    (use (reg:SI R0_REG))
7660    (use (reg:SI R1_REG))
7661    (use (reg:PSI FPSCR_REG))
7662    (clobber (reg:SI R10_REG))
7663    (clobber (reg:SI PR_REG))]
7664   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7665   "jsr  @%0%#"
7666   [(set_attr "type" "call")
7667    (set (attr "fp_mode")
7668         (if_then_else (eq_attr "fpu_single" "yes")
7669                       (const_string "single") (const_string "double")))
7670    (set_attr "needs_delay_slot" "yes")])
7671
7672 (define_expand "call_pop"
7673   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7674                     (match_operand 1 "" ""))
7675              (match_operand 2 "" "")
7676              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7677                                            (match_operand 3 "" "")))])]
7678   "TARGET_SHCOMPACT"
7679   "
7680 {
7681   rtx cookie_rtx;
7682   long cookie;
7683   rtx func;
7684   rtx r0, r1;
7685
7686   gcc_assert (operands[2] && INTVAL (operands[2]));
7687   cookie_rtx = operands[2];
7688   cookie = INTVAL (cookie_rtx);
7689   func = XEXP (operands[0], 0);
7690
7691   if (flag_pic)
7692     {
7693       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7694         {
7695           rtx reg = gen_reg_rtx (Pmode);
7696           emit_insn (gen_symGOTPLT2reg (reg, func));
7697           func = reg;
7698         }
7699       else
7700         func = legitimize_pic_address (func, Pmode, 0);
7701     }
7702
7703   r0 = gen_rtx_REG (SImode, R0_REG);
7704   r1 = gen_rtx_REG (SImode, R1_REG);
7705
7706   /* Since such a call function may use all call-clobbered
7707      registers, we force a mode switch earlier, so that we don't
7708      run out of registers when adjusting fpscr for the call.  */
7709   emit_insn (gen_force_mode_for_call ());
7710
7711   operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7712                                  SFUNC_GOT);
7713   operands[0] = force_reg (SImode, operands[0]);
7714
7715   emit_move_insn (r0, func);
7716   emit_move_insn (r1, cookie_rtx);
7717
7718   if (cookie & CALL_COOKIE_RET_TRAMP (1))
7719     emit_call_insn (gen_call_pop_compact_rettramp
7720                      (operands[0], operands[1], operands[2], operands[3]));
7721   else
7722     emit_call_insn (gen_call_pop_compact
7723                      (operands[0], operands[1], operands[2], operands[3]));
7724
7725   DONE;
7726 }")
7727
7728 (define_expand "call_value"
7729   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7730                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7731                                  (match_operand 2 "" "")))
7732               (match_operand 3 "" "")
7733               (use (reg:PSI FPSCR_REG))
7734               (clobber (reg:SI PR_REG))])]
7735   ""
7736   "
7737 {
7738   if (TARGET_SHMEDIA)
7739     {
7740       operands[1] = shmedia_prepare_call_address (operands[1], 0);
7741       emit_call_insn (gen_call_value_media (operands[0], operands[1],
7742                                             operands[2]));
7743       DONE;
7744     }
7745   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7746     {
7747       rtx cookie_rtx = operands[3];
7748       long cookie = INTVAL (cookie_rtx);
7749       rtx func = XEXP (operands[1], 0);
7750       rtx r0, r1;
7751
7752       if (flag_pic)
7753         {
7754           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7755             {
7756               rtx reg = gen_reg_rtx (Pmode);
7757
7758               emit_insn (gen_symGOTPLT2reg (reg, func));
7759               func = reg;
7760             }
7761           else
7762             func = legitimize_pic_address (func, Pmode, 0);
7763         }
7764
7765       r0 = gen_rtx_REG (SImode, R0_REG);
7766       r1 = gen_rtx_REG (SImode, R1_REG);
7767
7768       /* Since such a call function may use all call-clobbered
7769          registers, we force a mode switch earlier, so that we don't
7770          run out of registers when adjusting fpscr for the call.  */
7771       emit_insn (gen_force_mode_for_call ());
7772
7773       operands[1]
7774         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7775                            SFUNC_GOT);
7776       operands[1] = force_reg (SImode, operands[1]);
7777
7778       emit_move_insn (r0, func);
7779       emit_move_insn (r1, cookie_rtx);
7780
7781       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7782         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7783                                                          operands[1],
7784                                                          operands[2],
7785                                                          operands[3]));
7786       else
7787         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7788                                                 operands[2], operands[3]));
7789
7790       DONE;
7791     }
7792   else if (TARGET_SHCOMPACT && flag_pic
7793            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7794            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7795     {
7796       rtx reg = gen_reg_rtx (Pmode);
7797
7798       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7799       XEXP (operands[1], 0) = reg;
7800     }
7801   if (flag_pic && TARGET_SH2
7802       && GET_CODE (operands[1]) == MEM
7803       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7804     {
7805       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7806                                             operands[2]));
7807       DONE;
7808     }
7809   else
7810     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7811
7812   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7813   DONE;
7814 }")
7815
7816 (define_insn "sibcalli"
7817   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7818          (match_operand 1 "" ""))
7819    (use (reg:PSI FPSCR_REG))
7820    (return)]
7821   "TARGET_SH1"
7822   "jmp  @%0%#"
7823   [(set_attr "needs_delay_slot" "yes")
7824    (set (attr "fp_mode")
7825         (if_then_else (eq_attr "fpu_single" "yes")
7826                       (const_string "single") (const_string "double")))
7827    (set_attr "type" "jump_ind")])
7828
7829 (define_insn "sibcalli_pcrel"
7830   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7831          (match_operand 1 "" ""))
7832    (use (match_operand 2 "" ""))
7833    (use (reg:PSI FPSCR_REG))
7834    (return)]
7835   "TARGET_SH2"
7836   "braf %0\\n%O2:%#"
7837   [(set_attr "needs_delay_slot" "yes")
7838    (set (attr "fp_mode")
7839         (if_then_else (eq_attr "fpu_single" "yes")
7840                       (const_string "single") (const_string "double")))
7841    (set_attr "type" "jump_ind")])
7842
7843 ;; This uses an unspec to describe that the symbol_ref is very close.
7844 (define_insn "sibcalli_thunk"
7845   [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7846                              UNSPEC_THUNK))
7847          (match_operand 1 "" ""))
7848    (use (reg:PSI FPSCR_REG))
7849    (return)]
7850   "TARGET_SH1"
7851   "bra  %O0"
7852   [(set_attr "needs_delay_slot" "yes")
7853    (set (attr "fp_mode")
7854         (if_then_else (eq_attr "fpu_single" "yes")
7855                       (const_string "single") (const_string "double")))
7856    (set_attr "type" "jump")
7857    (set_attr "length" "2")])
7858
7859 (define_insn_and_split "sibcall_pcrel"
7860   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7861          (match_operand 1 "" ""))
7862    (use (reg:PSI FPSCR_REG))
7863    (clobber (match_scratch:SI 2 "=k"))
7864    (return)]
7865   "TARGET_SH2"
7866   "#"
7867   "reload_completed"
7868   [(const_int 0)]
7869   "
7870 {
7871   rtx lab = PATTERN (gen_call_site ());
7872   rtx call_insn;
7873
7874   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7875   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7876                                                   copy_rtx (lab)));
7877   SIBLING_CALL_P (call_insn) = 1;
7878   DONE;
7879 }"
7880   [(set_attr "needs_delay_slot" "yes")
7881    (set (attr "fp_mode")
7882         (if_then_else (eq_attr "fpu_single" "yes")
7883                       (const_string "single") (const_string "double")))
7884    (set_attr "type" "jump_ind")])
7885
7886 (define_insn "sibcall_compact"
7887   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7888          (match_operand 1 "" ""))
7889    (return)
7890    (use (match_operand:SI 2 "register_operand" "z,x"))
7891    (use (reg:SI R1_REG))
7892    (use (reg:PSI FPSCR_REG))
7893    ;; We want to make sure the `x' above will only match MACH_REG
7894    ;; because sibcall_epilogue may clobber MACL_REG.
7895    (clobber (reg:SI MACL_REG))]
7896   "TARGET_SHCOMPACT"
7897   "@
7898         jmp     @%0%#
7899         jmp     @%0\\n  sts     %2, r0"
7900   [(set_attr "needs_delay_slot" "yes,no")
7901    (set_attr "length" "2,4")
7902    (set (attr "fp_mode") (const_string "single"))
7903    (set_attr "type" "jump_ind")])
7904
7905 (define_insn "sibcall_media"
7906   [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7907          (match_operand 1 "" ""))
7908    (use (reg:SI PR_MEDIA_REG))
7909    (return)]
7910   "TARGET_SHMEDIA"
7911   "blink        %0, r63"
7912   [(set_attr "type" "jump_media")])
7913
7914 (define_expand "sibcall"
7915   [(parallel
7916     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7917            (match_operand 1 "" ""))
7918      (match_operand 2 "" "")
7919      (use (reg:PSI FPSCR_REG))
7920      (return)])]
7921   ""
7922   "
7923 {
7924   if (TARGET_SHMEDIA)
7925     {
7926       operands[0] = shmedia_prepare_call_address (operands[0], 1);
7927       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7928       DONE;
7929     }
7930   else if (TARGET_SHCOMPACT && operands[2]
7931            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7932     {
7933       rtx cookie_rtx = operands[2];
7934       long cookie = INTVAL (cookie_rtx);
7935       rtx func = XEXP (operands[0], 0);
7936       rtx mach, r1;
7937
7938       if (flag_pic)
7939         {
7940           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7941             {
7942               rtx reg = gen_reg_rtx (Pmode);
7943
7944               emit_insn (gen_symGOT2reg (reg, func));
7945               func = reg;
7946             }
7947           else
7948             func = legitimize_pic_address (func, Pmode, 0);
7949         }
7950
7951       /* FIXME: if we could tell whether all argument registers are
7952          already taken, we could decide whether to force the use of
7953          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
7954          simple way to tell.  We could use the CALL_COOKIE, but we
7955          can't currently tell a register used for regular argument
7956          passing from one that is unused.  If we leave it up to reload
7957          to decide which register to use, it seems to always choose
7958          R0_REG, which leaves no available registers in SIBCALL_REGS
7959          to hold the address of the trampoline.  */
7960       mach = gen_rtx_REG (SImode, MACH_REG);
7961       r1 = gen_rtx_REG (SImode, R1_REG);
7962
7963       /* Since such a call function may use all call-clobbered
7964          registers, we force a mode switch earlier, so that we don't
7965          run out of registers when adjusting fpscr for the call.  */
7966       emit_insn (gen_force_mode_for_call ());
7967
7968       operands[0]
7969         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7970                            SFUNC_GOT);
7971       operands[0] = force_reg (SImode, operands[0]);
7972
7973       /* We don't need a return trampoline, since the callee will
7974          return directly to the upper caller.  */
7975       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7976         {
7977           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
7978           cookie_rtx = GEN_INT (cookie);
7979         }
7980
7981       emit_move_insn (mach, func);
7982       emit_move_insn (r1, cookie_rtx);
7983
7984       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
7985       DONE;
7986     }
7987   else if (TARGET_SHCOMPACT && flag_pic
7988            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7989            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7990     {
7991       rtx reg = gen_reg_rtx (Pmode);
7992
7993       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
7994       XEXP (operands[0], 0) = reg;
7995     }
7996   if (flag_pic && TARGET_SH2
7997       && GET_CODE (operands[0]) == MEM
7998       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7999       /* The PLT needs the PIC register, but the epilogue would have
8000          to restore it, so we can only use PC-relative PIC calls for
8001          static functions.  */
8002       && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8003     {
8004       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
8005       DONE;
8006     }
8007   else
8008     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
8009
8010   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
8011   DONE;
8012 }")
8013
8014 (define_expand "sibcall_value"
8015   [(set (match_operand 0 "" "")
8016         (call (match_operand 1 "" "")
8017               (match_operand 2 "" "")))
8018    (match_operand 3 "" "")]
8019   ""
8020   "
8021 {
8022   emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
8023   DONE;
8024 }")
8025
8026 (define_insn "call_value_pop_compact"
8027   [(set (match_operand 0 "" "=rf")
8028         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8029               (match_operand 2 "" "")))
8030    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8031                                  (match_operand 4 "immediate_operand" "n")))
8032    (match_operand 3 "immediate_operand" "n")
8033    (use (reg:SI R0_REG))
8034    (use (reg:SI R1_REG))
8035    (use (reg:PSI FPSCR_REG))
8036    (clobber (reg:SI PR_REG))]
8037   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8038   "jsr  @%1%#"
8039   [(set_attr "type" "call")
8040    (set (attr "fp_mode")
8041         (if_then_else (eq_attr "fpu_single" "yes")
8042                       (const_string "single") (const_string "double")))
8043    (set_attr "needs_delay_slot" "yes")])
8044
8045 (define_insn "call_value_pop_compact_rettramp"
8046   [(set (match_operand 0 "" "=rf")
8047         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8048               (match_operand 2 "" "")))
8049    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8050                                  (match_operand 4 "immediate_operand" "n")))
8051    (match_operand 3 "immediate_operand" "n")
8052    (use (reg:SI R0_REG))
8053    (use (reg:SI R1_REG))
8054    (use (reg:PSI FPSCR_REG))
8055    (clobber (reg:SI R10_REG))
8056    (clobber (reg:SI PR_REG))]
8057   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8058   "jsr  @%1%#"
8059   [(set_attr "type" "call")
8060    (set (attr "fp_mode")
8061         (if_then_else (eq_attr "fpu_single" "yes")
8062                       (const_string "single") (const_string "double")))
8063    (set_attr "needs_delay_slot" "yes")])
8064
8065 (define_expand "call_value_pop"
8066   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8067                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8068                                  (match_operand 2 "" "")))
8069               (match_operand 3 "" "")
8070               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8071                                             (match_operand 4 "" "")))])]
8072   "TARGET_SHCOMPACT"
8073   "
8074 {
8075   rtx cookie_rtx;
8076   long cookie;
8077   rtx func;
8078   rtx r0, r1;
8079
8080   gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8081   cookie_rtx = operands[3];
8082   cookie = INTVAL (cookie_rtx);
8083   func = XEXP (operands[1], 0);
8084
8085   if (flag_pic)
8086     {
8087       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8088         {
8089           rtx reg = gen_reg_rtx (Pmode);
8090
8091           emit_insn (gen_symGOTPLT2reg (reg, func));
8092           func = reg;
8093         }
8094       else
8095         func = legitimize_pic_address (func, Pmode, 0);
8096     }
8097
8098   r0 = gen_rtx_REG (SImode, R0_REG);
8099   r1 = gen_rtx_REG (SImode, R1_REG);
8100
8101   /* Since such a call function may use all call-clobbered
8102      registers, we force a mode switch earlier, so that we don't
8103      run out of registers when adjusting fpscr for the call.  */
8104   emit_insn (gen_force_mode_for_call ());
8105
8106   operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8107                                  SFUNC_GOT);
8108   operands[1] = force_reg (SImode, operands[1]);
8109
8110   emit_move_insn (r0, func);
8111   emit_move_insn (r1, cookie_rtx);
8112
8113   if (cookie & CALL_COOKIE_RET_TRAMP (1))
8114     emit_call_insn (gen_call_value_pop_compact_rettramp
8115                         (operands[0], operands[1], operands[2],
8116                          operands[3], operands[4]));
8117   else
8118     emit_call_insn (gen_call_value_pop_compact
8119                         (operands[0], operands[1], operands[2],
8120                          operands[3], operands[4]));
8121
8122   DONE;
8123 }")
8124
8125 (define_expand "sibcall_epilogue"
8126   [(return)]
8127   ""
8128   "
8129 {
8130   sh_expand_epilogue (1);
8131   if (TARGET_SHCOMPACT)
8132     {
8133       rtx insn, set;
8134
8135       /* If epilogue clobbers r0, preserve it in macl.  */
8136       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8137         if ((set = single_set (insn))
8138             && GET_CODE (SET_DEST (set)) == REG
8139             && REGNO (SET_DEST (set)) == R0_REG)
8140           {
8141             rtx r0 = gen_rtx_REG (SImode, R0_REG);
8142             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8143             rtx i;
8144
8145             /* We can't tell at this point whether the sibcall is a
8146                sibcall_compact and, if it is, whether it uses r0 or
8147                mach as operand 2, so let the instructions that
8148                preserve r0 be optimized away if r0 turns out to be
8149                dead.  */
8150             i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8151             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8152                                                REG_NOTES (i));
8153             i = emit_move_insn (r0, tmp);
8154             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8155                                                REG_NOTES (i));
8156             break;
8157           }
8158     }
8159   DONE;
8160 }")
8161
8162 (define_insn "indirect_jump_compact"
8163   [(set (pc)
8164         (match_operand:SI 0 "arith_reg_operand" "r"))]
8165   "TARGET_SH1"
8166   "jmp  @%0%#"
8167   [(set_attr "needs_delay_slot" "yes")
8168    (set_attr "type" "jump_ind")])
8169
8170 (define_expand "indirect_jump"
8171   [(set (pc)
8172         (match_operand 0 "register_operand" ""))]
8173   ""
8174   "
8175 {
8176   if (GET_MODE (operands[0]) != Pmode)
8177     operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8178 }")
8179
8180 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8181 ;; which can be present in structured code from indirect jumps which can not
8182 ;; be present in structured code.  This allows -fprofile-arcs to work.
8183
8184 ;; For SH1 processors.
8185 (define_insn "casesi_jump_1"
8186   [(set (pc)
8187         (match_operand:SI 0 "register_operand" "r"))
8188    (use (label_ref (match_operand 1 "" "")))]
8189   "TARGET_SH1"
8190   "jmp  @%0%#"
8191   [(set_attr "needs_delay_slot" "yes")
8192    (set_attr "type" "jump_ind")])
8193
8194 ;; For all later processors.
8195 (define_insn "casesi_jump_2"
8196   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8197                       (label_ref (match_operand 1 "" ""))))
8198    (use (label_ref (match_operand 2 "" "")))]
8199   "TARGET_SH2
8200    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8201   "braf %0%#"
8202   [(set_attr "needs_delay_slot" "yes")
8203    (set_attr "type" "jump_ind")])
8204
8205 (define_insn "casesi_jump_media"
8206   [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8207    (use (label_ref (match_operand 1 "" "")))]
8208   "TARGET_SHMEDIA"
8209   "blink        %0, r63"
8210   [(set_attr "type" "jump_media")])
8211
8212 ;; Call subroutine returning any type.
8213 ;; ??? This probably doesn't work.
8214
8215 (define_expand "untyped_call"
8216   [(parallel [(call (match_operand 0 "" "")
8217                     (const_int 0))
8218               (match_operand 1 "" "")
8219               (match_operand 2 "" "")])]
8220   "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8221   "
8222 {
8223   int i;
8224
8225   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8226
8227   for (i = 0; i < XVECLEN (operands[2], 0); i++)
8228     {
8229       rtx set = XVECEXP (operands[2], 0, i);
8230       emit_move_insn (SET_DEST (set), SET_SRC (set));
8231     }
8232
8233   /* The optimizer does not know that the call sets the function value
8234      registers we stored in the result block.  We avoid problems by
8235      claiming that all hard registers are used and clobbered at this
8236      point.  */
8237   emit_insn (gen_blockage ());
8238
8239   DONE;
8240 }")
8241 \f
8242 ;; ------------------------------------------------------------------------
8243 ;; Misc insns
8244 ;; ------------------------------------------------------------------------
8245
8246 (define_insn "dect"
8247   [(set (reg:SI T_REG)
8248         (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
8249    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
8250   "TARGET_SH2"
8251   "dt   %0"
8252   [(set_attr "type" "arith")])
8253
8254 (define_insn "nop"
8255   [(const_int 0)]
8256   ""
8257   "nop")
8258
8259 ;; Load address of a label. This is only generated by the casesi expand,
8260 ;; and by machine_dependent_reorg (fixing up fp moves).
8261 ;; This must use unspec, because this only works for labels that are
8262 ;; within range,
8263
8264 (define_insn "mova"
8265   [(set (reg:SI R0_REG)
8266         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8267   "TARGET_SH1"
8268   "mova %O0,r0"
8269   [(set_attr "in_delay_slot" "no")
8270    (set_attr "type" "arith")])
8271
8272 ;; machine_dependent_reorg will make this a `mova'.
8273 (define_insn "mova_const"
8274   [(set (reg:SI R0_REG)
8275         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8276   "TARGET_SH1"
8277   "#"
8278   [(set_attr "in_delay_slot" "no")
8279    (set_attr "type" "arith")])
8280
8281 (define_expand "GOTaddr2picreg"
8282   [(set (reg:SI R0_REG)
8283         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8284                    UNSPEC_MOVA))
8285    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8286    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8287   "" "
8288 {
8289   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8290   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8291
8292   if (TARGET_SHMEDIA)
8293     {
8294       rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8295       rtx pic = operands[0];
8296       rtx lab = PATTERN (gen_call_site ());
8297       rtx insn, equiv;
8298
8299       equiv = operands[1];
8300       operands[1] = gen_rtx_MINUS (Pmode,
8301                                    operands[1],
8302                                    gen_rtx_CONST
8303                                    (Pmode,
8304                                     gen_rtx_MINUS (Pmode,
8305                                                    gen_rtx_CONST (Pmode,
8306                                                                   lab),
8307                                                    pc_rtx)));
8308       operands[1] = gen_sym2PIC (operands[1]);
8309       PUT_MODE (operands[1], Pmode);
8310
8311       if (Pmode == SImode)
8312         {
8313           emit_insn (gen_movsi_const (pic, operands[1]));
8314           emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
8315         }
8316       else
8317         {
8318           emit_insn (gen_movdi_const (pic, operands[1]));
8319           emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
8320         }
8321
8322       insn = emit_move_insn (operands[0], tr);
8323
8324       set_unique_reg_note (insn, REG_EQUAL, equiv);
8325
8326       DONE;
8327     }
8328 }
8329 ")
8330
8331 (define_insn "*ptb"
8332   [(set (match_operand 0 "target_reg_operand" "=b")
8333         (const (unspec [(match_operand 1 "" "Csy")]
8334                              UNSPEC_DATALABEL)))]
8335   "TARGET_SHMEDIA && flag_pic
8336    && EXTRA_CONSTRAINT_Csy (operands[1])"
8337   "ptb/u        datalabel %1, %0"
8338   [(set_attr "type" "ptabs_media")
8339    (set_attr "length" "*")])
8340
8341 (define_insn "ptrel_si"
8342   [(set (match_operand:SI 0 "target_reg_operand" "=b")
8343         (plus:SI (match_operand:SI 1 "register_operand" "r")
8344               (pc)))
8345    (match_operand:SI 2 "" "")]
8346   "TARGET_SHMEDIA"
8347   "%O2: ptrel/u %1, %0"
8348   [(set_attr "type" "ptabs_media")])
8349
8350 (define_insn "ptrel_di"
8351   [(set (match_operand:DI 0 "target_reg_operand" "=b")
8352         (plus:DI (match_operand:DI 1 "register_operand" "r")
8353               (pc)))
8354    (match_operand:DI 2 "" "")]
8355   "TARGET_SHMEDIA"
8356   "%O2: ptrel/u %1, %0"
8357   [(set_attr "type" "ptabs_media")])
8358
8359 (define_expand "builtin_setjmp_receiver"
8360   [(match_operand 0 "" "")]
8361   "flag_pic"
8362   "
8363 {
8364   emit_insn (gen_GOTaddr2picreg ());
8365   DONE;
8366 }")
8367
8368 (define_expand "call_site"
8369   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8370   "TARGET_SH1"
8371   "
8372 {
8373   static HOST_WIDE_INT i = 0;
8374   operands[0] = GEN_INT (i);
8375   i++;
8376 }")
8377
8378 (define_expand "sym_label2reg"
8379   [(set (match_operand:SI 0 "" "")
8380         (const:SI (minus:SI
8381                    (const:SI
8382                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
8383                    (const:SI
8384                     (plus:SI
8385                      (match_operand:SI 2 "" "")
8386                      (const_int 2))))))]
8387   "TARGET_SH1" "")
8388
8389 (define_expand "symGOT_load"
8390   [(set (match_dup 2) (match_operand 1 "" ""))
8391    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8392    (set (match_operand 0 "" "") (mem (match_dup 3)))]
8393   ""
8394   "
8395 {
8396   rtx insn, mem;
8397
8398   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8399   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8400
8401   if (TARGET_SHMEDIA)
8402     {
8403       rtx reg = operands[2];
8404
8405       if (Pmode == DImode)
8406         {      
8407           if (flag_pic > 1)
8408             emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8409           else
8410             emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8411         }
8412       else
8413         {
8414           if (flag_pic > 1)
8415             emit_insn (gen_movsi_const (reg, operands[1]));
8416           else
8417             emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8418         }
8419     }
8420   else
8421     emit_move_insn (operands[2], operands[1]);
8422
8423   emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8424                                              operands[2],
8425                                              gen_rtx_REG (Pmode, PIC_REG)));
8426
8427   /* N.B. This is not constant for a GOTPLT relocation.  */
8428   mem = gen_rtx_MEM (Pmode, operands[3]);
8429   MEM_NOTRAP_P (mem) = 1;
8430   /* ??? Should we have a special alias set for the GOT?  */
8431   insn = emit_move_insn (operands[0], mem);
8432
8433   set_unique_reg_note (insn, REG_EQUAL,
8434                        XVECEXP (XEXP (operands[1], 0), 0, 0));
8435
8436   DONE;
8437 }")
8438
8439 (define_expand "sym2GOT"
8440   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8441   ""
8442   "")
8443
8444 (define_expand "symGOT2reg"
8445   [(match_operand 0 "" "") (match_operand 1 "" "")]
8446   ""
8447   "
8448 {
8449   rtx gotsym, insn;
8450
8451   gotsym = gen_sym2GOT (operands[1]);
8452   PUT_MODE (gotsym, Pmode);
8453   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8454
8455   MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8456
8457   DONE;
8458 }")
8459
8460 (define_expand "symGOTPLT2reg"
8461   [(match_operand 0 "" "") (match_operand 1 "" "")]
8462   ""
8463   "
8464 {
8465   rtx pltsym = gen_rtx_CONST (Pmode,
8466                               gen_rtx_UNSPEC (Pmode,
8467                                               gen_rtvec (1, operands[1]),
8468                                               UNSPEC_GOTPLT));
8469   emit_insn (gen_symGOT_load (operands[0], pltsym));
8470   DONE;
8471 }")
8472
8473 (define_expand "sym2GOTOFF"
8474   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8475   ""
8476   "")
8477
8478 (define_expand "symGOTOFF2reg"
8479   [(match_operand 0 "" "") (match_operand 1 "" "")]
8480   ""
8481   "
8482 {
8483   rtx gotoffsym, insn;
8484   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8485
8486   gotoffsym = gen_sym2GOTOFF (operands[1]);
8487   PUT_MODE (gotoffsym, Pmode);
8488   emit_move_insn (t, gotoffsym);
8489   insn = emit_move_insn (operands[0],
8490                          gen_rtx_PLUS (Pmode, t,
8491                                        gen_rtx_REG (Pmode, PIC_REG)));
8492
8493   set_unique_reg_note (insn, REG_EQUAL, operands[1]);
8494
8495   DONE;
8496 }")
8497
8498 (define_expand "symPLT_label2reg"
8499   [(set (match_operand:SI 0 "" "")
8500         (const:SI (minus:SI
8501                    (const:SI
8502                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8503                    (const:SI
8504                     (minus:SI
8505                      (const:SI (plus:SI
8506                                 (match_operand:SI 2 "" "")
8507                                 (const_int 2)))
8508                      (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
8509    ;; Even though the PIC register is not really used by the call
8510    ;; sequence in which this is expanded, the PLT code assumes the PIC
8511    ;; register is set, so we must not skip its initialization.  Since
8512    ;; we only use this expand as part of calling sequences, and never
8513    ;; to take the address of a function, this is the best point to
8514    ;; insert the (use).  Using the PLT to take the address of a
8515    ;; function would be wrong, not only because the PLT entry could
8516    ;; then be called from a function that doesn't initialize the PIC
8517    ;; register to the proper GOT, but also because pointers to the
8518    ;; same function might not compare equal, should they be set by
8519    ;; different shared libraries.
8520    (use (reg:SI PIC_REG))]
8521   "TARGET_SH1"
8522   "")
8523
8524 (define_expand "sym2PIC"
8525   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8526   ""
8527   "")
8528
8529 ;; TLS code generation.
8530 ;; ??? this should be a define_insn_and_split
8531 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8532 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8533 ;; for details.
8534
8535 (define_insn "tls_global_dynamic"
8536   [(set (match_operand:SI 0 "register_operand" "=&z")
8537         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8538                                   UNSPEC_TLSGD))
8539               (const_int 0)))
8540    (use (reg:PSI FPSCR_REG))
8541    (use (reg:SI PIC_REG))
8542    (clobber (reg:SI PR_REG))
8543    (clobber (scratch:SI))]
8544   "TARGET_SH1"
8545   "*
8546 {
8547   return \"\\
8548 mov.l\\t1f,r4\\n\\
8549 \\tmova\\t2f,r0\\n\\
8550 \\tmov.l\\t2f,r1\\n\\
8551 \\tadd\\tr0,r1\\n\\
8552 \\tjsr\\t@r1\\n\\
8553 \\tadd\\tr12,r4\\n\\
8554 \\tbra\\t3f\\n\\
8555 \\tnop\\n\\
8556 \\t.align\\t2\\n\\
8557 1:\\t.long\\t%a1@TLSGD\\n\\
8558 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8559 3:\";
8560 }"
8561   [(set_attr "type" "tls_load")
8562    (set_attr "length" "26")])
8563
8564 (define_insn "tls_local_dynamic"
8565   [(set (match_operand:SI 0 "register_operand" "=&z")
8566         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8567                                   UNSPEC_TLSLDM))
8568               (const_int 0)))
8569    (use (reg:PSI FPSCR_REG))
8570    (use (reg:SI PIC_REG))
8571    (clobber (reg:SI PR_REG))
8572    (clobber (scratch:SI))]
8573   "TARGET_SH1"
8574   "*
8575 {
8576   return \"\\
8577 mov.l\\t1f,r4\\n\\
8578 \\tmova\\t2f,r0\\n\\
8579 \\tmov.l\\t2f,r1\\n\\
8580 \\tadd\\tr0,r1\\n\\
8581 \\tjsr\\t@r1\\n\\
8582 \\tadd\\tr12,r4\\n\\
8583 \\tbra\\t3f\\n\\
8584 \\tnop\\n\\
8585 \\t.align\\t2\\n\\
8586 1:\\t.long\\t%a1@TLSLDM\\n\\
8587 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8588 3:\";
8589 }"
8590   [(set_attr "type" "tls_load")
8591    (set_attr "length" "26")])
8592
8593 (define_expand "sym2DTPOFF"
8594   [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8595   ""
8596   "")
8597
8598 (define_expand "symDTPOFF2reg"
8599   [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8600   ""
8601   "
8602 {
8603   rtx dtpoffsym, insn;
8604   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8605
8606   dtpoffsym = gen_sym2DTPOFF (operands[1]);
8607   PUT_MODE (dtpoffsym, Pmode);
8608   emit_move_insn (t, dtpoffsym);
8609   insn = emit_move_insn (operands[0],
8610                          gen_rtx_PLUS (Pmode, t, operands[2]));
8611   DONE;
8612 }")
8613
8614 (define_expand "sym2GOTTPOFF"
8615   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8616   ""
8617   "")
8618
8619 (define_insn "tls_initial_exec"
8620   [(set (match_operand:SI 0 "register_operand" "=&r")
8621         (unspec:SI [(match_operand:SI 1 "" "")]
8622                     UNSPEC_TLSIE))
8623    (use (reg:SI GBR_REG))
8624    (use (reg:SI PIC_REG))
8625    (clobber (reg:SI R0_REG))]
8626   ""
8627   "*
8628 {
8629   return \"\\
8630 mov.l\\t1f,r0\\n\\
8631 \\tstc\\tgbr,%0\\n\\
8632 \\tmov.l\\t@(r0,r12),r0\\n\\
8633 \\tbra\\t2f\\n\\
8634 \\tadd\\tr0,%0\\n\\
8635 \\t.align\\t2\\n\\
8636 1:\\t.long\\t%a1\\n\\
8637 2:\";
8638 }"
8639   [(set_attr "type" "tls_load")
8640    (set_attr "length" "16")])
8641
8642 (define_expand "sym2TPOFF"
8643   [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8644   ""
8645   "")
8646
8647 (define_expand "symTPOFF2reg"
8648   [(match_operand 0 "" "") (match_operand 1 "" "")]
8649   ""
8650   "
8651 {
8652   rtx tpoffsym, insn;
8653
8654   tpoffsym = gen_sym2TPOFF (operands[1]);
8655   PUT_MODE (tpoffsym, Pmode);
8656   insn = emit_move_insn (operands[0], tpoffsym);
8657   DONE;
8658 }")
8659
8660 (define_insn "load_gbr"
8661   [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
8662    (use (reg:SI GBR_REG))]
8663   ""
8664   "stc  gbr,%0"
8665   [(set_attr "type" "tls_load")])
8666
8667 ;; case instruction for switch statements.
8668
8669 ;; Operand 0 is index
8670 ;; operand 1 is the minimum bound
8671 ;; operand 2 is the maximum bound - minimum bound + 1
8672 ;; operand 3 is CODE_LABEL for the table;
8673 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8674
8675 (define_expand "casesi"
8676   [(match_operand:SI 0 "arith_reg_operand" "")
8677    (match_operand:SI 1 "arith_reg_operand" "")
8678    (match_operand:SI 2 "arith_reg_operand" "")
8679    (match_operand 3 "" "") (match_operand 4 "" "")]
8680   ""
8681   "
8682 {
8683   rtx reg = gen_reg_rtx (SImode);
8684   rtx reg2 = gen_reg_rtx (SImode);
8685   if (TARGET_SHMEDIA)
8686     {
8687       rtx reg = gen_reg_rtx (DImode);
8688       rtx reg2 = gen_reg_rtx (DImode);
8689       rtx reg3 = gen_reg_rtx (Pmode);
8690       rtx reg4 = gen_reg_rtx (Pmode);
8691       rtx reg5 = gen_reg_rtx (Pmode);
8692       rtx load;
8693
8694       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8695       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8696       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8697
8698       emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
8699       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8700       emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
8701       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8702       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
8703                                                (Pmode, operands[3])));
8704       /* Messy: can we subreg to clean this up? */
8705       if (Pmode == DImode)
8706         load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8707       else
8708         load = gen_casesi_load_media (reg4,
8709                                       gen_rtx_SUBREG (DImode, reg3, 0),
8710                                       reg2, operands[3]);
8711       PUT_MODE (SET_SRC (load), Pmode);
8712       emit_insn (load);
8713       /* ??? The following add could be eliminated if we used ptrel.  */
8714       emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
8715       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
8716       emit_barrier ();
8717       DONE;
8718     }
8719   operands[1] = copy_to_mode_reg (SImode, operands[1]);
8720   operands[2] = copy_to_mode_reg (SImode, operands[2]);
8721   /* If optimizing, casesi_worker depends on the mode of the instruction
8722      before label it 'uses' - operands[3].  */
8723   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
8724                            reg));
8725   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
8726   if (TARGET_SH2)
8727     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
8728   else
8729     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
8730   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
8731      operands[3], but to lab.  We will fix this up in
8732      machine_dependent_reorg.  */
8733   emit_barrier ();
8734   DONE;
8735 }")
8736
8737 (define_expand "casesi_0"
8738   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
8739    (set (match_dup 4) (minus:SI (match_dup 4)
8740                                 (match_operand:SI 1 "arith_operand" "")))
8741    (set (reg:SI T_REG)
8742         (gtu:SI (match_dup 4)
8743                 (match_operand:SI 2 "arith_reg_operand" "")))
8744    (set (pc)
8745         (if_then_else (ne (reg:SI T_REG)
8746                           (const_int 0))
8747                       (label_ref (match_operand 3 "" ""))
8748                       (pc)))]
8749   "TARGET_SH1"
8750   "")
8751
8752 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
8753 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
8754 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
8755
8756 (define_insn "casesi_worker_0"
8757   [(set (match_operand:SI 0 "register_operand" "=r,r")
8758         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
8759                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8760    (clobber (match_scratch:SI 3 "=X,1"))
8761    (clobber (match_scratch:SI 4 "=&z,z"))]
8762   "TARGET_SH1"
8763   "#")
8764
8765 (define_split
8766   [(set (match_operand:SI 0 "register_operand" "")
8767         (unspec:SI [(match_operand:SI 1 "register_operand" "")
8768                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8769    (clobber (match_scratch:SI 3 ""))
8770    (clobber (match_scratch:SI 4 ""))]
8771   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
8772   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8773    (parallel [(set (match_dup 0)
8774               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8775                           (label_ref (match_dup 2))] UNSPEC_CASESI))
8776               (clobber (match_dup 3))])
8777    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8778   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8779
8780 (define_split
8781   [(set (match_operand:SI 0 "register_operand" "")
8782         (unspec:SI [(match_operand:SI 1 "register_operand" "")
8783                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8784    (clobber (match_scratch:SI 3 ""))
8785    (clobber (match_scratch:SI 4 ""))]
8786   "TARGET_SH2 && reload_completed"
8787   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8788    (parallel [(set (match_dup 0)
8789               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8790                           (label_ref (match_dup 2))] UNSPEC_CASESI))
8791               (clobber (match_dup 3))])]
8792   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8793
8794 (define_insn "casesi_worker_1"
8795   [(set (match_operand:SI 0 "register_operand" "=r,r")
8796         (unspec:SI [(reg:SI R0_REG)
8797                     (match_operand:SI 1 "register_operand" "0,r")
8798                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8799    (clobber (match_scratch:SI 3 "=X,1"))]
8800   "TARGET_SH1"
8801   "*
8802 {
8803   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8804
8805   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8806
8807   switch (GET_MODE (diff_vec))
8808     {
8809     case SImode:
8810       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
8811     case HImode:
8812       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
8813     case QImode:
8814       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8815         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
8816       return \"mov.b    @(r0,%1),%0\";
8817     default:
8818       gcc_unreachable ();
8819     }
8820 }"
8821   [(set_attr "length" "4")])
8822
8823 (define_insn "casesi_worker_2"
8824   [(set (match_operand:SI 0 "register_operand" "=r,r")
8825         (unspec:SI [(reg:SI R0_REG)
8826                     (match_operand:SI 1 "register_operand" "0,r")
8827                     (label_ref (match_operand 2 "" ""))
8828                     (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
8829    (clobber (match_operand:SI 4 "" "=X,1"))]
8830   "TARGET_SH2 && reload_completed && flag_pic"
8831   "*
8832 {
8833   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8834   const char *load;
8835
8836   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8837
8838   switch (GET_MODE (diff_vec))
8839     {
8840     case SImode:
8841       output_asm_insn (\"shll2    %1\", operands);
8842       load = \"mov.l    @(r0,%1),%0\"; break;
8843     case HImode:
8844       output_asm_insn (\"add    %1,%1\", operands);
8845       load = \"mov.w    @(r0,%1),%0\"; break;
8846     case QImode:
8847       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8848         load = \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
8849       else
8850         load = \"mov.b  @(r0,%1),%0\";
8851       break;
8852     default:
8853       gcc_unreachable ();
8854     }
8855   output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
8856   return load;
8857 }"
8858   [(set_attr "length" "8")])
8859
8860 (define_insn "casesi_shift_media"
8861   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
8862         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
8863                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
8864                     UNSPEC_CASESI)))]
8865   "TARGET_SHMEDIA"
8866   "*
8867 {
8868   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8869
8870   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8871
8872   switch (GET_MODE (diff_vec))
8873     {
8874     case SImode:
8875       return \"shlli    %1, 2, %0\";
8876     case HImode:
8877       return \"shlli    %1, 1, %0\";
8878     case QImode:
8879       if (rtx_equal_p (operands[0], operands[1]))
8880         return \"\";
8881       return \"add      %1, r63, %0\";
8882     default:
8883       gcc_unreachable ();
8884     }
8885 }"
8886   [(set_attr "type" "arith_media")])
8887
8888 (define_insn "casesi_load_media"
8889   [(set (match_operand 0 "any_arith_reg_dest" "=r")
8890         (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
8891                          (match_operand:DI 2 "arith_reg_operand" "r")
8892                          (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
8893   "TARGET_SHMEDIA"
8894   "*
8895 {
8896   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
8897
8898   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8899
8900   switch (GET_MODE (diff_vec))
8901     {
8902     case SImode:
8903       return \"ldx.l    %1, %2, %0\";
8904     case HImode:
8905 #if 0
8906       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8907         return \"ldx.uw %1, %2, %0\";
8908 #endif
8909       return \"ldx.w    %1, %2, %0\";
8910     case QImode:
8911       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8912         return \"ldx.ub %1, %2, %0\";
8913       return \"ldx.b    %1, %2, %0\";
8914     default:
8915       gcc_unreachable ();
8916     }
8917 }"
8918   [(set_attr "type" "load_media")])
8919
8920 (define_expand "return"
8921   [(return)]
8922   "reload_completed && ! sh_need_epilogue ()"
8923   "
8924 {
8925   if (TARGET_SHMEDIA)
8926     {
8927       emit_jump_insn (gen_return_media ());
8928       DONE;
8929     }
8930
8931   if (TARGET_SHCOMPACT
8932       && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
8933     {
8934       emit_jump_insn (gen_shcompact_return_tramp ());
8935       DONE;
8936     }
8937 }")
8938
8939 (define_insn "*return_i"
8940   [(return)]
8941   "TARGET_SH1 && ! (TARGET_SHCOMPACT
8942                     && (current_function_args_info.call_cookie
8943                         & CALL_COOKIE_RET_TRAMP (1)))
8944    && reload_completed
8945    && lookup_attribute (\"trap_exit\",
8946                         DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
8947   "%@   %#"
8948   [(set_attr "type" "return")
8949    (set_attr "needs_delay_slot" "yes")])
8950
8951 ;; trapa has no delay slot.
8952 (define_insn "*return_trapa"
8953   [(return)]
8954   "TARGET_SH1 && !TARGET_SHCOMPACT
8955    && reload_completed"
8956   "%@"
8957   [(set_attr "type" "return")])
8958
8959 (define_expand "shcompact_return_tramp"
8960   [(return)]
8961   "TARGET_SHCOMPACT
8962    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8963   "
8964 {
8965   rtx reg = gen_rtx_REG (Pmode, R0_REG);
8966
8967   function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
8968   emit_jump_insn (gen_shcompact_return_tramp_i ());
8969   DONE;
8970 }")
8971
8972 (define_insn "shcompact_return_tramp_i"
8973   [(parallel [(return) (use (reg:SI R0_REG))])]
8974   "TARGET_SHCOMPACT
8975    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8976   "jmp  @r0%#"
8977   [(set_attr "type" "jump_ind")
8978    (set_attr "needs_delay_slot" "yes")])
8979
8980 (define_insn "return_media_i"
8981   [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
8982   "TARGET_SHMEDIA && reload_completed"
8983   "blink        %0, r63"
8984   [(set_attr "type" "jump_media")])
8985
8986 (define_insn "return_media_rte"
8987   [(return)]
8988   "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
8989   "rte"
8990   [(set_attr "type" "jump_media")])
8991
8992 (define_expand "return_media"
8993   [(return)]
8994   "TARGET_SHMEDIA && reload_completed"
8995   "
8996 {
8997   int tr_regno = sh_media_register_for_return ();
8998   rtx tr;
8999
9000   if (current_function_interrupt)
9001     {
9002       emit_jump_insn (gen_return_media_rte ());
9003       DONE;
9004     }
9005   if (tr_regno < 0)
9006     {
9007       rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
9008
9009       gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
9010       tr_regno = TR0_REG;
9011       tr = gen_rtx_REG (Pmode, tr_regno);
9012       emit_move_insn (tr, r18);
9013     }
9014   else
9015     tr = gen_rtx_REG (Pmode, tr_regno);
9016
9017   emit_jump_insn (gen_return_media_i (tr));
9018   DONE;
9019 }")
9020
9021 (define_insn "shcompact_preserve_incoming_args"
9022   [(set (match_operand:SI 0 "register_operand" "+r")
9023         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9024   "TARGET_SHCOMPACT"
9025   ""
9026   [(set_attr "length" "0")])
9027
9028 (define_insn "shcompact_incoming_args"
9029   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9030    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9031    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9032    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9033    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9034    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9035    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9036    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9037    (set (mem:BLK (reg:SI MACL_REG))
9038         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9039    (use (reg:SI R0_REG))
9040    (clobber (reg:SI R0_REG))
9041    (clobber (reg:SI MACL_REG))
9042    (clobber (reg:SI MACH_REG))
9043    (clobber (reg:SI PR_REG))]
9044   "TARGET_SHCOMPACT"
9045   "jsr  @r0%#"
9046   [(set_attr "needs_delay_slot" "yes")])
9047
9048 (define_insn "shmedia_save_restore_regs_compact"
9049   [(set (reg:SI SP_REG)
9050         (plus:SI (reg:SI SP_REG)
9051                  (match_operand:SI 0 "immediate_operand" "i")))
9052    (use (reg:SI R0_REG))
9053    (clobber (reg:SI PR_REG))]
9054   "TARGET_SHCOMPACT
9055    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9056        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9057   "jsr @r0%#"
9058   [(set_attr "needs_delay_slot" "yes")])
9059
9060 (define_expand "prologue"
9061   [(const_int 0)]
9062   ""
9063   "sh_expand_prologue (); DONE;")
9064
9065 (define_expand "epilogue"
9066   [(return)]
9067   ""
9068   "
9069 {
9070   sh_expand_epilogue (0);
9071   emit_jump_insn (gen_return ());
9072   DONE;
9073 }")
9074
9075 (define_expand "eh_return"
9076   [(use (match_operand 0 "register_operand" ""))]
9077   ""
9078 {
9079   rtx ra = operands[0];
9080
9081   if (TARGET_SHMEDIA64)
9082     emit_insn (gen_eh_set_ra_di (ra));
9083   else
9084     emit_insn (gen_eh_set_ra_si (ra));
9085
9086   DONE;
9087 })
9088
9089 ;; Clobber the return address on the stack.  We can't expand this
9090 ;; until we know where it will be put in the stack frame.
9091
9092 (define_insn "eh_set_ra_si"
9093   [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
9094    (clobber (match_scratch:SI 1 "=&r"))]
9095   "! TARGET_SHMEDIA64"
9096   "#")
9097
9098 (define_insn "eh_set_ra_di"
9099   [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
9100    (clobber (match_scratch:DI 1 "=&r"))]
9101   "TARGET_SHMEDIA64"
9102   "#")
9103
9104 (define_split
9105   [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
9106    (clobber (match_scratch 1 ""))]
9107   "reload_completed"
9108   [(const_int 0)]
9109   "
9110 {
9111   sh_set_return_address (operands[0], operands[1]);
9112   DONE;
9113 }")
9114
9115 (define_insn "blockage"
9116   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9117   ""
9118   ""
9119   [(set_attr "length" "0")])
9120 \f
9121 ;; ------------------------------------------------------------------------
9122 ;; Scc instructions
9123 ;; ------------------------------------------------------------------------
9124
9125 (define_insn "movt"
9126   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9127         (eq:SI (reg:SI T_REG) (const_int 1)))]
9128   "TARGET_SH1"
9129   "movt %0"
9130   [(set_attr "type" "arith")])
9131
9132 (define_expand "seq"
9133   [(set (match_operand:SI 0 "arith_reg_dest" "")
9134         (match_dup 1))]
9135   ""
9136   "
9137 {
9138   if (TARGET_SHMEDIA)
9139     {
9140       rtx reg;
9141
9142       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9143       if (sh_compare_op1 != const0_rtx)
9144         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9145                                     ? GET_MODE (sh_compare_op0)
9146                                     : GET_MODE (sh_compare_op1),
9147                                     sh_compare_op1);
9148       if (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4)
9149         {
9150           if (GET_MODE (operands[0]) != SImode)
9151             operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
9152
9153           switch (GET_MODE (sh_compare_op0))
9154             {
9155             case SImode:
9156               emit_insn (gen_cmpeqsi_media (operands[0],
9157                                               sh_compare_op0, sh_compare_op1));
9158               break;
9159
9160             case DImode:
9161               emit_insn (gen_cmpeqdi_media (operands[0],
9162                                               sh_compare_op0, sh_compare_op1));
9163               break;
9164
9165             case SFmode:
9166               if (! TARGET_SHMEDIA_FPU)
9167                 FAIL;
9168               emit_insn (gen_cmpeqsf_media (operands[0],
9169                                               sh_compare_op0, sh_compare_op1));
9170               break;
9171
9172             case DFmode:
9173               if (! TARGET_SHMEDIA_FPU)
9174                 FAIL;
9175               emit_insn (gen_cmpeqdf_media (operands[0],
9176                                               sh_compare_op0, sh_compare_op1));
9177               break;
9178
9179             default:
9180               FAIL;
9181             }
9182           DONE;
9183         }
9184
9185       reg = operands[0];
9186       if (GET_MODE (operands[0]) != SImode)
9187         reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9188                              : gen_reg_rtx (SImode);
9189
9190       switch (GET_MODE (sh_compare_op0))
9191         {
9192         case SImode:
9193           emit_insn (gen_cmpeqsi_media (reg,
9194                                         sh_compare_op0, sh_compare_op1));
9195           break;
9196
9197         case DImode:
9198           emit_insn (gen_cmpeqdi_media (reg,
9199                                         sh_compare_op0, sh_compare_op1));
9200           break;
9201
9202         case SFmode:
9203           if (! TARGET_SHMEDIA_FPU)
9204             FAIL;
9205           emit_insn (gen_cmpeqsf_media (reg,
9206                                         sh_compare_op0, sh_compare_op1));
9207           break;
9208
9209         case DFmode:
9210           if (! TARGET_SHMEDIA_FPU)
9211             FAIL;
9212           emit_insn (gen_cmpeqdf_media (reg,
9213                                         sh_compare_op0, sh_compare_op1));
9214           break;
9215
9216         default:
9217           FAIL;
9218         }
9219
9220       if (GET_MODE (operands[0]) == DImode)
9221         emit_insn (gen_extendsidi2 (operands[0], reg));
9222
9223       DONE;
9224     }
9225   if (sh_expand_t_scc (EQ, operands[0]))
9226     DONE;
9227   if (! currently_expanding_to_rtl)
9228     FAIL;
9229   operands[1] = prepare_scc_operands (EQ);
9230 }")
9231
9232 (define_expand "slt"
9233   [(set (match_operand:SI 0 "arith_reg_operand" "")
9234         (match_dup 1))]
9235   ""
9236   "
9237 {
9238   if (TARGET_SHMEDIA)
9239     {
9240       rtx reg;
9241
9242       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9243       if (sh_compare_op1 != const0_rtx)
9244         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9245                                     ? GET_MODE (sh_compare_op0)
9246                                     : GET_MODE (sh_compare_op1),
9247                                     sh_compare_op1);
9248
9249       reg = operands[0];
9250       if (GET_MODE (operands[0]) != SImode)
9251         reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9252                              : gen_reg_rtx (SImode);
9253
9254       switch (GET_MODE (sh_compare_op0))
9255         {
9256         case SImode:
9257           emit_insn (gen_cmpgtsi_media (reg,
9258                                         sh_compare_op1, sh_compare_op0));
9259           break;
9260
9261         case DImode:
9262           emit_insn (gen_cmpgtdi_media (reg,
9263                                         sh_compare_op1, sh_compare_op0));
9264           break;
9265
9266         case SFmode:
9267           if (! TARGET_SHMEDIA_FPU)
9268             FAIL;
9269           emit_insn (gen_cmpgtsf_media (reg,
9270                                         sh_compare_op1, sh_compare_op0));
9271           break;
9272
9273         case DFmode:
9274           if (! TARGET_SHMEDIA_FPU)
9275             FAIL;
9276           emit_insn (gen_cmpgtdf_media (reg,
9277                                         sh_compare_op1, sh_compare_op0));
9278           break;
9279
9280         default:
9281           FAIL;
9282         }
9283
9284       if (GET_MODE (operands[0]) == DImode)
9285         emit_insn (gen_extendsidi2 (operands[0], reg));
9286
9287       DONE;
9288     }
9289   if (! currently_expanding_to_rtl)
9290     FAIL;
9291   operands[1] = prepare_scc_operands (LT);
9292 }")
9293
9294 (define_expand "sle"
9295   [(match_operand:SI 0 "arith_reg_operand" "")]
9296   ""
9297   "
9298 {
9299   rtx tmp = sh_compare_op0;
9300
9301   if (TARGET_SHMEDIA)
9302     {
9303       rtx reg;
9304
9305       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9306       if (sh_compare_op1 != const0_rtx)
9307         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9308                                     ? GET_MODE (sh_compare_op0)
9309                                     : GET_MODE (sh_compare_op1),
9310                                     sh_compare_op1);
9311
9312       reg = operands[0];
9313       if (GET_MODE (operands[0]) != SImode)
9314         reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9315                              : gen_reg_rtx (SImode);
9316
9317       switch (GET_MODE (sh_compare_op0))
9318         {
9319         case SImode:
9320           {
9321             tmp = no_new_pseudos ? reg : gen_reg_rtx (SImode);
9322
9323             emit_insn (gen_cmpgtsi_media (tmp,
9324                                           sh_compare_op0, sh_compare_op1));
9325             emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9326             break;
9327           }
9328
9329         case DImode:
9330           {
9331             tmp = no_new_pseudos ? reg : gen_reg_rtx (SImode);
9332
9333             emit_insn (gen_cmpgtdi_media (tmp,
9334                                           sh_compare_op0, sh_compare_op1));
9335             emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9336             break;
9337           }
9338
9339         case SFmode:
9340           if (! TARGET_SHMEDIA_FPU)
9341             FAIL;
9342           emit_insn (gen_cmpgesf_media (reg,
9343                                         sh_compare_op1, sh_compare_op0));
9344           break;
9345
9346         case DFmode:
9347           if (! TARGET_SHMEDIA_FPU)
9348             FAIL;
9349           emit_insn (gen_cmpgedf_media (reg,
9350                                         sh_compare_op1, sh_compare_op0));
9351           break;
9352
9353         default:
9354           FAIL;
9355         }
9356
9357       if (GET_MODE (operands[0]) == DImode)
9358         emit_insn (gen_extendsidi2 (operands[0], reg));
9359
9360       DONE;
9361     }
9362
9363   sh_compare_op0 = sh_compare_op1;
9364   sh_compare_op1 = tmp;
9365   emit_insn (gen_sge (operands[0]));
9366   DONE;
9367 }")
9368
9369 (define_expand "sgt"
9370   [(set (match_operand:SI 0 "arith_reg_operand" "")
9371         (match_dup 1))]
9372   ""
9373   "
9374 {
9375   if (TARGET_SHMEDIA)
9376     {
9377       rtx reg;
9378
9379       reg = operands[0];
9380       if (GET_MODE (operands[0]) != SImode)
9381         reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9382                              : gen_reg_rtx (SImode);
9383       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9384       if (sh_compare_op1 != const0_rtx)
9385         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9386                                     ? GET_MODE (sh_compare_op0)
9387                                     : GET_MODE (sh_compare_op1),
9388                                     sh_compare_op1);
9389
9390       switch (GET_MODE (sh_compare_op0))
9391         {
9392         case SImode:
9393           emit_insn (gen_cmpgtsi_media (reg,
9394                                         sh_compare_op0, sh_compare_op1));
9395           break;
9396
9397         case DImode:
9398           emit_insn (gen_cmpgtdi_media (reg,
9399                                         sh_compare_op0, sh_compare_op1));
9400           break;
9401
9402         case SFmode:
9403           if (! TARGET_SHMEDIA_FPU)
9404             FAIL;
9405           emit_insn (gen_cmpgtsf_media (reg,
9406                                         sh_compare_op0, sh_compare_op1));
9407           break;
9408
9409         case DFmode:
9410           if (! TARGET_SHMEDIA_FPU)
9411             FAIL;
9412           emit_insn (gen_cmpgtdf_media (reg,
9413                                         sh_compare_op0, sh_compare_op1));
9414           break;
9415
9416         default:
9417           FAIL;
9418         }
9419
9420       if (GET_MODE (operands[0]) == DImode)
9421         emit_insn (gen_extendsidi2 (operands[0], reg));
9422
9423       DONE;
9424     }
9425   if (! currently_expanding_to_rtl)
9426     FAIL;
9427   operands[1] = prepare_scc_operands (GT);
9428 }")
9429
9430 (define_expand "sge"
9431   [(set (match_operand:SI 0 "arith_reg_operand" "")
9432         (match_dup 1))]
9433   ""
9434   "
9435 {
9436   if (TARGET_SHMEDIA)
9437     {
9438       rtx reg;
9439       enum machine_mode mode = GET_MODE (sh_compare_op0);
9440
9441       if ((mode) == VOIDmode)
9442         mode = GET_MODE (sh_compare_op1);
9443       reg = operands[0];
9444       if (GET_MODE (operands[0]) != SImode)
9445         reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9446                              : gen_reg_rtx (SImode);
9447       sh_compare_op0 = force_reg (mode, sh_compare_op0);
9448       if (sh_compare_op1 != const0_rtx)
9449         sh_compare_op1 = force_reg (mode, sh_compare_op1);
9450
9451       switch (mode)
9452         {
9453         case SImode:
9454           {
9455             rtx tmp = no_new_pseudos ? reg : gen_reg_rtx (SImode);
9456
9457             emit_insn (gen_cmpgtsi_media (tmp,
9458                                           sh_compare_op1, sh_compare_op0));
9459             emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9460             break;
9461           }
9462
9463         case DImode:
9464           {
9465             rtx tmp = no_new_pseudos ? reg : gen_reg_rtx (SImode);
9466
9467             emit_insn (gen_cmpgtdi_media (tmp,
9468                                           sh_compare_op1, sh_compare_op0));
9469             emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9470             break;
9471           }
9472
9473         case SFmode:
9474           if (! TARGET_SHMEDIA_FPU)
9475             FAIL;
9476           emit_insn (gen_cmpgesf_media (reg,
9477                                         sh_compare_op0, sh_compare_op1));
9478           break;
9479
9480         case DFmode:
9481           if (! TARGET_SHMEDIA_FPU)
9482             FAIL;
9483           emit_insn (gen_cmpgedf_media (reg,
9484                                         sh_compare_op0, sh_compare_op1));
9485           break;
9486
9487         default:
9488           FAIL;
9489         }
9490
9491       if (GET_MODE (operands[0]) == DImode)
9492         emit_insn (gen_extendsidi2 (operands[0], reg));
9493
9494       DONE;
9495     }
9496
9497   if (! currently_expanding_to_rtl)
9498     FAIL;
9499   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
9500     {
9501       if (TARGET_IEEE)
9502         {
9503           rtx lab = gen_label_rtx ();
9504           prepare_scc_operands (EQ);
9505           emit_jump_insn (gen_branch_true (lab));
9506           prepare_scc_operands (GT);
9507           emit_label (lab);
9508           emit_insn (gen_movt (operands[0]));
9509         }
9510       else
9511         emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
9512       DONE;
9513     }
9514   operands[1] = prepare_scc_operands (GE);
9515 }")
9516
9517 (define_expand "sgtu"
9518   [(set (match_operand:SI 0 "arith_reg_operand" "")
9519         (match_dup 1))]
9520   ""
9521   "
9522 {
9523   if (TARGET_SHMEDIA)
9524     {
9525       rtx reg;
9526
9527       reg = operands[0];
9528       if (GET_MODE (operands[0]) == DImode)
9529         reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9530                              : gen_reg_rtx (SImode);
9531       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9532       if (sh_compare_op1 != const0_rtx)
9533         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9534                                     ? GET_MODE (sh_compare_op0)
9535                                     : GET_MODE (sh_compare_op1),
9536                                     sh_compare_op1);
9537
9538       emit_insn (gen_cmpgtudi_media (reg,
9539                                      sh_compare_op0, sh_compare_op1));
9540       if (GET_MODE (operands[0]) == DImode)
9541         emit_insn (gen_extendsidi2 (operands[0], reg));
9542
9543       DONE;
9544     }
9545   if (! currently_expanding_to_rtl)
9546     FAIL;
9547   operands[1] = prepare_scc_operands (GTU);
9548 }")
9549
9550 (define_expand "sltu"
9551   [(set (match_operand:SI 0 "arith_reg_operand" "")
9552         (match_dup 1))]
9553   ""
9554   "
9555 {
9556   if (TARGET_SHMEDIA)
9557     {
9558       rtx reg;
9559
9560       reg = operands[0];
9561       if (GET_MODE (operands[0]) == DImode)
9562         reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9563                              : gen_reg_rtx (SImode);
9564       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9565       if (sh_compare_op1 != const0_rtx)
9566         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9567                                     ? GET_MODE (sh_compare_op0)
9568                                     : GET_MODE (sh_compare_op1),
9569                                     sh_compare_op1);
9570
9571       emit_insn (gen_cmpgtudi_media (reg,
9572                                      sh_compare_op1, sh_compare_op0));
9573       if (GET_MODE (operands[0]) == DImode)
9574         emit_insn (gen_extendsidi2 (operands[0], reg));
9575
9576       DONE;
9577     }
9578   if (! currently_expanding_to_rtl)
9579     FAIL;
9580   operands[1] = prepare_scc_operands (LTU);
9581 }")
9582
9583 (define_expand "sleu"
9584   [(set (match_operand:SI 0 "arith_reg_operand" "")
9585         (match_dup 1))]
9586   ""
9587   "
9588 {
9589   if (TARGET_SHMEDIA)
9590     {
9591       rtx tmp, reg;
9592
9593       reg = operands[0];
9594       if (GET_MODE (operands[0]) != SImode)
9595         reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9596                              : gen_reg_rtx (SImode);
9597       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9598       if (sh_compare_op1 != const0_rtx)
9599         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9600                                     ? GET_MODE (sh_compare_op0)
9601                                     : GET_MODE (sh_compare_op1),
9602                                     sh_compare_op1);
9603
9604       tmp = no_new_pseudos ? reg : gen_reg_rtx (SImode);
9605
9606       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
9607       emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9608       if (GET_MODE (operands[0]) == DImode)
9609         emit_insn (gen_extendsidi2 (operands[0], reg));
9610
9611       DONE;
9612     }
9613   if (! currently_expanding_to_rtl)
9614     FAIL;
9615   operands[1] = prepare_scc_operands (LEU);
9616 }")
9617
9618 (define_expand "sgeu"
9619   [(set (match_operand:SI 0 "arith_reg_operand" "")
9620         (match_dup 1))]
9621   ""
9622   "
9623 {
9624   if (TARGET_SHMEDIA)
9625     {
9626       rtx tmp, reg;
9627
9628       reg = operands[0];
9629       if (GET_MODE (operands[0]) != SImode)
9630         reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9631                              : gen_reg_rtx (SImode);
9632       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9633       if (sh_compare_op1 != const0_rtx)
9634         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9635                                     ? GET_MODE (sh_compare_op0)
9636                                     : GET_MODE (sh_compare_op1),
9637                                     sh_compare_op1);
9638
9639       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
9640
9641       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
9642       emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9643       if (GET_MODE (operands[0]) == DImode)
9644         emit_insn (gen_extendsidi2 (operands[0], reg));
9645
9646       DONE;
9647     }
9648
9649   if (! currently_expanding_to_rtl)
9650     FAIL;
9651   operands[1] = prepare_scc_operands (GEU);
9652 }")
9653
9654 ;; sne moves the complement of the T reg to DEST like this:
9655 ;;      cmp/eq ...
9656 ;;      mov    #-1,temp
9657 ;;      negc   temp,dest
9658 ;;   This is better than xoring compare result with 1 because it does
9659 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
9660 ;;   loop.
9661
9662 (define_expand "sne"
9663   [(set (match_dup 2) (const_int -1))
9664    (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
9665                    (neg:SI (plus:SI (match_dup 1)
9666                                     (match_dup 2))))
9667               (set (reg:SI T_REG)
9668                    (ne:SI (ior:SI (match_dup 1) (match_dup 2))
9669                           (const_int 0)))])]
9670   ""
9671   "
9672 {
9673   if (TARGET_SHMEDIA)
9674     {
9675       rtx tmp, reg;
9676
9677       reg = operands[0];
9678       if (GET_MODE (operands[0]) != SImode)
9679         reg = no_new_pseudos ? gen_rtx_SUBREG (SImode, operands[0], 0)
9680                              : gen_reg_rtx (SImode);
9681       if (! TARGET_SHMEDIA_FPU
9682           && GET_MODE (sh_compare_op0) != DImode
9683           && GET_MODE (sh_compare_op0) != SImode)
9684         FAIL;
9685
9686       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9687       if (sh_compare_op1 != const0_rtx)
9688         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9689                                     ? GET_MODE (sh_compare_op0)
9690                                     : GET_MODE (sh_compare_op1),
9691                                     sh_compare_op1);
9692
9693       tmp = no_new_pseudos ? reg : gen_reg_rtx (SImode);
9694
9695       emit_insn (gen_seq (tmp));
9696       emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9697       if (GET_MODE (operands[0]) == DImode)
9698         emit_insn (gen_extendsidi2 (operands[0], reg));
9699
9700       DONE;
9701     }
9702
9703   if (sh_expand_t_scc (NE, operands[0]))
9704     DONE;
9705   if (! currently_expanding_to_rtl)
9706     FAIL;
9707   operands[1] = prepare_scc_operands (EQ);
9708   operands[2] = gen_reg_rtx (SImode);
9709 }")
9710
9711 (define_expand "sunordered"
9712   [(set (match_operand:SI 0 "arith_reg_operand" "")
9713         (unordered:SI (match_dup 1) (match_dup 2)))]
9714   "TARGET_SHMEDIA_FPU"
9715   "
9716 {
9717   operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9718   operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
9719 }")
9720
9721 ;; Use the same trick for FP sle / sge
9722
9723 ;; Apart from the constant use and the T setting, this is like movt,
9724 ;; except that it uses the logically negated value of T, i.e.
9725 ;; operand[0] := T ? 0 : 1.
9726 (define_expand "movnegt"
9727   [(set (match_dup 2) (const_int -1))
9728    (parallel [(set (match_operand 0 "" "")
9729                    (neg:SI (plus:SI (match_dup 1)
9730                                     (match_dup 2))))
9731               (set (reg:SI T_REG)
9732                    (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
9733                           (const_int 0)))])]
9734   "TARGET_SH1"
9735   "operands[2] = gen_reg_rtx (SImode);")
9736
9737 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9738 ;; This prevents a regression that occurred when we switched from xor to
9739 ;; mov/neg for sne.
9740
9741 (define_split
9742   [(set (match_operand:SI 0 "arith_reg_dest" "")
9743         (plus:SI (reg:SI T_REG)
9744                  (const_int -1)))]
9745   "TARGET_SH1"
9746   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9747    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9748   "")
9749
9750 ;; -------------------------------------------------------------------------
9751 ;; Instructions to cope with inline literal tables
9752 ;; -------------------------------------------------------------------------
9753
9754 ; 2 byte integer in line
9755
9756 (define_insn "consttable_2"
9757  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9758                     (match_operand 1 "" "")]
9759                    UNSPECV_CONST2)]
9760  ""
9761  "*
9762 {
9763   if (operands[1] != const0_rtx)
9764     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9765   return \"\";
9766 }"
9767  [(set_attr "length" "2")
9768  (set_attr "in_delay_slot" "no")])
9769
9770 ; 4 byte integer in line
9771
9772 (define_insn "consttable_4"
9773  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9774                     (match_operand 1 "" "")]
9775                    UNSPECV_CONST4)]
9776  ""
9777  "*
9778 {
9779   if (operands[1] != const0_rtx)
9780     assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9781   return \"\";
9782 }"
9783  [(set_attr "length" "4")
9784   (set_attr "in_delay_slot" "no")])
9785
9786 ; 8 byte integer in line
9787
9788 (define_insn "consttable_8"
9789  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9790                     (match_operand 1 "" "")]
9791                    UNSPECV_CONST8)]
9792  ""
9793  "*
9794 {
9795   if (operands[1] != const0_rtx)
9796     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9797   return \"\";
9798 }"
9799  [(set_attr "length" "8")
9800   (set_attr "in_delay_slot" "no")])
9801
9802 ; 4 byte floating point
9803
9804 (define_insn "consttable_sf"
9805  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9806                     (match_operand 1 "" "")]
9807                    UNSPECV_CONST4)]
9808  ""
9809  "*
9810 {
9811   if (operands[1] != const0_rtx)
9812     {
9813       REAL_VALUE_TYPE d;
9814       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9815       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9816     }
9817   return \"\";
9818 }"
9819  [(set_attr "length" "4")
9820   (set_attr "in_delay_slot" "no")])
9821
9822 ; 8 byte floating point
9823
9824 (define_insn "consttable_df"
9825  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9826                     (match_operand 1 "" "")]
9827                    UNSPECV_CONST8)]
9828  ""
9829  "*
9830 {
9831   if (operands[1] != const0_rtx)
9832     {
9833       REAL_VALUE_TYPE d;
9834       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9835       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9836     }
9837   return \"\";
9838 }"
9839  [(set_attr "length" "8")
9840   (set_attr "in_delay_slot" "no")])
9841
9842 ;; Alignment is needed for some constant tables; it may also be added for
9843 ;; Instructions at the start of loops, or after unconditional branches.
9844 ;; ??? We would get more accurate lengths if we did instruction
9845 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9846 ;; here is too conservative.
9847
9848 ; align to a two byte boundary
9849
9850 (define_expand "align_2"
9851  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9852  ""
9853  "")
9854
9855 ; align to a four byte boundary
9856 ;; align_4 and align_log are instructions for the starts of loops, or
9857 ;; after unconditional branches, which may take up extra room.
9858
9859 (define_expand "align_4"
9860  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9861  ""
9862  "")
9863
9864 ; align to a cache line boundary
9865
9866 (define_insn "align_log"
9867  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9868  ""
9869  ""
9870  [(set_attr "length" "0")
9871   (set_attr "in_delay_slot" "no")])
9872
9873 ; emitted at the end of the literal table, used to emit the
9874 ; 32bit branch labels if needed.
9875
9876 (define_insn "consttable_end"
9877   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9878   ""
9879   "* return output_jump_label_table ();"
9880   [(set_attr "in_delay_slot" "no")])
9881
9882 ; emitted at the end of the window in the literal table.
9883
9884 (define_insn "consttable_window_end"
9885   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9886   ""
9887   ""
9888   [(set_attr "length" "0")
9889    (set_attr "in_delay_slot" "no")])
9890
9891 ;; -------------------------------------------------------------------------
9892 ;; Misc
9893 ;; -------------------------------------------------------------------------
9894
9895 ;; String/block move insn.
9896
9897 (define_expand "movmemsi"
9898   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9899                    (mem:BLK (match_operand:BLK 1 "" "")))
9900               (use (match_operand:SI 2 "nonmemory_operand" ""))
9901               (use (match_operand:SI 3 "immediate_operand" ""))
9902               (clobber (reg:SI PR_REG))
9903               (clobber (reg:SI R4_REG))
9904               (clobber (reg:SI R5_REG))
9905               (clobber (reg:SI R0_REG))])]
9906   "TARGET_SH1 && ! TARGET_SH5"
9907   "
9908 {
9909   if(expand_block_move (operands))
9910      DONE;
9911   else FAIL;
9912 }")
9913
9914 (define_insn "block_move_real"
9915   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9916                    (mem:BLK (reg:SI R5_REG)))
9917               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9918               (clobber (reg:SI PR_REG))
9919               (clobber (reg:SI R0_REG))])]
9920   "TARGET_SH1 && ! TARGET_HARD_SH4"
9921   "jsr  @%0%#"
9922   [(set_attr "type" "sfunc")
9923    (set_attr "needs_delay_slot" "yes")])
9924
9925 (define_insn "block_lump_real"
9926   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9927                    (mem:BLK (reg:SI R5_REG)))
9928               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9929               (use (reg:SI R6_REG))
9930               (clobber (reg:SI PR_REG))
9931               (clobber (reg:SI T_REG))
9932               (clobber (reg:SI R4_REG))
9933               (clobber (reg:SI R5_REG))
9934               (clobber (reg:SI R6_REG))
9935               (clobber (reg:SI R0_REG))])]
9936   "TARGET_SH1 && ! TARGET_HARD_SH4"
9937   "jsr  @%0%#"
9938   [(set_attr "type" "sfunc")
9939    (set_attr "needs_delay_slot" "yes")])
9940
9941 (define_insn "block_move_real_i4"
9942   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9943                    (mem:BLK (reg:SI R5_REG)))
9944               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9945               (clobber (reg:SI PR_REG))
9946               (clobber (reg:SI R0_REG))
9947               (clobber (reg:SI R1_REG))
9948               (clobber (reg:SI R2_REG))])]
9949   "TARGET_HARD_SH4"
9950   "jsr  @%0%#"
9951   [(set_attr "type" "sfunc")
9952    (set_attr "needs_delay_slot" "yes")])
9953
9954 (define_insn "block_lump_real_i4"
9955   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9956                    (mem:BLK (reg:SI R5_REG)))
9957               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9958               (use (reg:SI R6_REG))
9959               (clobber (reg:SI PR_REG))
9960               (clobber (reg:SI T_REG))
9961               (clobber (reg:SI R4_REG))
9962               (clobber (reg:SI R5_REG))
9963               (clobber (reg:SI R6_REG))
9964               (clobber (reg:SI R0_REG))
9965               (clobber (reg:SI R1_REG))
9966               (clobber (reg:SI R2_REG))
9967               (clobber (reg:SI R3_REG))])]
9968   "TARGET_HARD_SH4"
9969   "jsr  @%0%#"
9970   [(set_attr "type" "sfunc")
9971    (set_attr "needs_delay_slot" "yes")])
9972 \f
9973 ;; -------------------------------------------------------------------------
9974 ;; Floating point instructions.
9975 ;; -------------------------------------------------------------------------
9976
9977 ;; ??? All patterns should have a type attribute.
9978
9979 (define_expand "movpsi"
9980   [(set (match_operand:PSI 0 "register_operand" "")
9981         (match_operand:PSI 1 "general_movsrc_operand" ""))]
9982   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9983   "")
9984
9985 ;; The c / m alternative is a fake to guide reload to load directly into
9986 ;; fpscr, since reload doesn't know how to use post-increment.
9987 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
9988 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9989 ;; predicate after reload.
9990 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9991 ;; like a mac -> gpr move.
9992 (define_insn "fpu_switch"
9993   [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9994         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
9995   "TARGET_SH2E
9996    && (! reload_completed
9997        || true_regnum (operands[0]) != FPSCR_REG
9998        || GET_CODE (operands[1]) != MEM
9999        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
10000   "@
10001         ! precision stays the same
10002         lds.l   %1,fpscr
10003         mov.l   %1,%0
10004         #
10005         lds     %1,fpscr
10006         mov     %1,%0
10007         mov.l   %1,%0
10008         sts     fpscr,%0
10009         sts.l   fpscr,%0"
10010   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
10011    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
10012
10013 (define_peephole2
10014   [(set (reg:PSI FPSCR_REG)
10015         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
10016   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
10017   [(const_int 0)]
10018 {
10019   rtx fpscr, mem, new_insn;
10020
10021   fpscr = SET_DEST (PATTERN (curr_insn));
10022   mem = SET_SRC (PATTERN (curr_insn));
10023   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
10024
10025   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
10026   REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
10027   DONE;
10028 })
10029
10030 (define_split
10031   [(set (reg:PSI FPSCR_REG)
10032         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
10033   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
10034    && (flag_peephole2 ? flow2_completed : reload_completed)"
10035   [(const_int 0)]
10036 {
10037   rtx fpscr, mem, new_insn;
10038
10039   fpscr = SET_DEST (PATTERN (curr_insn));
10040   mem = SET_SRC (PATTERN (curr_insn));
10041   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
10042
10043   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
10044   REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
10045
10046   if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
10047     emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
10048   DONE;
10049 })
10050
10051 ;; ??? This uses the fp unit, but has no type indicating that.
10052 ;; If we did that, this would either give a bogus latency or introduce
10053 ;; a bogus FIFO constraint.
10054 ;; Since this insn is currently only used for prologues/epilogues,
10055 ;; it is probably best to claim no function unit, which matches the
10056 ;; current setting.
10057 (define_insn "toggle_sz"
10058   [(set (reg:PSI FPSCR_REG)
10059         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
10060   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10061   "fschg"
10062   [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
10063
10064 ;; There's no way we can use it today, since optimize mode switching
10065 ;; doesn't enable us to know from which mode we're switching to the
10066 ;; mode it requests, to tell whether we can use a relative mode switch
10067 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
10068 ;; memory).
10069 (define_insn "toggle_pr"
10070   [(set (reg:PSI FPSCR_REG)
10071         (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
10072   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
10073   "fpchg"
10074   [(set_attr "type" "fpscr_toggle")])
10075
10076 (define_expand "addsf3"
10077   [(set (match_operand:SF 0 "arith_reg_operand" "")
10078         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
10079                  (match_operand:SF 2 "arith_reg_operand" "")))]
10080   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10081   "
10082 {
10083   if (TARGET_SH2E)
10084     {
10085       expand_sf_binop (&gen_addsf3_i, operands);
10086       DONE;
10087     }
10088 }")
10089
10090 (define_insn "*addsf3_media"
10091   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10092         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10093                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10094   "TARGET_SHMEDIA_FPU"
10095   "fadd.s       %1, %2, %0"
10096   [(set_attr "type" "fparith_media")])
10097
10098 (define_insn_and_split "unary_sf_op"
10099   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10100         (vec_select:V2SF
10101          (vec_concat:V2SF
10102           (vec_select:SF
10103            (match_dup 0)
10104            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
10105           (match_operator:SF 2 "unary_float_operator"
10106             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10107                             (parallel [(match_operand 4
10108                                         "const_int_operand" "n")]))]))
10109          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
10110   "TARGET_SHMEDIA_FPU"
10111   "#"
10112   "TARGET_SHMEDIA_FPU && reload_completed"
10113   [(set (match_dup 5) (match_dup 6))]
10114   "
10115 {
10116   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10117   rtx op1 = gen_rtx_REG (SFmode,
10118                          (true_regnum (operands[1])
10119                           + (INTVAL (operands[4]) ^ endian)));
10120
10121   operands[7] = gen_rtx_REG (SFmode,
10122                              (true_regnum (operands[0])
10123                               + (INTVAL (operands[3]) ^ endian)));
10124   operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
10125 }"
10126   [(set_attr "type" "fparith_media")])
10127
10128 (define_insn_and_split "binary_sf_op"
10129   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10130         (vec_select:V2SF
10131          (vec_concat:V2SF
10132           (vec_select:SF
10133            (match_dup 0)
10134            (parallel [(match_operand 7 "const_int_operand" "n")]))
10135           (match_operator:SF 3 "binary_float_operator"
10136             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10137                             (parallel [(match_operand 5
10138                                         "const_int_operand" "n")]))
10139              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10140                             (parallel [(match_operand 6
10141                                         "const_int_operand" "n")]))]))
10142          (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
10143   "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
10144   "#"
10145   "&& reload_completed"
10146   [(set (match_dup 8) (match_dup 9))]
10147   "
10148 {
10149   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10150   rtx op1 = gen_rtx_REG (SFmode,
10151                          (true_regnum (operands[1])
10152                           + (INTVAL (operands[5]) ^ endian)));
10153   rtx op2 = gen_rtx_REG (SFmode,
10154                          (true_regnum (operands[2])
10155                           + (INTVAL (operands[6]) ^ endian)));
10156
10157   operands[8] = gen_rtx_REG (SFmode,
10158                              (true_regnum (operands[0])
10159                               + (INTVAL (operands[4]) ^ endian)));
10160   operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10161 }"
10162   [(set_attr "type" "fparith_media")])
10163
10164 (define_insn "addsf3_i"
10165   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10166         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10167                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10168    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10169   "TARGET_SH2E"
10170   "fadd %2,%0"
10171   [(set_attr "type" "fp")
10172    (set_attr "fp_mode" "single")])
10173
10174 (define_expand "subsf3"
10175   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10176         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10177                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10178   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10179   "
10180 {
10181   if (TARGET_SH2E)
10182     {
10183       expand_sf_binop (&gen_subsf3_i, operands);
10184       DONE;
10185     }
10186 }")
10187
10188 (define_insn "*subsf3_media"
10189   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10190         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10191                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10192   "TARGET_SHMEDIA_FPU"
10193   "fsub.s       %1, %2, %0"
10194   [(set_attr "type" "fparith_media")])
10195
10196 (define_insn "subsf3_i"
10197   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10198         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
10199                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10200    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10201   "TARGET_SH2E"
10202   "fsub %2,%0"
10203   [(set_attr "type" "fp")
10204    (set_attr "fp_mode" "single")])
10205
10206 (define_expand "mulsf3"
10207   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10208         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10209                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10210   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10211   "")
10212
10213 (define_insn "*mulsf3_media"
10214   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10215         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10216                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10217   "TARGET_SHMEDIA_FPU"
10218   "fmul.s       %1, %2, %0"
10219   [(set_attr "type" "fparith_media")])
10220
10221 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10222 ;; register in feeding fp instructions.  Thus, in order to generate fmac,
10223 ;; we start out with a mulsf pattern that does not depend on fpscr.
10224 ;; This is split after combine to introduce the dependency, in order to
10225 ;; get mode switching and scheduling right.
10226 (define_insn_and_split "mulsf3_ie"
10227   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10228         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10229                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10230   "TARGET_SH2E"
10231   "fmul %2,%0"
10232   "TARGET_SH4 || TARGET_SH2A_SINGLE"
10233   [(const_int 0)]
10234   "
10235 {
10236   emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2],
10237              get_fpscr_rtx ()));
10238   DONE;
10239 }"
10240   [(set_attr "type" "fp")])
10241
10242 (define_insn "mulsf3_i4"
10243   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10244         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10245                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10246    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10247   "TARGET_SH2E"
10248   "fmul %2,%0"
10249   [(set_attr "type" "fp")
10250    (set_attr "fp_mode" "single")])
10251
10252 (define_insn "mac_media"
10253   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10254         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10255                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10256                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10257   "TARGET_SHMEDIA_FPU && TARGET_FMAC"
10258   "fmac.s %1, %2, %0"
10259   [(set_attr "type" "fparith_media")])
10260
10261 (define_insn "*macsf3"
10262   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10263         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10264                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10265                  (match_operand:SF 3 "arith_reg_operand" "0")))
10266    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10267   "TARGET_SH2E && TARGET_FMAC"
10268   "fmac fr0,%2,%0"
10269   [(set_attr "type" "fp")
10270    (set_attr "fp_mode" "single")])
10271
10272 (define_expand "divsf3"
10273   [(set (match_operand:SF 0 "arith_reg_operand" "")
10274         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10275                 (match_operand:SF 2 "arith_reg_operand" "")))]
10276   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10277   "
10278 {
10279   if (TARGET_SH2E)
10280     {
10281       expand_sf_binop (&gen_divsf3_i, operands);
10282       DONE;
10283     }
10284 }")
10285
10286 (define_insn "*divsf3_media"
10287   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10288         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10289                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10290   "TARGET_SHMEDIA_FPU"
10291   "fdiv.s       %1, %2, %0"
10292   [(set_attr "type" "fdiv_media")])
10293
10294 (define_insn "divsf3_i"
10295   [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10296         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10297                  (match_operand:SF 2 "arith_reg_operand" "f")))
10298    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10299   "TARGET_SH2E"
10300   "fdiv %2,%0"
10301   [(set_attr "type" "fdiv")
10302    (set_attr "fp_mode" "single")])
10303
10304 (define_insn "floatdisf2"
10305   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10306         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10307   "TARGET_SHMEDIA_FPU"
10308   "float.qs %1, %0"
10309   [(set_attr "type" "fpconv_media")])
10310
10311 (define_expand "floatsisf2"
10312   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10313         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10314   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10315   "
10316 {
10317   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10318     {
10319       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10320       DONE;
10321     }
10322 }")
10323
10324 (define_insn "*floatsisf2_media"
10325   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10326         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10327   "TARGET_SHMEDIA_FPU"
10328   "float.ls     %1, %0"
10329   [(set_attr "type" "fpconv_media")])
10330
10331 (define_insn "floatsisf2_i4"
10332   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10333         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10334    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10335   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10336   "float        %1,%0"
10337   [(set_attr "type" "fp")
10338    (set_attr "fp_mode" "single")])
10339
10340 (define_insn "*floatsisf2_ie"
10341   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10342         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10343   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10344   "float        %1,%0"
10345   [(set_attr "type" "fp")])
10346
10347 (define_insn "fix_truncsfdi2"
10348   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10349         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10350   "TARGET_SHMEDIA_FPU"
10351   "ftrc.sq %1, %0"
10352   [(set_attr "type" "fpconv_media")])
10353
10354 (define_expand "fix_truncsfsi2"
10355   [(set (match_operand:SI 0 "fpul_operand" "=y")
10356         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10357   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10358   "
10359 {
10360   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10361     {
10362       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10363       DONE;
10364     }
10365 }")
10366
10367 (define_insn "*fix_truncsfsi2_media"
10368   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10369         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10370   "TARGET_SHMEDIA_FPU"
10371   "ftrc.sl      %1, %0"
10372   [(set_attr "type" "fpconv_media")])
10373
10374 (define_insn "fix_truncsfsi2_i4"
10375   [(set (match_operand:SI 0 "fpul_operand" "=y")
10376         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10377    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10378   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10379   "ftrc %1,%0"
10380   [(set_attr "type" "ftrc_s")
10381    (set_attr "fp_mode" "single")])
10382
10383 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
10384 ;; fix_truncsfsi2_i4.
10385 ;; (define_insn "fix_truncsfsi2_i4_2"
10386 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10387 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10388 ;;   (use (reg:PSI FPSCR_REG))
10389 ;;   (clobber (reg:SI FPUL_REG))]
10390 ;;  "TARGET_SH4"
10391 ;;  "#"
10392 ;;  [(set_attr "length" "4")
10393 ;;   (set_attr "fp_mode" "single")])
10394
10395 ;;(define_split
10396 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10397 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10398 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
10399 ;;   (clobber (reg:SI FPUL_REG))]
10400 ;;  "TARGET_SH4"
10401 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10402 ;;            (use (match_dup 2))])
10403 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
10404
10405 (define_insn "*fixsfsi"
10406   [(set (match_operand:SI 0 "fpul_operand" "=y")
10407         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10408   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10409   "ftrc %1,%0"
10410   [(set_attr "type" "fp")])
10411
10412 (define_insn "cmpgtsf_t"
10413   [(set (reg:SI T_REG)
10414         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10415                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10416   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10417   "fcmp/gt      %1,%0"
10418   [(set_attr "type" "fp_cmp")
10419    (set_attr "fp_mode" "single")])
10420
10421 (define_insn "cmpeqsf_t"
10422   [(set (reg:SI T_REG)
10423         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10424                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10425   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10426   "fcmp/eq      %1,%0"
10427   [(set_attr "type" "fp_cmp")
10428    (set_attr "fp_mode" "single")])
10429
10430 (define_insn "ieee_ccmpeqsf_t"
10431   [(set (reg:SI T_REG)
10432         (ior:SI (reg:SI T_REG)
10433                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10434                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10435   "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10436   "* return output_ieee_ccmpeq (insn, operands);"
10437   [(set_attr "length" "4")])
10438
10439
10440 (define_insn "cmpgtsf_t_i4"
10441   [(set (reg:SI T_REG)
10442         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10443                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10444    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10445   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10446   "fcmp/gt      %1,%0"
10447   [(set_attr "type" "fp_cmp")
10448    (set_attr "fp_mode" "single")])
10449
10450 (define_insn "cmpeqsf_t_i4"
10451   [(set (reg:SI T_REG)
10452         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10453                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10454    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10455   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10456   "fcmp/eq      %1,%0"
10457   [(set_attr "type" "fp_cmp")
10458    (set_attr "fp_mode" "single")])
10459
10460 (define_insn "*ieee_ccmpeqsf_t_4"
10461   [(set (reg:SI T_REG)
10462         (ior:SI (reg:SI T_REG)
10463                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10464                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10465    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10466   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10467   "* return output_ieee_ccmpeq (insn, operands);"
10468   [(set_attr "length" "4")
10469    (set_attr "fp_mode" "single")])
10470
10471 (define_insn "cmpeqsf_media"
10472   [(set (match_operand:SI 0 "register_operand" "=r")
10473         (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10474                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10475   "TARGET_SHMEDIA_FPU"
10476   "fcmpeq.s     %1, %2, %0"
10477   [(set_attr "type" "fcmp_media")])
10478
10479 (define_insn "cmpgtsf_media"
10480   [(set (match_operand:SI 0 "register_operand" "=r")
10481         (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10482                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10483   "TARGET_SHMEDIA_FPU"
10484   "fcmpgt.s     %1, %2, %0"
10485   [(set_attr "type" "fcmp_media")])
10486
10487 (define_insn "cmpgesf_media"
10488   [(set (match_operand:SI 0 "register_operand" "=r")
10489         (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10490                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10491   "TARGET_SHMEDIA_FPU"
10492   "fcmpge.s     %1, %2, %0"
10493   [(set_attr "type" "fcmp_media")])
10494
10495 (define_insn "cmpunsf_media"
10496   [(set (match_operand:SI 0 "register_operand" "=r")
10497         (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10498                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10499   "TARGET_SHMEDIA_FPU"
10500   "fcmpun.s     %1, %2, %0"
10501   [(set_attr "type" "fcmp_media")])
10502
10503 (define_expand "cmpsf"
10504   [(set (reg:SI T_REG)
10505         (compare (match_operand:SF 0 "arith_operand" "")
10506                  (match_operand:SF 1 "arith_operand" "")))]
10507   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10508   "
10509 {
10510   sh_compare_op0 = operands[0];
10511   sh_compare_op1 = operands[1];
10512   DONE;
10513 }")
10514
10515 (define_expand "negsf2"
10516   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10517         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10518   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10519   "
10520 {
10521   if (TARGET_SH2E)
10522     {
10523       expand_sf_unop (&gen_negsf2_i, operands);
10524       DONE;
10525     }
10526 }")
10527
10528 (define_insn "*negsf2_media"
10529   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10530         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10531   "TARGET_SHMEDIA_FPU"
10532   "fneg.s       %1, %0"
10533   [(set_attr "type" "fmove_media")])
10534
10535 (define_insn "negsf2_i"
10536   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10537         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10538    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10539   "TARGET_SH2E"
10540   "fneg %0"
10541   [(set_attr "type" "fmove")
10542    (set_attr "fp_mode" "single")])
10543
10544 (define_expand "sqrtsf2"
10545   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10546         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10547   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10548   "
10549 {
10550   if (TARGET_SH3E)
10551     {
10552       expand_sf_unop (&gen_sqrtsf2_i, operands);
10553       DONE;
10554     }
10555 }")
10556
10557 (define_insn "*sqrtsf2_media"
10558   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10559         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10560   "TARGET_SHMEDIA_FPU"
10561   "fsqrt.s      %1, %0"
10562   [(set_attr "type" "fdiv_media")])
10563
10564 (define_insn "sqrtsf2_i"
10565   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10566         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10567    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10568   "TARGET_SH3E"
10569   "fsqrt        %0"
10570   [(set_attr "type" "fdiv")
10571    (set_attr "fp_mode" "single")])
10572
10573 (define_insn "rsqrtsf2"
10574   [(set (match_operand:SF 0 "register_operand" "=f")
10575         (div:SF (match_operand:SF 1 "immediate_operand" "i")
10576                 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10577    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10578   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10579    && operands[1] == CONST1_RTX (SFmode)"
10580   "fsrra        %0"
10581   [(set_attr "type" "fsrra")
10582    (set_attr "fp_mode" "single")])
10583
10584 (define_insn "fsca"
10585   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10586         (vec_concat:V2SF
10587          (unspec:SF [(mult:SF
10588                       (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10589                       (match_operand:SF 2 "immediate_operand" "i"))
10590                     ] UNSPEC_FSINA)
10591          (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10592                     ] UNSPEC_FCOSA)))
10593    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10594   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10595    && operands[2] == sh_fsca_int2sf ()"
10596   "fsca fpul,%d0"
10597   [(set_attr "type" "fsca")
10598    (set_attr "fp_mode" "single")])
10599
10600 (define_expand "sinsf2"
10601   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10602         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10603                    UNSPEC_FSINA))]
10604   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10605   "
10606 {
10607   rtx scaled = gen_reg_rtx (SFmode);
10608   rtx truncated = gen_reg_rtx (SImode);
10609   rtx fsca = gen_reg_rtx (V2SFmode);
10610   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10611
10612   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10613   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10614   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10615                           get_fpscr_rtx ()));
10616   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10617   DONE;
10618 }")
10619
10620 (define_expand "cossf2"
10621   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10622         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10623                    UNSPEC_FCOSA))]
10624   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10625   "
10626 {
10627   rtx scaled = gen_reg_rtx (SFmode);
10628   rtx truncated = gen_reg_rtx (SImode);
10629   rtx fsca = gen_reg_rtx (V2SFmode);
10630   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10631
10632   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10633   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10634   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10635                           get_fpscr_rtx ()));
10636   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10637   DONE;
10638 }")
10639
10640 (define_expand "sindf2"
10641   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10642         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10643                    UNSPEC_FSINA))]
10644   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10645   "
10646 {
10647   rtx scaled = gen_reg_rtx (DFmode);
10648   rtx truncated = gen_reg_rtx (SImode);
10649   rtx fsca = gen_reg_rtx (V2SFmode);
10650   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10651   rtx sfresult = gen_reg_rtx (SFmode);
10652
10653   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10654   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10655   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10656                           get_fpscr_rtx ()));
10657   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10658   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10659   DONE;
10660 }")
10661
10662 (define_expand "cosdf2"
10663   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10664         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10665                    UNSPEC_FCOSA))]
10666   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10667   "
10668 {
10669   rtx scaled = gen_reg_rtx (DFmode);
10670   rtx truncated = gen_reg_rtx (SImode);
10671   rtx fsca = gen_reg_rtx (V2SFmode);
10672   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10673   rtx sfresult = gen_reg_rtx (SFmode);
10674
10675   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10676   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10677   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10678                           get_fpscr_rtx ()));
10679   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10680   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10681   DONE;
10682 }")
10683
10684 (define_expand "abssf2"
10685   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10686         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10687   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10688   "
10689 {
10690   if (TARGET_SH2E)
10691     {
10692       expand_sf_unop (&gen_abssf2_i, operands);
10693       DONE;
10694     }
10695 }")
10696
10697 (define_insn "*abssf2_media"
10698   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10699         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10700   "TARGET_SHMEDIA_FPU"
10701   "fabs.s       %1, %0"
10702   [(set_attr "type" "fmove_media")])
10703
10704 (define_insn "abssf2_i"
10705   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10706         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10707    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10708   "TARGET_SH2E"
10709   "fabs %0"
10710   [(set_attr "type" "fmove")
10711    (set_attr "fp_mode" "single")])
10712
10713 (define_expand "adddf3"
10714   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10715         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10716                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10717   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10718   "
10719 {
10720   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10721     {
10722       expand_df_binop (&gen_adddf3_i, operands);
10723       DONE;
10724     }
10725 }")
10726
10727 (define_insn "*adddf3_media"
10728   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10729         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10730                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10731   "TARGET_SHMEDIA_FPU"
10732   "fadd.d       %1, %2, %0"
10733   [(set_attr "type" "dfparith_media")])
10734
10735 (define_insn "adddf3_i"
10736   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10737         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10738                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10739    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10740   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10741   "fadd %2,%0"
10742   [(set_attr "type" "dfp_arith")
10743    (set_attr "fp_mode" "double")])
10744
10745 (define_expand "subdf3"
10746   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10747         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10748                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10749   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10750   "
10751 {
10752   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10753     {
10754       expand_df_binop (&gen_subdf3_i, operands);
10755       DONE;
10756     }
10757 }")
10758
10759 (define_insn "*subdf3_media"
10760   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10761         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10762                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10763   "TARGET_SHMEDIA_FPU"
10764   "fsub.d       %1, %2, %0"
10765   [(set_attr "type" "dfparith_media")])
10766
10767 (define_insn "subdf3_i"
10768   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10769         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10770                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10771    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10772   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10773   "fsub %2,%0"
10774   [(set_attr "type" "dfp_arith")
10775    (set_attr "fp_mode" "double")])
10776
10777 (define_expand "muldf3"
10778   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10779         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10780                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10781   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10782   "
10783 {
10784   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10785     {
10786       expand_df_binop (&gen_muldf3_i, operands);
10787       DONE;
10788     }
10789 }")
10790
10791 (define_insn "*muldf3_media"
10792   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10793         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10794                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10795   "TARGET_SHMEDIA_FPU"
10796   "fmul.d       %1, %2, %0"
10797   [(set_attr "type" "dfmul_media")])
10798
10799 (define_insn "muldf3_i"
10800   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10801         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10802                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10803    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10804   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10805   "fmul %2,%0"
10806   [(set_attr "type" "dfp_mul")
10807    (set_attr "fp_mode" "double")])
10808
10809 (define_expand "divdf3"
10810   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10811         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10812                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10813   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10814   "
10815 {
10816   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10817     {
10818       expand_df_binop (&gen_divdf3_i, operands);
10819       DONE;
10820     }
10821 }")
10822
10823 (define_insn "*divdf3_media"
10824   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10825         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10826                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10827   "TARGET_SHMEDIA_FPU"
10828   "fdiv.d       %1, %2, %0"
10829   [(set_attr "type" "dfdiv_media")])
10830
10831 (define_insn "divdf3_i"
10832   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10833         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10834                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10835    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10836   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10837   "fdiv %2,%0"
10838   [(set_attr "type" "dfdiv")
10839    (set_attr "fp_mode" "double")])
10840
10841 (define_insn "floatdidf2"
10842   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10843         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10844   "TARGET_SHMEDIA_FPU"
10845   "float.qd     %1, %0"
10846   [(set_attr "type" "dfpconv_media")])
10847
10848 (define_expand "floatsidf2"
10849   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10850         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10851   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10852   "
10853 {
10854   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10855     {
10856       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10857                                       get_fpscr_rtx ()));
10858       DONE;
10859     }
10860 }")
10861
10862 (define_insn "*floatsidf2_media"
10863   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10864         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10865   "TARGET_SHMEDIA_FPU"
10866   "float.ld     %1, %0"
10867   [(set_attr "type" "dfpconv_media")])
10868
10869 (define_insn "floatsidf2_i"
10870   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10871         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10872    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10873   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10874   "float        %1,%0"
10875   [(set_attr "type" "dfp_conv")
10876    (set_attr "fp_mode" "double")])
10877
10878 (define_insn "fix_truncdfdi2"
10879   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10880         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10881   "TARGET_SHMEDIA_FPU"
10882   "ftrc.dq      %1, %0"
10883   [(set_attr "type" "dfpconv_media")])
10884
10885 (define_expand "fix_truncdfsi2"
10886   [(set (match_operand:SI 0 "fpul_operand" "")
10887         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10888   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10889   "
10890 {
10891   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10892     {
10893       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10894                                           get_fpscr_rtx ()));
10895       DONE;
10896     }
10897 }")
10898
10899 (define_insn "*fix_truncdfsi2_media"
10900   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10901         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10902   "TARGET_SHMEDIA_FPU"
10903   "ftrc.dl      %1, %0"
10904   [(set_attr "type" "dfpconv_media")])
10905
10906 (define_insn "fix_truncdfsi2_i"
10907   [(set (match_operand:SI 0 "fpul_operand" "=y")
10908         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10909    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10910   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10911   "ftrc %1,%0"
10912   [(set_attr "type" "dfp_conv")
10913    (set_attr "dfp_comp" "no")
10914    (set_attr "fp_mode" "double")])
10915
10916 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
10917 ;; fix_truncdfsi2_i.
10918 ;; (define_insn "fix_truncdfsi2_i4"
10919 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10920 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10921 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10922 ;;    (clobber (reg:SI FPUL_REG))]
10923 ;;   "TARGET_SH4"
10924 ;;   "#"
10925 ;;   [(set_attr "length" "4")
10926 ;;    (set_attr "fp_mode" "double")])
10927 ;;
10928 ;; (define_split
10929 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10930 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10931 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10932 ;;    (clobber (reg:SI FPUL_REG))]
10933 ;;   "TARGET_SH4"
10934 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10935 ;;            (use (match_dup 2))])
10936 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
10937
10938 (define_insn "cmpgtdf_t"
10939   [(set (reg:SI T_REG)
10940         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10941                (match_operand:DF 1 "arith_reg_operand" "f")))
10942    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10943   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10944   "fcmp/gt      %1,%0"
10945   [(set_attr "type" "dfp_cmp")
10946    (set_attr "fp_mode" "double")])
10947
10948 (define_insn "cmpeqdf_t"
10949   [(set (reg:SI T_REG)
10950         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10951                (match_operand:DF 1 "arith_reg_operand" "f")))
10952    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10953   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10954   "fcmp/eq      %1,%0"
10955   [(set_attr "type" "dfp_cmp")
10956    (set_attr "fp_mode" "double")])
10957
10958 (define_insn "*ieee_ccmpeqdf_t"
10959   [(set (reg:SI T_REG)
10960         (ior:SI (reg:SI T_REG)
10961                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10962                        (match_operand:DF 1 "arith_reg_operand" "f"))))
10963    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10964   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10965   "* return output_ieee_ccmpeq (insn, operands);"
10966   [(set_attr "length" "4")
10967    (set_attr "fp_mode" "double")])
10968
10969 (define_insn "cmpeqdf_media"
10970   [(set (match_operand:SI 0 "register_operand" "=r")
10971         (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10972                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10973   "TARGET_SHMEDIA_FPU"
10974   "fcmpeq.d     %1,%2,%0"
10975   [(set_attr "type" "fcmp_media")])
10976
10977 (define_insn "cmpgtdf_media"
10978   [(set (match_operand:SI 0 "register_operand" "=r")
10979         (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10980                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10981   "TARGET_SHMEDIA_FPU"
10982   "fcmpgt.d     %1,%2,%0"
10983   [(set_attr "type" "fcmp_media")])
10984
10985 (define_insn "cmpgedf_media"
10986   [(set (match_operand:SI 0 "register_operand" "=r")
10987         (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10988                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10989   "TARGET_SHMEDIA_FPU"
10990   "fcmpge.d     %1,%2,%0"
10991   [(set_attr "type" "fcmp_media")])
10992
10993 (define_insn "cmpundf_media"
10994   [(set (match_operand:SI 0 "register_operand" "=r")
10995         (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10996                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10997   "TARGET_SHMEDIA_FPU"
10998   "fcmpun.d     %1,%2,%0"
10999   [(set_attr "type" "fcmp_media")])
11000
11001 (define_expand "cmpdf"
11002   [(set (reg:SI T_REG)
11003         (compare (match_operand:DF 0 "arith_operand" "")
11004                  (match_operand:DF 1 "arith_operand" "")))]
11005   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11006   "
11007 {
11008   sh_compare_op0 = operands[0];
11009   sh_compare_op1 = operands[1];
11010   DONE;
11011 }")
11012
11013 (define_expand "negdf2"
11014   [(set (match_operand:DF 0 "arith_reg_operand" "")
11015         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11016   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11017   "
11018 {
11019   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11020     {
11021       expand_df_unop (&gen_negdf2_i, operands);
11022       DONE;
11023     }
11024 }")
11025
11026 (define_insn "*negdf2_media"
11027   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11028         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11029   "TARGET_SHMEDIA_FPU"
11030   "fneg.d       %1, %0"
11031   [(set_attr "type" "fmove_media")])
11032
11033 (define_insn "negdf2_i"
11034   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11035         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11036    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11037   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11038   "fneg %0"
11039   [(set_attr "type" "fmove")
11040    (set_attr "fp_mode" "double")])
11041
11042 (define_expand "sqrtdf2"
11043   [(set (match_operand:DF 0 "arith_reg_operand" "")
11044         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11045   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11046   "
11047 {
11048   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11049     {
11050       expand_df_unop (&gen_sqrtdf2_i, operands);
11051       DONE;
11052     }
11053 }")
11054
11055 (define_insn "*sqrtdf2_media"
11056   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11057         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11058   "TARGET_SHMEDIA_FPU"
11059   "fsqrt.d      %1, %0"
11060   [(set_attr "type" "dfdiv_media")])
11061
11062 (define_insn "sqrtdf2_i"
11063   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11064         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11065    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11066   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11067   "fsqrt        %0"
11068   [(set_attr "type" "dfdiv")
11069    (set_attr "fp_mode" "double")])
11070
11071 (define_expand "absdf2"
11072   [(set (match_operand:DF 0 "arith_reg_operand" "")
11073         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11074   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11075   "
11076 {
11077   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11078     {
11079       expand_df_unop (&gen_absdf2_i, operands);
11080       DONE;
11081     }
11082 }")
11083
11084 (define_insn "*absdf2_media"
11085   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11086         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11087   "TARGET_SHMEDIA_FPU"
11088   "fabs.d       %1, %0"
11089   [(set_attr "type" "fmove_media")])
11090
11091 (define_insn "absdf2_i"
11092   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11093         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11094    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11095   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11096   "fabs %0"
11097   [(set_attr "type" "fmove")
11098    (set_attr "fp_mode" "double")])
11099
11100 (define_expand "extendsfdf2"
11101   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11102         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
11103   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11104   "
11105 {
11106   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11107     {
11108       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
11109                                         get_fpscr_rtx ()));
11110       DONE;
11111     }
11112 }")
11113
11114 (define_insn "*extendsfdf2_media"
11115   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11116         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11117   "TARGET_SHMEDIA_FPU"
11118   "fcnv.sd      %1, %0"
11119   [(set_attr "type" "dfpconv_media")])
11120
11121 (define_insn "extendsfdf2_i4"
11122   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11123         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
11124    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11125   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11126   "fcnvsd  %1,%0"
11127   [(set_attr "type" "fp")
11128    (set_attr "fp_mode" "double")])
11129
11130 (define_expand "truncdfsf2"
11131   [(set (match_operand:SF 0 "fpul_operand" "")
11132         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11133   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11134   "
11135 {
11136   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11137     {
11138       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
11139                                        get_fpscr_rtx ()));
11140       DONE;
11141     }
11142 }")
11143
11144 (define_insn "*truncdfsf2_media"
11145   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11146         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11147   "TARGET_SHMEDIA_FPU"
11148   "fcnv.ds      %1, %0"
11149   [(set_attr "type" "dfpconv_media")])
11150
11151 (define_insn "truncdfsf2_i4"
11152   [(set (match_operand:SF 0 "fpul_operand" "=y")
11153         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11154    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11155   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11156   "fcnvds  %1,%0"
11157   [(set_attr "type" "fp")
11158    (set_attr "fp_mode" "double")])
11159 \f
11160 ;; Bit field extract patterns.  These give better code for packed bitfields,
11161 ;; because they allow auto-increment addresses to be generated.
11162
11163 (define_expand "insv"
11164   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
11165                          (match_operand:SI 1 "immediate_operand" "")
11166                          (match_operand:SI 2 "immediate_operand" ""))
11167         (match_operand:SI 3 "general_operand" ""))]
11168   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
11169   "
11170 {
11171   rtx addr_target, orig_address, shift_reg, qi_val;
11172   HOST_WIDE_INT bitsize, size, v = 0;
11173   rtx x = operands[3];
11174
11175   /* ??? expmed doesn't care for non-register predicates.  */
11176   if (! memory_operand (operands[0], VOIDmode)
11177       || ! immediate_operand (operands[1], VOIDmode)
11178       || ! immediate_operand (operands[2], VOIDmode)
11179       || ! general_operand (x, VOIDmode))
11180     FAIL;
11181   /* If this isn't a 16 / 24 / 32 bit field, or if
11182      it doesn't start on a byte boundary, then fail.  */
11183   bitsize = INTVAL (operands[1]);
11184   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
11185       || (INTVAL (operands[2]) % 8) != 0)
11186     FAIL;
11187
11188   size = bitsize / 8;
11189   orig_address = XEXP (operands[0], 0);
11190   shift_reg = gen_reg_rtx (SImode);
11191   if (GET_CODE (x) == CONST_INT)
11192     {
11193       v = INTVAL (x);
11194       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11195     }
11196   else
11197     {
11198       emit_insn (gen_movsi (shift_reg, operands[3]));
11199       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11200     }
11201   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11202
11203   operands[0] = replace_equiv_address (operands[0], addr_target);
11204   emit_insn (gen_movqi (operands[0], qi_val));
11205
11206   while (size -= 1)
11207     {
11208       if (GET_CODE (x) == CONST_INT)
11209         qi_val
11210           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11211       else
11212         {
11213           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11214           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11215         }
11216       emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11217       emit_insn (gen_movqi (operands[0], qi_val));
11218     }
11219
11220   DONE;
11221 }")
11222
11223 (define_insn "movua"
11224   [(set (match_operand:SI 0 "register_operand" "=z")
11225         (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
11226                    UNSPEC_MOVUA))]
11227   "TARGET_SH4A_ARCH"
11228   "movua.l      %1,%0"
11229   [(set_attr "type" "movua")])
11230
11231 ;; We shouldn't need this, but cse replaces increments with references
11232 ;; to other regs before flow has a chance to create post_inc
11233 ;; addressing modes, and only postreload's cse_move2add brings the
11234 ;; increments back to a usable form.
11235 (define_peephole2
11236   [(set (match_operand:SI 0 "register_operand" "")
11237         (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11238                          (const_int 32) (const_int 0)))
11239    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11240   "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11241   [(set (match_operand:SI 0 "register_operand" "")
11242         (sign_extract:SI (mem:SI (post_inc:SI
11243                                   (match_operand:SI 1 "register_operand" "")))
11244                          (const_int 32) (const_int 0)))]
11245   "")
11246
11247 (define_expand "extv"
11248   [(set (match_operand:SI 0 "register_operand" "")
11249         (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11250                          (match_operand 2 "const_int_operand" "")
11251                          (match_operand 3 "const_int_operand" "")))]
11252   "TARGET_SH4A_ARCH"
11253 {
11254   if (TARGET_SH4A_ARCH
11255       && INTVAL (operands[2]) == 32
11256       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11257       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11258     {
11259       rtx src = adjust_address (operands[1], BLKmode, 0);
11260       set_mem_size (src, GEN_INT (4));
11261       emit_insn (gen_movua (operands[0], src));
11262       DONE;
11263     }
11264
11265   FAIL;
11266 })
11267
11268 (define_expand "extzv"
11269   [(set (match_operand:SI 0 "register_operand" "")
11270         (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11271                          (match_operand 2 "const_int_operand" "")
11272                          (match_operand 3 "const_int_operand" "")))]
11273   "TARGET_SH4A_ARCH"
11274 {
11275   if (TARGET_SH4A_ARCH
11276       && INTVAL (operands[2]) == 32
11277       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11278       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11279     {
11280       rtx src = adjust_address (operands[1], BLKmode, 0);
11281       set_mem_size (src, GEN_INT (4));
11282       emit_insn (gen_movua (operands[0], src));
11283       DONE;
11284     }
11285
11286   FAIL;
11287 })
11288
11289 \f
11290 ;; -------------------------------------------------------------------------
11291 ;; Peepholes
11292 ;; -------------------------------------------------------------------------
11293
11294 ;; This matches cases where a stack pointer increment at the start of the
11295 ;; epilogue combines with a stack slot read loading the return value.
11296
11297 (define_peephole
11298   [(set (match_operand:SI 0 "arith_reg_operand" "")
11299         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11300    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11301   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11302   "mov.l        @%1+,%0")
11303
11304 ;; See the comment on the dt combiner pattern above.
11305
11306 (define_peephole
11307   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11308         (plus:SI (match_dup 0)
11309                  (const_int -1)))
11310    (set (reg:SI T_REG)
11311         (eq:SI (match_dup 0)
11312                (const_int 0)))]
11313   "TARGET_SH2"
11314   "dt   %0")
11315
11316 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11317 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
11318 ;; reload when the constant is too large for a reg+offset address.
11319
11320 ;; ??? We would get much better code if this was done in reload.  This would
11321 ;; require modifying find_reloads_address to recognize that if the constant
11322 ;; is out-of-range for an immediate add, then we get better code by reloading
11323 ;; the constant into a register than by reloading the sum into a register,
11324 ;; since the former is one instruction shorter if the address does not need
11325 ;; to be offsettable.  Unfortunately this does not work, because there is
11326 ;; only one register, r0, that can be used as an index register.  This register
11327 ;; is also the function return value register.  So, if we try to force reload
11328 ;; to use double-reg addresses, then we end up with some instructions that
11329 ;; need to use r0 twice.  The only way to fix this is to change the calling
11330 ;; convention so that r0 is not used to return values.
11331
11332 (define_peephole
11333   [(set (match_operand:SI 0 "register_operand" "=r")
11334         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11335    (set (mem:SI (match_dup 0))
11336         (match_operand:SI 2 "general_movsrc_operand" ""))]
11337   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11338   "mov.l        %2,@(%0,%1)")
11339
11340 (define_peephole
11341   [(set (match_operand:SI 0 "register_operand" "=r")
11342         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11343    (set (match_operand:SI 2 "general_movdst_operand" "")
11344         (mem:SI (match_dup 0)))]
11345   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11346   "mov.l        @(%0,%1),%2")
11347
11348 (define_peephole
11349   [(set (match_operand:SI 0 "register_operand" "=r")
11350         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11351    (set (mem:HI (match_dup 0))
11352         (match_operand:HI 2 "general_movsrc_operand" ""))]
11353   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11354   "mov.w        %2,@(%0,%1)")
11355
11356 (define_peephole
11357   [(set (match_operand:SI 0 "register_operand" "=r")
11358         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11359    (set (match_operand:HI 2 "general_movdst_operand" "")
11360         (mem:HI (match_dup 0)))]
11361   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11362   "mov.w        @(%0,%1),%2")
11363
11364 (define_peephole
11365   [(set (match_operand:SI 0 "register_operand" "=r")
11366         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11367    (set (mem:QI (match_dup 0))
11368         (match_operand:QI 2 "general_movsrc_operand" ""))]
11369   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11370   "mov.b        %2,@(%0,%1)")
11371
11372 (define_peephole
11373   [(set (match_operand:SI 0 "register_operand" "=r")
11374         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11375    (set (match_operand:QI 2 "general_movdst_operand" "")
11376         (mem:QI (match_dup 0)))]
11377   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11378   "mov.b        @(%0,%1),%2")
11379
11380 (define_peephole
11381   [(set (match_operand:SI 0 "register_operand" "=r")
11382         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11383    (set (mem:SF (match_dup 0))
11384         (match_operand:SF 2 "general_movsrc_operand" ""))]
11385   "TARGET_SH1 && REGNO (operands[0]) == 0
11386    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11387        || (GET_CODE (operands[2]) == SUBREG
11388            && REGNO (SUBREG_REG (operands[2])) < 16))
11389    && reg_unused_after (operands[0], insn)"
11390   "mov.l        %2,@(%0,%1)")
11391
11392 (define_peephole
11393   [(set (match_operand:SI 0 "register_operand" "=r")
11394         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11395    (set (match_operand:SF 2 "general_movdst_operand" "")
11396
11397         (mem:SF (match_dup 0)))]
11398   "TARGET_SH1 && REGNO (operands[0]) == 0
11399    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11400        || (GET_CODE (operands[2]) == SUBREG
11401            && REGNO (SUBREG_REG (operands[2])) < 16))
11402    && reg_unused_after (operands[0], insn)"
11403   "mov.l        @(%0,%1),%2")
11404
11405 (define_peephole
11406   [(set (match_operand:SI 0 "register_operand" "=r")
11407         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11408    (set (mem:SF (match_dup 0))
11409         (match_operand:SF 2 "general_movsrc_operand" ""))]
11410   "TARGET_SH2E && REGNO (operands[0]) == 0
11411    && ((GET_CODE (operands[2]) == REG
11412         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11413        || (GET_CODE (operands[2]) == SUBREG
11414            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11415    && reg_unused_after (operands[0], insn)"
11416   "fmov{.s|}    %2,@(%0,%1)")
11417
11418 (define_peephole
11419   [(set (match_operand:SI 0 "register_operand" "=r")
11420         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11421    (set (match_operand:SF 2 "general_movdst_operand" "")
11422
11423         (mem:SF (match_dup 0)))]
11424   "TARGET_SH2E && REGNO (operands[0]) == 0
11425    && ((GET_CODE (operands[2]) == REG
11426         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11427        || (GET_CODE (operands[2]) == SUBREG
11428            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11429    && reg_unused_after (operands[0], insn)"
11430   "fmov{.s|}    @(%0,%1),%2")
11431
11432 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
11433 (define_insn "sp_switch_1"
11434   [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11435   "TARGET_SH1"
11436   "*
11437 {
11438   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11439   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11440   return \"mov r0,r15\";
11441 }"
11442   [(set_attr "length" "10")])
11443
11444 ;; Switch back to the original stack for interrupt functions with the
11445 ;; sp_switch attribute.  */
11446 (define_insn "sp_switch_2"
11447   [(const_int 2)]
11448   "TARGET_SH1"
11449   "mov.l @r15+,r15\;mov.l @r15+,r0"
11450   [(set_attr "length" "4")])
11451
11452 ;; Integer vector moves
11453
11454 (define_expand "movv8qi"
11455   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11456         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11457   "TARGET_SHMEDIA"
11458   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11459
11460 (define_insn "movv8qi_i"
11461   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11462         (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11463   "TARGET_SHMEDIA
11464    && (register_operand (operands[0], V8QImode)
11465        || sh_register_operand (operands[1], V8QImode))"
11466   "@
11467         add     %1, r63, %0
11468         movi    %1, %0
11469         #
11470         ld%M1.q %m1, %0
11471         st%M0.q %m0, %N1"
11472   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11473    (set_attr "length" "4,4,16,4,4")])
11474
11475 (define_split
11476   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11477         (subreg:V8QI (const_int 0) 0))]
11478   "TARGET_SHMEDIA"
11479   [(set (match_dup 0)
11480         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11481                             (const_int 0) (const_int 0) (const_int 0)
11482                             (const_int 0) (const_int 0)]))])
11483
11484 (define_split
11485   [(set (match_operand 0 "arith_reg_dest" "")
11486         (match_operand 1 "sh_rep_vec" ""))]
11487   "TARGET_SHMEDIA && reload_completed
11488    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11489    && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11490    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11491    && (XVECEXP (operands[1], 0, 0) != const0_rtx
11492        || XVECEXP (operands[1], 0, 1) != const0_rtx)
11493    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11494        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11495   [(set (match_dup 0) (match_dup 1))
11496    (match_dup 2)]
11497   "
11498 {
11499   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11500   rtx elt1 = XVECEXP (operands[1], 0, 1);
11501
11502   if (unit_size > 2)
11503     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11504   else
11505     {
11506       if (unit_size < 2)
11507         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11508       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11509     }
11510   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11511   operands[1] = XVECEXP (operands[1], 0, 0);
11512   if (unit_size < 2)
11513     {
11514       if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
11515         operands[1]
11516           = GEN_INT (TARGET_LITTLE_ENDIAN
11517                      ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11518                      : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11519       else
11520         {
11521           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11522           operands[1]
11523             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11524         }
11525     }
11526 }")
11527
11528 (define_split
11529   [(set (match_operand 0 "arith_reg_dest" "")
11530         (match_operand 1 "sh_const_vec" ""))]
11531   "TARGET_SHMEDIA && reload_completed
11532    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11533    && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11534   [(set (match_dup 0) (match_dup 1))]
11535   "
11536 {
11537   rtx v = operands[1];
11538   enum machine_mode new_mode
11539     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11540
11541   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11542   operands[1]
11543     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11544 }")
11545
11546 (define_expand "movv2hi"
11547   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11548         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11549   "TARGET_SHMEDIA"
11550   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11551
11552 (define_insn "movv2hi_i"
11553   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11554         (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11555   "TARGET_SHMEDIA
11556    && (register_operand (operands[0], V2HImode)
11557        || sh_register_operand (operands[1], V2HImode))"
11558   "@
11559         add.l   %1, r63, %0
11560         movi    %1, %0
11561         #
11562         ld%M1.l %m1, %0
11563         st%M0.l %m0, %N1"
11564   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11565    (set_attr "length" "4,4,16,4,4")
11566    (set (attr "highpart")
11567         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
11568                (const_string "user")]
11569               (const_string "ignore")))])
11570
11571 (define_expand "movv4hi"
11572   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11573         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11574   "TARGET_SHMEDIA"
11575   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11576
11577 (define_insn "movv4hi_i"
11578   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11579         (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11580   "TARGET_SHMEDIA
11581    && (register_operand (operands[0], V4HImode)
11582        || sh_register_operand (operands[1], V4HImode))"
11583   "@
11584         add     %1, r63, %0
11585         movi    %1, %0
11586         #
11587         ld%M1.q %m1, %0
11588         st%M0.q %m0, %N1"
11589   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11590    (set_attr "length" "4,4,16,4,4")
11591    (set_attr "highpart" "depend")])
11592
11593 (define_expand "movv2si"
11594   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11595         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11596   "TARGET_SHMEDIA"
11597   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11598
11599 (define_insn "movv2si_i"
11600   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11601         (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11602   "TARGET_SHMEDIA
11603    && (register_operand (operands[0], V2SImode)
11604        || sh_register_operand (operands[1], V2SImode))"
11605   "@
11606         add     %1, r63, %0
11607         #
11608         #
11609         ld%M1.q %m1, %0
11610         st%M0.q %m0, %N1"
11611   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11612    (set_attr "length" "4,4,16,4,4")
11613    (set_attr "highpart" "depend")])
11614
11615 ;; Multimedia Intrinsics
11616
11617 (define_insn "absv2si2"
11618   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11619         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11620   "TARGET_SHMEDIA"
11621   "mabs.l       %1, %0"
11622   [(set_attr "type" "mcmp_media")
11623    (set_attr "highpart" "depend")])
11624
11625 (define_insn "absv4hi2"
11626   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11627         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11628   "TARGET_SHMEDIA"
11629   "mabs.w       %1, %0"
11630   [(set_attr "type" "mcmp_media")
11631    (set_attr "highpart" "depend")])
11632
11633 (define_insn "addv2si3"
11634   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11635         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11636                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11637   "TARGET_SHMEDIA"
11638   "madd.l       %1, %2, %0"
11639   [(set_attr "type" "arith_media")
11640    (set_attr "highpart" "depend")])
11641
11642 (define_insn "addv4hi3"
11643   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11644         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11645                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11646   "TARGET_SHMEDIA"
11647   "madd.w       %1, %2, %0"
11648   [(set_attr "type" "arith_media")
11649    (set_attr "highpart" "depend")])
11650
11651 (define_insn_and_split "addv2hi3"
11652   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11653         (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11654                    (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11655   "TARGET_SHMEDIA"
11656   "#"
11657   "TARGET_SHMEDIA"
11658   [(const_int 0)]
11659   "
11660 {
11661   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11662   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11663   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11664   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11665   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11666
11667   emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11668   emit_insn (gen_truncdisi2 (si_dst, di_dst));
11669   DONE;
11670 }"
11671   [(set_attr "highpart" "must_split")])
11672
11673 (define_insn "ssaddv2si3"
11674   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11675         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11676                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11677   "TARGET_SHMEDIA"
11678   "madds.l      %1, %2, %0"
11679   [(set_attr "type" "mcmp_media")
11680    (set_attr "highpart" "depend")])
11681
11682 (define_insn "usaddv8qi3"
11683   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11684         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11685                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11686   "TARGET_SHMEDIA"
11687   "madds.ub     %1, %2, %0"
11688   [(set_attr "type" "mcmp_media")
11689    (set_attr "highpart" "depend")])
11690
11691 (define_insn "ssaddv4hi3"
11692   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11693         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11694                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11695   "TARGET_SHMEDIA"
11696   "madds.w      %1, %2, %0"
11697   [(set_attr "type" "mcmp_media")
11698    (set_attr "highpart" "depend")])
11699
11700 (define_insn "negcmpeqv8qi"
11701   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11702         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11703                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11704   "TARGET_SHMEDIA"
11705   "mcmpeq.b     %N1, %N2, %0"
11706   [(set_attr "type" "mcmp_media")
11707    (set_attr "highpart" "depend")])
11708
11709 (define_insn "negcmpeqv2si"
11710   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11711         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11712                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11713   "TARGET_SHMEDIA"
11714   "mcmpeq.l     %N1, %N2, %0"
11715   [(set_attr "type" "mcmp_media")
11716    (set_attr "highpart" "depend")])
11717
11718 (define_insn "negcmpeqv4hi"
11719   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11720         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11721                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11722   "TARGET_SHMEDIA"
11723   "mcmpeq.w     %N1, %N2, %0"
11724   [(set_attr "type" "mcmp_media")
11725    (set_attr "highpart" "depend")])
11726
11727 (define_insn "negcmpgtuv8qi"
11728   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11729         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11730                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11731   "TARGET_SHMEDIA"
11732   "mcmpgt.ub    %N1, %N2, %0"
11733   [(set_attr "type" "mcmp_media")
11734    (set_attr "highpart" "depend")])
11735
11736 (define_insn "negcmpgtv2si"
11737   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11738         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11739                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11740   "TARGET_SHMEDIA"
11741   "mcmpgt.l     %N1, %N2, %0"
11742   [(set_attr "type" "mcmp_media")
11743    (set_attr "highpart" "depend")])
11744
11745 (define_insn "negcmpgtv4hi"
11746   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11747         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11748                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11749   "TARGET_SHMEDIA"
11750   "mcmpgt.w     %N1, %N2, %0"
11751   [(set_attr "type" "mcmp_media")
11752    (set_attr "highpart" "depend")])
11753
11754 (define_insn "mcmv"
11755   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11756         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11757                         (match_operand:DI 2 "arith_reg_operand" "r"))
11758                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11759                         (not:DI (match_dup 2)))))]
11760   "TARGET_SHMEDIA"
11761   "mcmv %N1, %2, %0"
11762   [(set_attr "type" "arith_media")
11763    (set_attr "highpart" "depend")])
11764
11765 (define_insn "mcnvs_lw"
11766   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11767         (vec_concat:V4HI
11768          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11769          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11770   "TARGET_SHMEDIA"
11771   "mcnvs.lw     %N1, %N2, %0"
11772   [(set_attr "type" "mcmp_media")])
11773
11774 (define_insn "mcnvs_wb"
11775   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11776         (vec_concat:V8QI
11777          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11778          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11779   "TARGET_SHMEDIA"
11780   "mcnvs.wb     %N1, %N2, %0"
11781   [(set_attr "type" "mcmp_media")])
11782
11783 (define_insn "mcnvs_wub"
11784   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11785         (vec_concat:V8QI
11786          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11787          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11788   "TARGET_SHMEDIA"
11789   "mcnvs.wub    %N1, %N2, %0"
11790   [(set_attr "type" "mcmp_media")])
11791
11792 (define_insn "mextr_rl"
11793   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11794         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11795                              (match_operand:HI 3 "mextr_bit_offset" "i"))
11796                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11797                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11798   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11799   "*
11800 {
11801   static char templ[21];
11802
11803   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
11804            (int) INTVAL (operands[3]) >> 3);
11805   return templ;
11806 }"
11807   [(set_attr "type" "arith_media")])
11808
11809 (define_insn "*mextr_lr"
11810   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11811         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11812                            (match_operand:HI 3 "mextr_bit_offset" "i"))
11813                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11814                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11815   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11816   "*
11817 {
11818   static char templ[21];
11819
11820   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
11821            (int) INTVAL (operands[4]) >> 3);
11822   return templ;
11823 }"
11824   [(set_attr "type" "arith_media")])
11825
11826 ; mextrN can be modelled with vec_select / vec_concat, but the selection
11827 ; vector then varies depending on endianness.
11828 (define_expand "mextr1"
11829   [(match_operand:DI 0 "arith_reg_dest" "")
11830    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11831    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11832   "TARGET_SHMEDIA"
11833   "
11834 {
11835   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11836                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
11837   DONE;
11838 }")
11839
11840 (define_expand "mextr2"
11841   [(match_operand:DI 0 "arith_reg_dest" "")
11842    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11843    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11844   "TARGET_SHMEDIA"
11845   "
11846 {
11847   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11848                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
11849   DONE;
11850 }")
11851
11852 (define_expand "mextr3"
11853   [(match_operand:DI 0 "arith_reg_dest" "")
11854    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11855    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11856   "TARGET_SHMEDIA"
11857   "
11858 {
11859   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11860                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
11861   DONE;
11862 }")
11863
11864 (define_expand "mextr4"
11865   [(match_operand:DI 0 "arith_reg_dest" "")
11866    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11867    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11868   "TARGET_SHMEDIA"
11869   "
11870 {
11871   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11872                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
11873   DONE;
11874 }")
11875
11876 (define_expand "mextr5"
11877   [(match_operand:DI 0 "arith_reg_dest" "")
11878    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11879    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11880   "TARGET_SHMEDIA"
11881   "
11882 {
11883   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11884                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
11885   DONE;
11886 }")
11887
11888 (define_expand "mextr6"
11889   [(match_operand:DI 0 "arith_reg_dest" "")
11890    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11891    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11892   "TARGET_SHMEDIA"
11893   "
11894 {
11895   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11896                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
11897   DONE;
11898 }")
11899
11900 (define_expand "mextr7"
11901   [(match_operand:DI 0 "arith_reg_dest" "")
11902    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11903    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11904   "TARGET_SHMEDIA"
11905   "
11906 {
11907   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11908                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
11909   DONE;
11910 }")
11911
11912 (define_expand "mmacfx_wl"
11913   [(match_operand:V2SI 0 "arith_reg_dest" "")
11914    (match_operand:V2HI 1 "extend_reg_operand" "")
11915    (match_operand:V2HI 2 "extend_reg_operand" "")
11916    (match_operand:V2SI 3 "arith_reg_operand" "")]
11917   "TARGET_SHMEDIA"
11918   "
11919 {
11920   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
11921                               operands[1], operands[2]));
11922   DONE;
11923 }")
11924
11925 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
11926 ;; is depend
11927 (define_insn "mmacfx_wl_i"
11928   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11929         (ss_plus:V2SI
11930          (match_operand:V2SI 1 "arith_reg_operand" "0")
11931          (ss_truncate:V2SI
11932           (ashift:V2DI
11933            (sign_extend:V2DI
11934             (mult:V2SI
11935              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11936              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11937            (const_int 1)))))]
11938   "TARGET_SHMEDIA"
11939   "mmacfx.wl    %2, %3, %0"
11940   [(set_attr "type" "mac_media")
11941    (set_attr "highpart" "depend")])
11942
11943 (define_expand "mmacnfx_wl"
11944   [(match_operand:V2SI 0 "arith_reg_dest" "")
11945    (match_operand:V2HI 1 "extend_reg_operand" "")
11946    (match_operand:V2HI 2 "extend_reg_operand" "")
11947    (match_operand:V2SI 3 "arith_reg_operand" "")]
11948   "TARGET_SHMEDIA"
11949   "
11950 {
11951   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
11952                                operands[1], operands[2]));
11953   DONE;
11954 }")
11955
11956 (define_insn "mmacnfx_wl_i"
11957   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11958         (ss_minus:V2SI
11959          (match_operand:V2SI 1 "arith_reg_operand" "0")
11960          (ss_truncate:V2SI
11961           (ashift:V2DI
11962            (sign_extend:V2DI
11963             (mult:V2SI
11964              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11965              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11966            (const_int 1)))))]
11967   "TARGET_SHMEDIA"
11968   "mmacnfx.wl   %2, %3, %0"
11969   [(set_attr "type" "mac_media")
11970    (set_attr "highpart" "depend")])
11971
11972 (define_insn "mulv2si3"
11973   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11974         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
11975                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11976   "TARGET_SHMEDIA"
11977   "mmul.l       %1, %2, %0"
11978   [(set_attr "type" "d2mpy_media")
11979    (set_attr "highpart" "depend")])
11980
11981 (define_insn "mulv4hi3"
11982   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11983         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
11984                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11985   "TARGET_SHMEDIA"
11986   "mmul.w       %1, %2, %0"
11987   [(set_attr "type" "dmpy_media")
11988    (set_attr "highpart" "depend")])
11989
11990 (define_insn "mmulfx_l"
11991   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11992         (ss_truncate:V2SI
11993          (ashiftrt:V2DI
11994           (mult:V2DI
11995            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
11996            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
11997           (const_int 31))))]
11998   "TARGET_SHMEDIA"
11999   "mmulfx.l     %1, %2, %0"
12000   [(set_attr "type" "d2mpy_media")
12001    (set_attr "highpart" "depend")])
12002
12003 (define_insn "mmulfx_w"
12004   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12005         (ss_truncate:V4HI
12006          (ashiftrt:V4SI
12007           (mult:V4SI
12008            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12009            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12010           (const_int 15))))]
12011   "TARGET_SHMEDIA"
12012   "mmulfx.w     %1, %2, %0"
12013   [(set_attr "type" "dmpy_media")
12014    (set_attr "highpart" "depend")])
12015
12016 (define_insn "mmulfxrp_w"
12017   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12018         (ss_truncate:V4HI
12019          (ashiftrt:V4SI
12020           (plus:V4SI
12021            (mult:V4SI
12022             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12023             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12024            (const_int 16384))
12025           (const_int 15))))]
12026   "TARGET_SHMEDIA"
12027   "mmulfxrp.w   %1, %2, %0"
12028   [(set_attr "type" "dmpy_media")
12029    (set_attr "highpart" "depend")])
12030
12031
12032 (define_expand "mmulhi_wl"
12033   [(match_operand:V2SI 0 "arith_reg_dest" "")
12034    (match_operand:V4HI 1 "arith_reg_operand" "")
12035    (match_operand:V4HI 2 "arith_reg_operand" "")]
12036   "TARGET_SHMEDIA"
12037   "
12038 {
12039   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
12040              (operands[0], operands[1], operands[2]));
12041   DONE;
12042 }")
12043
12044 (define_expand "mmullo_wl"
12045   [(match_operand:V2SI 0 "arith_reg_dest" "")
12046    (match_operand:V4HI 1 "arith_reg_operand" "")
12047    (match_operand:V4HI 2 "arith_reg_operand" "")]
12048   "TARGET_SHMEDIA"
12049   "
12050 {
12051   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
12052              (operands[0], operands[1], operands[2]));
12053   DONE;
12054 }")
12055
12056 (define_insn "mmul23_wl"
12057   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12058         (vec_select:V2SI
12059          (mult:V4SI
12060           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12061           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12062          (parallel [(const_int 2) (const_int 3)])))]
12063   "TARGET_SHMEDIA"
12064   "* return (TARGET_LITTLE_ENDIAN
12065              ? \"mmulhi.wl      %1, %2, %0\"
12066              : \"mmullo.wl      %1, %2, %0\");"
12067   [(set_attr "type" "dmpy_media")
12068    (set (attr "highpart")
12069         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12070          (const_string "user")))])
12071
12072 (define_insn "mmul01_wl"
12073   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12074         (vec_select:V2SI
12075          (mult:V4SI
12076           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12077           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12078          (parallel [(const_int 0) (const_int 1)])))]
12079   "TARGET_SHMEDIA"
12080   "* return (TARGET_LITTLE_ENDIAN
12081              ? \"mmullo.wl      %1, %2, %0\"
12082              : \"mmulhi.wl      %1, %2, %0\");"
12083   [(set_attr "type" "dmpy_media")
12084    (set (attr "highpart")
12085         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12086          (const_string "user")))])
12087
12088
12089 (define_expand "mmulsum_wq"
12090   [(match_operand:DI 0 "arith_reg_dest" "")
12091    (match_operand:V4HI 1 "arith_reg_operand" "")
12092    (match_operand:V4HI 2 "arith_reg_operand" "")
12093    (match_operand:DI 3 "arith_reg_operand" "")]
12094   "TARGET_SHMEDIA"
12095   "
12096 {
12097   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12098                                operands[1], operands[2]));
12099   DONE;
12100 }")
12101
12102 (define_insn "mmulsum_wq_i"
12103   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12104         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12105          (plus:DI
12106           (plus:DI
12107            (vec_select:DI
12108             (mult:V4DI
12109              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12110              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12111             (parallel [(const_int 0)]))
12112            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12113                                      (sign_extend:V4DI (match_dup 3)))
12114                           (parallel [(const_int 1)])))
12115           (plus:DI
12116            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12117                                      (sign_extend:V4DI (match_dup 3)))
12118                           (parallel [(const_int 2)]))
12119            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12120                                      (sign_extend:V4DI (match_dup 3)))
12121                           (parallel [(const_int 3)]))))))]
12122   "TARGET_SHMEDIA"
12123   "mmulsum.wq   %2, %3, %0"
12124   [(set_attr "type" "mac_media")])
12125
12126 (define_expand "mperm_w"
12127   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12128    (match_operand:V4HI 1 "arith_reg_operand" "r")
12129    (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12130   "TARGET_SHMEDIA"
12131   "
12132 {
12133   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12134              (operands[0], operands[1], operands[2]));
12135   DONE;
12136 }")
12137
12138 ; This use of vec_select isn't exactly correct according to rtl.texi
12139 ; (because not constant), but it seems a straightforward extension.
12140 (define_insn "mperm_w_little"
12141   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12142         (vec_select:V4HI
12143          (match_operand:V4HI 1 "arith_reg_operand" "r")
12144          (parallel
12145           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12146                             (const_int 2) (const_int 0))
12147            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12148            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12149            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12150   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12151   "mperm.w      %1, %N2, %0"
12152   [(set_attr "type" "arith_media")])
12153
12154 (define_insn "mperm_w_big"
12155   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12156         (vec_select:V4HI
12157          (match_operand:V4HI 1 "arith_reg_operand" "r")
12158          (parallel
12159           [(zero_extract:QI (not:QI (match_operand:QI 2
12160                                      "extend_reg_or_0_operand" "rZ"))
12161                             (const_int 2) (const_int 0))
12162            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12163            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12164            (zero_extract:QI (not:QI (match_dup 2))
12165                             (const_int 2) (const_int 6))])))]
12166   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12167   "mperm.w      %1, %N2, %0"
12168   [(set_attr "type" "arith_media")])
12169
12170 (define_insn "mperm_w0"
12171   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12172         (vec_duplicate:V4HI (truncate:HI (match_operand 1
12173                                           "trunc_hi_operand" "r"))))]
12174   "TARGET_SHMEDIA"
12175   "mperm.w      %1, r63, %0"
12176   [(set_attr "type" "arith_media")
12177    (set_attr "highpart" "ignore")])
12178
12179 (define_expand "msad_ubq"
12180   [(match_operand:DI 0 "arith_reg_dest" "")
12181    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12182    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12183    (match_operand:DI 3 "arith_reg_operand" "")]
12184   "TARGET_SHMEDIA"
12185   "
12186 {
12187   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12188                              operands[1], operands[2]));
12189   DONE;
12190 }")
12191
12192 (define_insn "msad_ubq_i"
12193   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12194         (plus:DI
12195          (plus:DI
12196           (plus:DI
12197            (plus:DI
12198             (match_operand:DI 1 "arith_reg_operand" "0")
12199             (abs:DI (vec_select:DI
12200                      (minus:V8DI
12201                       (zero_extend:V8DI
12202                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12203                       (zero_extend:V8DI
12204                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12205                      (parallel [(const_int 0)]))))
12206            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12207                                               (zero_extend:V8DI (match_dup 3)))
12208                                   (parallel [(const_int 1)]))))
12209           (plus:DI
12210            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12211                                               (zero_extend:V8DI (match_dup 3)))
12212                                   (parallel [(const_int 2)])))
12213            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12214                                               (zero_extend:V8DI (match_dup 3)))
12215                                   (parallel [(const_int 3)])))))
12216          (plus:DI
12217           (plus:DI
12218            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12219                                               (zero_extend:V8DI (match_dup 3)))
12220                                   (parallel [(const_int 4)])))
12221            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12222                                               (zero_extend:V8DI (match_dup 3)))
12223                                   (parallel [(const_int 5)]))))
12224           (plus:DI
12225            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12226                                               (zero_extend:V8DI (match_dup 3)))
12227                                   (parallel [(const_int 6)])))
12228            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12229                                               (zero_extend:V8DI (match_dup 3)))
12230                                   (parallel [(const_int 7)])))))))]
12231   "TARGET_SHMEDIA"
12232   "msad.ubq     %N2, %N3, %0"
12233   [(set_attr "type" "mac_media")])
12234
12235 (define_insn "mshalds_l"
12236   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12237         (ss_truncate:V2SI
12238          (ashift:V2DI
12239           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12240           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12241                   (const_int 31)))))]
12242   "TARGET_SHMEDIA"
12243   "mshalds.l    %1, %2, %0"
12244   [(set_attr "type" "mcmp_media")
12245    (set_attr "highpart" "depend")])
12246
12247 (define_insn "mshalds_w"
12248   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12249         (ss_truncate:V4HI
12250          (ashift:V4SI
12251           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12252           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12253                   (const_int 15)))))]
12254   "TARGET_SHMEDIA"
12255   "mshalds.w    %1, %2, %0"
12256   [(set_attr "type" "mcmp_media")
12257    (set_attr "highpart" "depend")])
12258
12259 (define_insn "ashrv2si3"
12260   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12261         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12262                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12263   "TARGET_SHMEDIA"
12264   "mshard.l     %1, %2, %0"
12265   [(set_attr "type" "arith_media")
12266    (set_attr "highpart" "depend")])
12267
12268 (define_insn "ashrv4hi3"
12269   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12270         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12271                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12272   "TARGET_SHMEDIA"
12273   "mshard.w     %1, %2, %0"
12274   [(set_attr "type" "arith_media")
12275    (set_attr "highpart" "depend")])
12276
12277 (define_insn "mshards_q"
12278   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12279         (ss_truncate:HI
12280          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12281                       (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12282   "TARGET_SHMEDIA"
12283   "mshards.q    %1, %N2, %0"
12284   [(set_attr "type" "mcmp_media")])
12285
12286 (define_expand "mshfhi_b"
12287   [(match_operand:V8QI 0 "arith_reg_dest" "")
12288    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12289    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12290   "TARGET_SHMEDIA"
12291   "
12292 {
12293   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12294              (operands[0], operands[1], operands[2]));
12295   DONE;
12296 }")
12297
12298 (define_expand "mshflo_b"
12299   [(match_operand:V8QI 0 "arith_reg_dest" "")
12300    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12301    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12302   "TARGET_SHMEDIA"
12303   "
12304 {
12305   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12306              (operands[0], operands[1], operands[2]));
12307   DONE;
12308 }")
12309
12310 (define_insn "mshf4_b"
12311   [(set
12312     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12313     (vec_select:V8QI
12314      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12315                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12316      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12317                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12318   "TARGET_SHMEDIA"
12319   "* return (TARGET_LITTLE_ENDIAN
12320              ? \"mshfhi.b       %N1, %N2, %0\"
12321              : \"mshflo.b       %N1, %N2, %0\");"
12322   [(set_attr "type" "arith_media")
12323    (set (attr "highpart")
12324         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12325          (const_string "user")))])
12326
12327 (define_insn "mshf0_b"
12328   [(set
12329     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12330     (vec_select:V8QI
12331      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12332                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12333      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12334                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12335   "TARGET_SHMEDIA"
12336   "* return (TARGET_LITTLE_ENDIAN
12337              ? \"mshflo.b       %N1, %N2, %0\"
12338              : \"mshfhi.b       %N1, %N2, %0\");"
12339   [(set_attr "type" "arith_media")
12340    (set (attr "highpart")
12341         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12342          (const_string "user")))])
12343
12344 (define_expand "mshfhi_l"
12345   [(match_operand:V2SI 0 "arith_reg_dest" "")
12346    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12347    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12348   "TARGET_SHMEDIA"
12349   "
12350 {
12351   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12352              (operands[0], operands[1], operands[2]));
12353   DONE;
12354 }")
12355
12356 (define_expand "mshflo_l"
12357   [(match_operand:V2SI 0 "arith_reg_dest" "")
12358    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12359    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12360   "TARGET_SHMEDIA"
12361   "
12362 {
12363   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12364              (operands[0], operands[1], operands[2]));
12365   DONE;
12366 }")
12367
12368 (define_insn "mshf4_l"
12369   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12370         (vec_select:V2SI
12371          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12372                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12373          (parallel [(const_int 1) (const_int 3)])))]
12374   "TARGET_SHMEDIA"
12375   "* return (TARGET_LITTLE_ENDIAN
12376              ? \"mshfhi.l       %N1, %N2, %0\"
12377              : \"mshflo.l       %N1, %N2, %0\");"
12378   [(set_attr "type" "arith_media")
12379    (set (attr "highpart")
12380         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12381          (const_string "user")))])
12382
12383 (define_insn "mshf0_l"
12384   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12385         (vec_select:V2SI
12386          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12387                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12388          (parallel [(const_int 0) (const_int 2)])))]
12389   "TARGET_SHMEDIA"
12390   "* return (TARGET_LITTLE_ENDIAN
12391              ? \"mshflo.l       %N1, %N2, %0\"
12392              : \"mshfhi.l       %N1, %N2, %0\");"
12393   [(set_attr "type" "arith_media")
12394    (set (attr "highpart")
12395         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12396          (const_string "user")))])
12397
12398 (define_expand "mshfhi_w"
12399   [(match_operand:V4HI 0 "arith_reg_dest" "")
12400    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12401    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12402   "TARGET_SHMEDIA"
12403   "
12404 {
12405   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12406              (operands[0], operands[1], operands[2]));
12407   DONE;
12408 }")
12409
12410 (define_expand "mshflo_w"
12411   [(match_operand:V4HI 0 "arith_reg_dest" "")
12412    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12413    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12414   "TARGET_SHMEDIA"
12415   "
12416 {
12417   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12418              (operands[0], operands[1], operands[2]));
12419   DONE;
12420 }")
12421
12422 (define_insn "mshf4_w"
12423   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12424         (vec_select:V4HI
12425          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12426                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12427          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12428   "TARGET_SHMEDIA"
12429   "* return (TARGET_LITTLE_ENDIAN
12430              ? \"mshfhi.w       %N1, %N2, %0\"
12431              : \"mshflo.w       %N1, %N2, %0\");"
12432   [(set_attr "type" "arith_media")
12433    (set (attr "highpart")
12434         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12435          (const_string "user")))])
12436
12437 (define_insn "mshf0_w"
12438   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12439         (vec_select:V4HI
12440          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12441                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12442          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12443   "TARGET_SHMEDIA"
12444   "* return (TARGET_LITTLE_ENDIAN
12445              ? \"mshflo.w       %N1, %N2, %0\"
12446              : \"mshfhi.w       %N1, %N2, %0\");"
12447   [(set_attr "type" "arith_media")
12448    (set (attr "highpart")
12449         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12450          (const_string "user")))])
12451
12452 (define_insn "mshflo_w_x"
12453   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12454         (vec_select:V4HI
12455          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12456                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12457          (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12458   "TARGET_SHMEDIA"
12459   "mshflo.w     %N1, %N2, %0"
12460   [(set_attr "type" "arith_media")
12461    (set_attr "highpart" "ignore")])
12462
12463 /* These are useful to expand ANDs and as combiner patterns.  */
12464 (define_insn_and_split "mshfhi_l_di"
12465   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12466         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12467                              (const_int 32))
12468                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12469                         (const_int -4294967296))))]
12470   "TARGET_SHMEDIA"
12471   "@
12472         mshfhi.l        %N1, %N2, %0
12473         #"
12474   "TARGET_SHMEDIA && reload_completed
12475    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12476   [(set (match_dup 3) (match_dup 4))
12477    (set (match_dup 5) (match_dup 6))]
12478   "
12479 {
12480   operands[3] = gen_lowpart (SImode, operands[0]);
12481   operands[4] = gen_highpart (SImode, operands[1]);
12482   operands[5] = gen_highpart (SImode, operands[0]);
12483   operands[6] = gen_highpart (SImode, operands[2]);
12484 }"
12485   [(set_attr "type" "arith_media")])
12486
12487 (define_insn "*mshfhi_l_di_rev"
12488   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12489         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12490                         (const_int -4294967296))
12491                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12492                              (const_int 32))))]
12493   "TARGET_SHMEDIA"
12494   "mshfhi.l     %N2, %N1, %0"
12495   [(set_attr "type" "arith_media")])
12496
12497 (define_split
12498   [(set (match_operand:DI 0 "arith_reg_dest" "")
12499         (ior:DI (zero_extend:DI (match_operand:SI 1
12500                                               "extend_reg_or_0_operand" ""))
12501                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12502                         (const_int -4294967296))))
12503    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12504   "TARGET_SHMEDIA"
12505   [(const_int 0)]
12506   "
12507 {
12508   emit_insn (gen_ashldi3_media (operands[3],
12509                                 simplify_gen_subreg (DImode, operands[1],
12510                                                      SImode, 0),
12511                                 GEN_INT (32)));
12512   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12513   DONE;
12514 }")
12515
12516 (define_insn "mshflo_l_di"
12517   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12518         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12519                         (const_int 4294967295))
12520                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12521                            (const_int 32))))]
12522
12523   "TARGET_SHMEDIA"
12524   "mshflo.l     %N1, %N2, %0"
12525   [(set_attr "type" "arith_media")
12526    (set_attr "highpart" "ignore")])
12527
12528 (define_insn "*mshflo_l_di_rev"
12529   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12530         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12531                            (const_int 32))
12532                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12533                         (const_int 4294967295))))]
12534
12535   "TARGET_SHMEDIA"
12536   "mshflo.l     %N2, %N1, %0"
12537   [(set_attr "type" "arith_media")
12538    (set_attr "highpart" "ignore")])
12539
12540 ;; Combiner pattern for trampoline initialization.
12541 (define_insn_and_split "*double_shori"
12542   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12543         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12544                            (const_int 32))
12545                 (match_operand:DI 2 "const_int_operand" "n")))]
12546   "TARGET_SHMEDIA
12547    && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12548   "#"
12549   "rtx_equal_p (operands[0], operands[1])"
12550   [(const_int 0)]
12551   "
12552 {
12553   HOST_WIDE_INT v = INTVAL (operands[2]);
12554
12555   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12556   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12557   DONE;
12558 }"
12559   [(set_attr "highpart" "ignore")])
12560
12561
12562 (define_insn "*mshflo_l_di_x"
12563   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12564         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12565                                  "rZ"))
12566                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12567                            (const_int 32))))]
12568
12569   "TARGET_SHMEDIA"
12570   "mshflo.l     %N1, %N2, %0"
12571   [(set_attr "type" "arith_media")
12572    (set_attr "highpart" "ignore")])
12573
12574 (define_insn_and_split "concat_v2sf"
12575   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12576 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12577         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12578                          (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12579
12580   "TARGET_SHMEDIA"
12581   "@
12582         mshflo.l        %N1, %N2, %0
12583         #
12584         #"
12585   "TARGET_SHMEDIA && reload_completed
12586    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12587   [(set (match_dup 3) (match_dup 1))
12588    (set (match_dup 4) (match_dup 2))]
12589   "
12590 {
12591   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12592   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12593 }"
12594   [(set_attr "type" "arith_media")
12595    (set_attr "highpart" "ignore")])
12596
12597 (define_insn "*mshflo_l_di_x_rev"
12598   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12599         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12600                            (const_int 32))
12601                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12602
12603   "TARGET_SHMEDIA"
12604   "mshflo.l     %N2, %N1, %0"
12605   [(set_attr "type" "arith_media")
12606    (set_attr "highpart" "ignore")])
12607
12608 (define_insn "ashlv2si3"
12609   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12610         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12611                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12612   "TARGET_SHMEDIA"
12613   "mshlld.l     %1, %2, %0"
12614   [(set_attr "type" "arith_media")
12615    (set_attr "highpart" "depend")])
12616
12617 (define_split
12618   [(set (match_operand 0 "any_register_operand" "")
12619         (match_operator 3 "shift_operator"
12620           [(match_operand 1 "any_register_operand" "")
12621            (match_operand 2 "shift_count_reg_operand" "")]))]
12622   "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12623   [(set (match_dup 0) (match_dup 3))]
12624   "
12625 {
12626   rtx count = operands[2];
12627   enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12628
12629   while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12630          || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12631          || GET_CODE (count) == TRUNCATE)
12632     count = XEXP (count, 0);
12633   inner_mode = GET_MODE (count);
12634   count = simplify_gen_subreg (outer_mode, count, inner_mode,
12635                                subreg_lowpart_offset (outer_mode, inner_mode));
12636   operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12637                                 operands[1], count);
12638 }")
12639
12640 (define_insn "ashlv4hi3"
12641   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12642         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12643                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12644   "TARGET_SHMEDIA"
12645   "mshlld.w     %1, %2, %0"
12646   [(set_attr "type" "arith_media")
12647    (set_attr "highpart" "depend")])
12648
12649 (define_insn "lshrv2si3"
12650   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12651         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12652                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12653   "TARGET_SHMEDIA"
12654   "mshlrd.l     %1, %2, %0"
12655   [(set_attr "type" "arith_media")
12656    (set_attr "highpart" "depend")])
12657
12658 (define_insn "lshrv4hi3"
12659   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12660         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12661                        (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12662   "TARGET_SHMEDIA"
12663   "mshlrd.w     %1, %2, %0"
12664   [(set_attr "type" "arith_media")
12665    (set_attr "highpart" "depend")])
12666
12667 (define_insn "subv2si3"
12668   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12669         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12670                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12671   "TARGET_SHMEDIA"
12672   "msub.l       %N1, %2, %0"
12673   [(set_attr "type" "arith_media")
12674    (set_attr "highpart" "depend")])
12675
12676 (define_insn "subv4hi3"
12677   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12678         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12679                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12680   "TARGET_SHMEDIA"
12681   "msub.w       %N1, %2, %0"
12682   [(set_attr "type" "arith_media")
12683    (set_attr "highpart" "depend")])
12684
12685 (define_insn_and_split "subv2hi3"
12686   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12687         (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12688                    (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12689   "TARGET_SHMEDIA"
12690   "#"
12691   "TARGET_SHMEDIA"
12692   [(const_int 0)]
12693   "
12694 {
12695   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12696   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12697   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12698   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12699   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12700
12701   emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12702   emit_insn (gen_truncdisi2 (si_dst, di_dst));
12703   DONE;
12704 }"
12705   [(set_attr "highpart" "must_split")])
12706
12707 (define_insn "sssubv2si3"
12708   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12709         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12710                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12711   "TARGET_SHMEDIA"
12712   "msubs.l      %N1, %2, %0"
12713   [(set_attr "type" "mcmp_media")
12714    (set_attr "highpart" "depend")])
12715
12716 (define_insn "ussubv8qi3"
12717   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12718         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12719                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12720   "TARGET_SHMEDIA"
12721   "msubs.ub     %N1, %2, %0"
12722   [(set_attr "type" "mcmp_media")
12723    (set_attr "highpart" "depend")])
12724
12725 (define_insn "sssubv4hi3"
12726   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12727         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12728                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12729   "TARGET_SHMEDIA"
12730   "msubs.w      %N1, %2, %0"
12731   [(set_attr "type" "mcmp_media")
12732    (set_attr "highpart" "depend")])
12733
12734 ;; Floating Point Intrinsics
12735
12736 (define_insn "fcosa_s"
12737   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12738         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12739                    UNSPEC_FCOSA))]
12740   "TARGET_SHMEDIA"
12741   "fcosa.s      %1, %0"
12742   [(set_attr "type" "atrans_media")])
12743
12744 (define_insn "fsina_s"
12745   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12746         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12747                    UNSPEC_FSINA))]
12748   "TARGET_SHMEDIA"
12749   "fsina.s      %1, %0"
12750   [(set_attr "type" "atrans_media")])
12751
12752 (define_insn "fipr"
12753   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12754         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12755                                                     "fp_arith_reg_operand" "f")
12756                                                    (match_operand:V4SF 2
12757                                                     "fp_arith_reg_operand" "f"))
12758                                          (parallel [(const_int 0)]))
12759                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12760                                          (parallel [(const_int 1)])))
12761                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12762                                          (parallel [(const_int 2)]))
12763                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12764                                          (parallel [(const_int 3)])))))]
12765   "TARGET_SHMEDIA"
12766   "fipr.s       %1, %2, %0"
12767   [(set_attr "type" "fparith_media")])
12768
12769 (define_insn "fsrra_s"
12770   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12771         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
12772                    UNSPEC_FSRRA))]
12773   "TARGET_SHMEDIA"
12774   "fsrra.s      %1, %0"
12775   [(set_attr "type" "atrans_media")])
12776
12777 (define_insn "ftrv"
12778   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
12779         (plus:V4SF
12780          (plus:V4SF
12781           (mult:V4SF
12782            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
12783                             (parallel [(const_int 0) (const_int 5)
12784                                        (const_int 10) (const_int 15)]))
12785            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
12786           (mult:V4SF
12787            (vec_select:V4SF (match_dup 1)
12788                             (parallel [(const_int 4) (const_int 9)
12789                                        (const_int 14) (const_int 3)]))
12790            (vec_select:V4SF (match_dup 2)
12791                             (parallel [(const_int 1) (const_int 2)
12792                                        (const_int 3) (const_int 0)]))))
12793          (plus:V4SF
12794           (mult:V4SF
12795            (vec_select:V4SF (match_dup 1)
12796                             (parallel [(const_int 8) (const_int 13)
12797                                        (const_int 2) (const_int 7)]))
12798            (vec_select:V4SF (match_dup 2)
12799                             (parallel [(const_int 2) (const_int 3)
12800                                        (const_int 0) (const_int 1)])))
12801           (mult:V4SF
12802            (vec_select:V4SF (match_dup 1)
12803                             (parallel [(const_int 12) (const_int 1)
12804                                        (const_int 6) (const_int 11)]))
12805            (vec_select:V4SF (match_dup 2)
12806                             (parallel [(const_int 3) (const_int 0)
12807                                        (const_int 1) (const_int 2)]))))))]
12808   "TARGET_SHMEDIA"
12809   "ftrv.s %1, %2, %0"
12810   [(set_attr "type" "fparith_media")])
12811
12812 (define_insn "ldhi_l"
12813   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12814         (zero_extract:SI
12815          (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12816                                   (const_int 3))
12817                           (const_int -3)))
12818          (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
12819          (const_int 0)))]
12820   "TARGET_SHMEDIA32"
12821   "ldhi.l       %U1, %0"
12822   [(set_attr "type" "load_media")])
12823
12824 (define_insn "ldhi_q"
12825   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12826         (zero_extract:DI
12827          (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12828                                   (const_int 7))
12829                           (const_int -7)))
12830          (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
12831          (const_int 0)))]
12832   "TARGET_SHMEDIA32"
12833   "ldhi.q       %U1, %0"
12834   [(set_attr "type" "load_media")])
12835
12836 (define_insn_and_split "*ldhi_q_comb0"
12837   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12838         (zero_extract:DI
12839          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12840                                             "register_operand" "r")
12841                                            (match_operand:SI 2
12842                                             "ua_offset" "I06"))
12843                                   (const_int 7))
12844                           (const_int -7)))
12845          (plus:SI (and:SI (match_dup 1) (const_int 7))
12846                   (const_int 1))
12847          (const_int 0)))]
12848   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12849   "#"
12850   ""
12851   [(pc)]
12852   "emit_insn (gen_ldhi_q (operands[0],
12853                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12854    DONE;")
12855
12856
12857 (define_insn_and_split "*ldhi_q_comb1"
12858   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12859         (zero_extract:DI
12860          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12861                                             "register_operand" "r")
12862                                            (match_operand:SI 2
12863                                             "ua_offset" "I06"))
12864                                   (const_int 7))
12865                           (const_int -7)))
12866          (plus:SI (and:SI (plus:SI (match_dup 1)  (match_operand:SI 3
12867                                                    "ua_offset" "I06"))
12868                           (const_int 7))
12869                   (const_int 1))
12870          (const_int 0)))]
12871   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12872    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12873   "#"
12874   ""
12875   [(pc)]
12876   "emit_insn (gen_ldhi_q (operands[0],
12877                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12878    DONE;")
12879
12880
12881 (define_insn "ldlo_l"
12882   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12883         (zero_extract:SI
12884          (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12885                          (const_int -4)))
12886          (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
12887          (and:SI (match_dup 1) (const_int 3))))]
12888   "TARGET_SHMEDIA32"
12889   "ldlo.l       %U1, %0"
12890   [(set_attr "type" "load_media")])
12891
12892 (define_insn "ldlo_q"
12893   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12894         (zero_extract:DI
12895          (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12896                          (const_int -8)))
12897          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12898          (and:SI (match_dup 1) (const_int 7))))]
12899   "TARGET_SHMEDIA32"
12900   "ldlo.q       %U1, %0"
12901   [(set_attr "type" "load_media")])
12902
12903 (define_insn_and_split "*ldlo_q_comb0"
12904   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12905         (zero_extract:DI
12906          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12907                                   (match_operand:SI 2 "ua_offset" "I06"))
12908                          (const_int -8)))
12909          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12910          (and:SI (match_dup 1) (const_int 7))))]
12911   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12912   "#"
12913   ""
12914   [(pc)]
12915   "emit_insn (gen_ldlo_q (operands[0],
12916                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12917    DONE;")
12918
12919 (define_insn_and_split "*ldlo_q_comb1"
12920   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12921         (zero_extract:DI
12922          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12923                                   (match_operand:SI 2 "ua_offset" "I06"))
12924                          (const_int -8)))
12925          (minus:SI (const_int 8)
12926                    (and:SI (plus:SI (match_dup 1)
12927                                     (match_operand:SI 3 "ua_offset" "I06"))
12928                            (const_int 7)))
12929          (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
12930   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12931    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12932   "#"
12933   ""
12934   [(pc)]
12935   "emit_insn (gen_ldlo_q (operands[0],
12936                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12937    DONE;")
12938
12939 (define_insn "sthi_l"
12940   [(set (zero_extract:SI
12941          (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12942                                   (const_int 3))
12943                           (const_int -3)))
12944          (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
12945          (const_int 0))
12946         (match_operand:SI 1 "arith_reg_operand" "r"))]
12947   "TARGET_SHMEDIA32"
12948   "sthi.l       %U0, %1"
12949   [(set_attr "type" "ustore_media")])
12950
12951 ;; All unaligned stores are considered to be 'narrow' because they typically
12952 ;; operate on less that a quadword, and when they operate on a full quadword,
12953 ;; the vanilla store high / store low sequence will cause a stall if not
12954 ;; scheduled apart.
12955 (define_insn "sthi_q"
12956   [(set (zero_extract:DI
12957          (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12958                                   (const_int 7))
12959                           (const_int -7)))
12960          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12961          (const_int 0))
12962         (match_operand:DI 1 "arith_reg_operand" "r"))]
12963   "TARGET_SHMEDIA32"
12964   "sthi.q       %U0, %1"
12965   [(set_attr "type" "ustore_media")])
12966
12967 (define_insn_and_split "*sthi_q_comb0"
12968   [(set (zero_extract:DI
12969          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12970                                             "register_operand" "r")
12971                                            (match_operand:SI 1 "ua_offset"
12972                                             "I06"))
12973                                   (const_int 7))
12974                           (const_int -7)))
12975          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12976          (const_int 0))
12977         (match_operand:DI 2 "arith_reg_operand" "r"))]
12978   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12979   "#"
12980   ""
12981   [(pc)]
12982   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12983                           operands[2]));
12984    DONE;")
12985
12986 (define_insn_and_split "*sthi_q_comb1"
12987   [(set (zero_extract:DI
12988          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12989                                             "register_operand" "r")
12990                                            (match_operand:SI 1 "ua_offset"
12991                                             "I06"))
12992                                   (const_int 7))
12993                           (const_int -7)))
12994          (plus:SI (and:SI (plus:SI (match_dup 0)
12995                                    (match_operand:SI 2 "ua_offset" "I06"))
12996                           (const_int 7))
12997                   (const_int 1))
12998          (const_int 0))
12999         (match_operand:DI 3 "arith_reg_operand" "r"))]
13000   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
13001    && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13002   "#"
13003   ""
13004   [(pc)]
13005   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13006                           operands[3]));
13007    DONE;")
13008
13009 ;; This is highpart user because the address is used as full 64 bit.
13010 (define_insn "stlo_l"
13011   [(set (zero_extract:SI
13012          (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13013                          (const_int -4)))
13014          (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
13015          (and:SI (match_dup 0) (const_int 3)))
13016         (match_operand:SI 1 "arith_reg_operand" "r"))]
13017   "TARGET_SHMEDIA32"
13018   "stlo.l       %U0, %1"
13019   [(set_attr "type" "ustore_media")])
13020
13021 (define_insn "stlo_q"
13022   [(set (zero_extract:DI
13023          (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13024                          (const_int -8)))
13025          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13026          (and:SI (match_dup 0) (const_int 7)))
13027         (match_operand:DI 1 "arith_reg_operand" "r"))]
13028   "TARGET_SHMEDIA32"
13029   "stlo.q       %U0, %1"
13030   [(set_attr "type" "ustore_media")])
13031
13032 (define_insn_and_split "*stlo_q_comb0"
13033   [(set (zero_extract:DI
13034          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13035                                   (match_operand:SI 1 "ua_offset" "I06"))
13036                          (const_int -8)))
13037          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13038          (and:SI (match_dup 0) (const_int 7)))
13039         (match_operand:DI 2 "arith_reg_operand" "r"))]
13040   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13041   "#"
13042   ""
13043   [(pc)]
13044   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13045                           operands[2]));
13046    DONE;")
13047
13048 (define_insn_and_split "*stlo_q_comb1"
13049   [(set (zero_extract:DI
13050          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13051                                   (match_operand:SI 1 "ua_offset" "I06"))
13052                          (const_int -8)))
13053          (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
13054                                                   (match_operand:SI 2
13055                                                    "ua_offset" "I06"))
13056                                          (const_int 7)))
13057          (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
13058         (match_operand:DI 3 "arith_reg_operand" "r"))]
13059   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13060   "#"
13061   ""
13062   [(pc)]
13063   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13064                           operands[3]));
13065    DONE;")
13066
13067 (define_insn "ldhi_l64"
13068   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13069         (zero_extract:SI
13070          (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13071                                   (const_int 3))
13072                           (const_int -3)))
13073          (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13074          (const_int 0)))]
13075   "TARGET_SHMEDIA64"
13076   "ldhi.l       %U1, %0"
13077   [(set_attr "type" "load_media")])
13078
13079 (define_insn "ldhi_q64"
13080   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13081         (zero_extract:DI
13082          (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13083                                   (const_int 7))
13084                           (const_int -7)))
13085          (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13086          (const_int 0)))]
13087   "TARGET_SHMEDIA64"
13088   "ldhi.q       %U1, %0"
13089   [(set_attr "type" "load_media")])
13090
13091 (define_insn "ldlo_l64"
13092   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13093         (zero_extract:SI
13094          (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13095                          (const_int -4)))
13096          (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13097          (and:DI (match_dup 1) (const_int 3))))]
13098   "TARGET_SHMEDIA64"
13099   "ldlo.l       %U1, %0"
13100   [(set_attr "type" "load_media")])
13101
13102 (define_insn "ldlo_q64"
13103   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13104         (zero_extract:DI
13105          (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13106                          (const_int -8)))
13107          (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13108          (and:DI (match_dup 1) (const_int 7))))]
13109   "TARGET_SHMEDIA64"
13110   "ldlo.q       %U1, %0"
13111   [(set_attr "type" "load_media")])
13112
13113 (define_insn "sthi_l64"
13114   [(set (zero_extract:SI
13115          (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13116                                   (const_int 3))
13117                           (const_int -3)))
13118          (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13119          (const_int 0))
13120         (match_operand:SI 1 "arith_reg_operand" "r"))]
13121   "TARGET_SHMEDIA64"
13122   "sthi.l       %U0, %1"
13123   [(set_attr "type" "ustore_media")])
13124
13125 (define_insn "sthi_q64"
13126   [(set (zero_extract:DI
13127          (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13128                                   (const_int 7))
13129                           (const_int -7)))
13130          (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13131          (const_int 0))
13132         (match_operand:DI 1 "arith_reg_operand" "r"))]
13133   "TARGET_SHMEDIA64"
13134   "sthi.q       %U0, %1"
13135   [(set_attr "type" "ustore_media")])
13136
13137 (define_insn "stlo_l64"
13138   [(set (zero_extract:SI
13139          (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13140                          (const_int -4)))
13141          (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13142          (and:DI (match_dup 0) (const_int 3)))
13143         (match_operand:SI 1 "arith_reg_operand" "r"))]
13144   "TARGET_SHMEDIA64"
13145   "stlo.l       %U0, %1"
13146   [(set_attr "type" "ustore_media")])
13147
13148 (define_insn "stlo_q64"
13149   [(set (zero_extract:DI
13150          (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13151                          (const_int -8)))
13152          (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13153          (and:DI (match_dup 0) (const_int 7)))
13154         (match_operand:DI 1 "arith_reg_operand" "r"))]
13155   "TARGET_SHMEDIA64"
13156   "stlo.q       %U0, %1"
13157   [(set_attr "type" "ustore_media")])
13158
13159 (define_insn "nsb"
13160   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13161         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13162                    UNSPEC_NSB))]
13163   "TARGET_SHMEDIA"
13164   "nsb  %1, %0"
13165   [(set_attr "type" "arith_media")])
13166
13167 (define_insn "nsbsi"
13168   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13169         (zero_extend:SI
13170          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13171                     UNSPEC_NSB)))]
13172   "TARGET_SHMEDIA"
13173   "nsb  %1, %0"
13174   [(set_attr "type" "arith_media")])
13175
13176 (define_insn "nsbdi"
13177   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13178         (zero_extend:DI
13179          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13180                     UNSPEC_NSB)))]
13181   "TARGET_SHMEDIA"
13182   "nsb  %1, %0"
13183   [(set_attr "type" "arith_media")])
13184
13185 (define_expand "ffsdi2"
13186   [(set (match_operand:DI 0 "arith_reg_dest" "")
13187         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13188   "TARGET_SHMEDIA"
13189   "
13190 {
13191   rtx scratch = gen_reg_rtx (DImode);
13192   rtx last;
13193
13194   emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13195   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13196   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13197   emit_insn (gen_nsbdi (scratch, scratch));
13198   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13199   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13200   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13201   set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
13202
13203   DONE;
13204 }")
13205
13206 (define_expand "ffssi2"
13207   [(set (match_operand:SI 0 "arith_reg_dest" "")
13208         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13209   "TARGET_SHMEDIA"
13210   "
13211 {
13212   rtx scratch = gen_reg_rtx (SImode);
13213   rtx discratch = gen_reg_rtx (DImode);
13214   rtx last;
13215
13216   emit_insn (gen_adddi3 (discratch,
13217                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
13218                          constm1_rtx));
13219   emit_insn (gen_andcdi3 (discratch,
13220                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
13221                           discratch));
13222   emit_insn (gen_nsbsi (scratch, discratch));
13223   last = emit_insn (gen_subsi3 (operands[0],
13224                                 force_reg (SImode, GEN_INT (63)), scratch));
13225   set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
13226
13227   DONE;
13228 }")
13229
13230 (define_insn "byterev"
13231   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13232         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13233                          (parallel [(const_int 7) (const_int 6) (const_int 5)
13234                                     (const_int 4) (const_int 3) (const_int 2)
13235                                     (const_int 1) (const_int 0)])))]
13236   "TARGET_SHMEDIA"
13237   "byterev      %1, %0"
13238   [(set_attr "type" "arith_media")])
13239
13240 (define_insn "*prefetch_media"
13241   [(prefetch (match_operand:QI 0 "address_operand" "p")
13242              (match_operand:SI 1 "const_int_operand" "n")
13243              (match_operand:SI 2 "const_int_operand" "n"))]
13244   "TARGET_SHMEDIA"
13245   "*
13246 {
13247   operands[0] = gen_rtx_MEM (QImode, operands[0]);
13248   output_asm_insn (\"ld%M0.b    %m0,r63\", operands);
13249   return \"\";
13250 }"
13251   [(set_attr "type" "other")])
13252
13253 (define_insn "*prefetch_i4"
13254   [(prefetch (match_operand:SI 0 "register_operand" "r")
13255              (match_operand:SI 1 "const_int_operand" "n")
13256              (match_operand:SI 2 "const_int_operand" "n"))]
13257   "TARGET_HARD_SH4 || TARGET_SHCOMPACT"
13258   "*
13259 {
13260   return \"pref @%0\";
13261 }"
13262   [(set_attr "type" "other")])
13263
13264 (define_expand "prefetch"
13265   [(prefetch (match_operand 0 "address_operand" "p")
13266              (match_operand:SI 1 "const_int_operand" "n")
13267              (match_operand:SI 2 "const_int_operand" "n"))]
13268   "TARGET_HARD_SH4 || TARGET_SH5"
13269   "
13270 {
13271   if (GET_MODE (operands[0]) != Pmode
13272       || GET_CODE (operands[1]) != CONST_INT
13273       || GET_CODE (operands[2]) != CONST_INT)
13274     FAIL;
13275   if (! TARGET_SHMEDIA)
13276     operands[0] = force_reg (Pmode, operands[0]);
13277 }")
13278
13279 (define_insn "alloco_i"
13280   [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13281         (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13282   "TARGET_SHMEDIA32"
13283   "*
13284 {
13285   rtx xops[2];
13286
13287   if (GET_CODE (operands[0]) == PLUS)
13288     {
13289       xops[0] = XEXP (operands[0], 0);
13290       xops[1] = XEXP (operands[0], 1);
13291     }
13292   else
13293     {
13294       xops[0] = operands[0];
13295       xops[1] = const0_rtx;
13296     }
13297   output_asm_insn (\"alloco   %0, %1\", xops);
13298   return \"\";
13299 }"
13300   [(set_attr "type" "other")])
13301
13302 (define_split
13303   [(set (match_operand 0 "any_register_operand" "")
13304         (match_operand 1 "" ""))]
13305   "TARGET_SHMEDIA && reload_completed"
13306   [(set (match_dup 0) (match_dup 1))]
13307   "
13308 {
13309   int n_changes = 0;
13310
13311   for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13312   if (!n_changes)
13313     FAIL;
13314 }")
13315
13316 ; Stack Protector Patterns
13317
13318 (define_expand "stack_protect_set"
13319   [(set (match_operand 0 "memory_operand" "")
13320         (match_operand 1 "memory_operand" ""))]
13321   ""
13322 {
13323   if (TARGET_SHMEDIA)
13324     {
13325       if (TARGET_SHMEDIA64)
13326         emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13327       else
13328         emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13329     }
13330   else
13331     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13332
13333   DONE;
13334 })
13335
13336 (define_insn "stack_protect_set_si"
13337   [(set (match_operand:SI 0 "memory_operand" "=m")
13338         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13339    (set (match_scratch:SI 2 "=&r") (const_int 0))]
13340   "!TARGET_SHMEDIA"
13341   "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13342   [(set_attr "type" "other")
13343    (set_attr "length" "6")])
13344
13345 (define_insn "stack_protect_set_si_media"
13346   [(set (match_operand:SI 0 "memory_operand" "=m")
13347         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13348    (set (match_scratch:SI 2 "=&r") (const_int 0))]
13349   "TARGET_SHMEDIA"
13350   "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13351   [(set_attr "type" "other")
13352    (set_attr "length" "12")])
13353
13354 (define_insn "stack_protect_set_di_media"
13355   [(set (match_operand:DI 0 "memory_operand" "=m")
13356         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13357    (set (match_scratch:DI 2 "=&r") (const_int 0))]
13358   "TARGET_SHMEDIA64"
13359   "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13360   [(set_attr "type" "other")
13361    (set_attr "length" "12")])
13362
13363 (define_expand "stack_protect_test"
13364   [(match_operand 0 "memory_operand" "")
13365    (match_operand 1 "memory_operand" "")
13366    (match_operand 2 "" "")]
13367   ""
13368 {
13369   if (TARGET_SHMEDIA)
13370     {
13371       rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13372
13373       if (TARGET_SHMEDIA64)
13374         emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13375                                                     operands[1]));
13376       else
13377         emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13378                                                     operands[1]));
13379
13380       emit_jump_insn (gen_bne_media (operands[2], tmp, const0_rtx));
13381     }
13382   else
13383     {
13384       emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13385       emit_jump_insn (gen_branch_true (operands[2]));
13386     }
13387
13388   DONE;
13389 })
13390
13391 (define_insn "stack_protect_test_si"
13392   [(set (reg:SI T_REG)
13393         (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13394                     (match_operand:SI 1 "memory_operand" "m")]
13395                    UNSPEC_SP_TEST))
13396   (set (match_scratch:SI 2 "=&r") (const_int 0))
13397   (set (match_scratch:SI 3 "=&r") (const_int 0))]
13398   "!TARGET_SHMEDIA"
13399   "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13400   [(set_attr "type" "other")
13401    (set_attr "length" "10")])
13402
13403 (define_insn "stack_protect_test_si_media"
13404   [(set (match_operand:SI 0 "register_operand" "=&r")
13405         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13406                     (match_operand:SI 2 "memory_operand" "m")]
13407                    UNSPEC_SP_TEST))
13408   (set (match_scratch:SI 3 "=&r") (const_int 0))]
13409   "TARGET_SHMEDIA"
13410   "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13411   [(set_attr "type" "other")
13412    (set_attr "length" "16")])
13413
13414 (define_insn "stack_protect_test_di_media"
13415   [(set (match_operand:DI 0 "register_operand" "=&r")
13416         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13417                     (match_operand:DI 2 "memory_operand" "m")]
13418                    UNSPEC_SP_TEST))
13419   (set (match_scratch:DI 3 "=&r") (const_int 0))]
13420   "TARGET_SHMEDIA64"
13421   "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13422   [(set_attr "type" "other")
13423    (set_attr "length" "16")])